mirror of https://github.com/aap/librw.git
implemented PS2 SA instance
This commit is contained in:
parent
040d167da0
commit
723807cec1
197
src/gtaplg.cpp
197
src/gtaplg.cpp
|
@ -869,21 +869,16 @@ static bool hasColors2(uint32 id)
|
|||
return id == 0x53f20083 || id == 0x53f2008f;
|
||||
}
|
||||
|
||||
struct SaVert {
|
||||
float32 p[3];
|
||||
float32 n[3];
|
||||
float32 t0[2];
|
||||
float32 t1[2];
|
||||
uint8 c0[4];
|
||||
uint8 c1[4];
|
||||
struct SaVert : ps2::Vertex {
|
||||
float32 w[4];
|
||||
uint8 i[4];
|
||||
float32 t1[2];
|
||||
uint8 c1[4];
|
||||
};
|
||||
|
||||
static void
|
||||
saPreCB(MatPipeline *p, Geometry *geo)
|
||||
{
|
||||
// allocate ADC, extra colors, skin
|
||||
allocateADC(geo);
|
||||
if(hasColors2(p->pluginData) && extraVertColorOffset)
|
||||
allocateExtraVertColors(geo);
|
||||
|
@ -924,15 +919,15 @@ findSAVertex(Geometry *g, uint32 flags[], uint32 mask, SaVert *v)
|
|||
!(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
|
||||
goto cont;
|
||||
if(mask & flags[i] & 0x100 &&
|
||||
!(cols0[0] == v->c0[0] && cols0[1] == v->c0[1] &&
|
||||
cols0[2] == v->c0[2] && cols0[3] == v->c0[3]))
|
||||
!(cols0[0] == v->c[0] && cols0[1] == v->c[1] &&
|
||||
cols0[2] == v->c[2] && cols0[3] == v->c[3]))
|
||||
goto cont;
|
||||
if(mask & flags[i] & 0x200 &&
|
||||
!(cols1[0] == v->c1[0] && cols1[1] == v->c1[1] &&
|
||||
cols1[2] == v->c1[2] && cols1[3] == v->c1[3]))
|
||||
goto cont;
|
||||
if(mask & flags[i] & 0x1000 &&
|
||||
!(tex0[0] == v->t0[0] && tex0[1] == v->t0[1]))
|
||||
!(tex0[0] == v->t[0] && tex0[1] == v->t[1]))
|
||||
goto cont;
|
||||
if(mask & flags[i] & 0x2000 &&
|
||||
!(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
|
||||
|
@ -960,7 +955,9 @@ findSAVertex(Geometry *g, uint32 flags[], uint32 mask, SaVert *v)
|
|||
void
|
||||
insertSAVertex(Geometry *geo, int32 i, uint32 mask, SaVert *v)
|
||||
{
|
||||
insertVertex(geo, i, mask, v->p, v->t0, v->t1, v->c0, v->n);
|
||||
insertVertex(geo, i, mask, v);
|
||||
if(mask & 0x2000)
|
||||
memcpy(&geo->texCoords[1][i*2], v->t1, 8);
|
||||
if(mask & 0x200 && extraVertColorOffset){
|
||||
uint8 *cols1 =
|
||||
&PLUGINOFFSET(ExtraVertColors, geo, extraVertColorOffset)->nightColors[i*4];
|
||||
|
@ -1023,23 +1020,23 @@ saUninstanceCB(ps2::MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
|
|||
v.n[2] = norms[2]/127.0f;
|
||||
}
|
||||
if(mask & 0x200){
|
||||
v.c0[0] = colors[0];
|
||||
v.c0[1] = colors[2];
|
||||
v.c0[2] = colors[4];
|
||||
v.c0[3] = colors[6];
|
||||
v.c[0] = colors[0];
|
||||
v.c[1] = colors[2];
|
||||
v.c[2] = colors[4];
|
||||
v.c[3] = colors[6];
|
||||
v.c1[0] = colors[1];
|
||||
v.c1[1] = colors[3];
|
||||
v.c1[2] = colors[5];
|
||||
v.c1[3] = colors[7];
|
||||
}else if(mask & 0x100){
|
||||
v.c0[0] = colors[0];
|
||||
v.c0[1] = colors[1];
|
||||
v.c0[2] = colors[2];
|
||||
v.c0[3] = colors[3];
|
||||
v.c[0] = colors[0];
|
||||
v.c[1] = colors[1];
|
||||
v.c[2] = colors[2];
|
||||
v.c[3] = colors[3];
|
||||
}
|
||||
if(mask & 0x1000){
|
||||
v.t0[0] = texcoords[0]/4096.0f;
|
||||
v.t0[1] = texcoords[1]/4096.0f;
|
||||
v.t[0] = texcoords[0]/4096.0f;
|
||||
v.t[1] = texcoords[1]/4096.0f;
|
||||
}
|
||||
if(mask & 0x2000){
|
||||
v.t1[0] = texcoords[2]/4096.0f;
|
||||
|
@ -1071,8 +1068,162 @@ saUninstanceCB(ps2::MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
|
|||
}
|
||||
|
||||
static void
|
||||
saInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data, int32 n)
|
||||
instanceSAPositions(Geometry *g, Mesh *m, int8 *adc, int16 *dst, float32 scale)
|
||||
{
|
||||
float32 *verts = g->morphTargets[0].vertices;
|
||||
uint16 j;
|
||||
for(uint32 i = 0; i < m->numIndices; i++){
|
||||
j = m->indices[i];
|
||||
dst[0] = verts[j*3+0]*scale;
|
||||
dst[1] = verts[j*3+1]*scale;
|
||||
dst[2] = verts[j*3+2]*scale;
|
||||
dst[3] = adc ? 0x8000*adc[i] : 0;
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
instanceSATex(Geometry *g, Mesh *m, int16 *dst)
|
||||
{
|
||||
float32 *tex = g->texCoords[0];
|
||||
uint16 j;
|
||||
for(uint32 i = 0; i < m->numIndices; i++){
|
||||
j = m->indices[i];
|
||||
if(tex){
|
||||
dst[0] = tex[j*2+0]*4096.0f;
|
||||
dst[1] = tex[j*2+1]*4096.0f;
|
||||
}else{
|
||||
dst[0] = 0;
|
||||
dst[1] = 0;
|
||||
}
|
||||
dst += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
instanceSADualTex(Geometry *g, Mesh *m, int16 *dst)
|
||||
{
|
||||
float32 *tex0 = g->texCoords[0];
|
||||
float32 *tex1 = g->texCoords[1];
|
||||
uint16 j;
|
||||
for(uint32 i = 0; i < m->numIndices; i++){
|
||||
j = m->indices[i];
|
||||
if(tex0){
|
||||
dst[0] = tex0[j*2+0]*4096.0f;
|
||||
dst[1] = tex0[j*2+1]*4096.0f;
|
||||
}else{
|
||||
dst[0] = 0;
|
||||
dst[1] = 0;
|
||||
}
|
||||
if(tex1){
|
||||
dst[2] = tex1[j*2+0]*4096.0f;
|
||||
dst[3] = tex1[j*2+1]*4096.0f;
|
||||
}else{
|
||||
dst[2] = 0;
|
||||
dst[3] = 0;
|
||||
}
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
instanceSAColors(Geometry *g, Mesh *m, uint8 *dst)
|
||||
{
|
||||
uint8 *c = g->colors;
|
||||
uint16 j;
|
||||
for(uint32 i = 0; i < m->numIndices; i++){
|
||||
j = m->indices[i];
|
||||
if(c)
|
||||
memcpy(dst, &c[j*4], 4);
|
||||
else
|
||||
memset(dst, 0xFF, 4);
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
instanceSADualColors(Geometry *g, Mesh *m, uint8 *dst)
|
||||
{
|
||||
uint8 *c0 = g->colors;
|
||||
uint8 *c1 =
|
||||
PLUGINOFFSET(ExtraVertColors, g, extraVertColorOffset)->nightColors;
|
||||
uint16 j;
|
||||
for(uint32 i = 0; i < m->numIndices; i++){
|
||||
j = m->indices[i];
|
||||
if(c0){
|
||||
dst[0] = c0[i*4+0];
|
||||
dst[2] = c0[i*4+1];
|
||||
dst[4] = c0[i*4+2];
|
||||
dst[6] = c0[i*4+3];
|
||||
}else{
|
||||
dst[0] = 0xFF;
|
||||
dst[2] = 0xFF;
|
||||
dst[4] = 0xFF;
|
||||
dst[6] = 0xFF;
|
||||
}
|
||||
if(c1){
|
||||
dst[1] = c1[i*4+0];
|
||||
dst[3] = c1[i*4+1];
|
||||
dst[6] = c1[i*4+2];
|
||||
dst[7] = c1[i*4+3];
|
||||
}else{
|
||||
dst[1] = 0xFF;
|
||||
dst[3] = 0xFF;
|
||||
dst[6] = 0xFF;
|
||||
dst[7] = 0xFF;
|
||||
}
|
||||
dst += 8;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
instanceSANormals(Geometry *g, Mesh *m, int8 *dst)
|
||||
{
|
||||
float32 *norms = g->morphTargets[0].normals;
|
||||
uint16 j;
|
||||
for(uint32 i = 0; i < m->numIndices; i++){
|
||||
j = m->indices[i];
|
||||
if(norms){
|
||||
dst[0] = norms[j*3+0]*127.0f;
|
||||
dst[1] = norms[j*3+1]*127.0f;
|
||||
dst[2] = norms[j*3+2]*127.0f;
|
||||
dst[3] = 0;
|
||||
}else
|
||||
memset(dst, 0, 4);
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
saInstanceCB(MatPipeline *pipe, Geometry *g, Mesh *m, uint8 **data)
|
||||
{
|
||||
uint32 id = pipe->pluginData;
|
||||
float vertScale = 128.0f;
|
||||
if(id == 0x53f20085 || id == 0x53f20087 ||
|
||||
id == 0x53f20089 || id == 0x53f2008b)
|
||||
vertScale = 1024.0f;
|
||||
ADCData *adc = PLUGINOFFSET(ADCData, g, adcOffset);
|
||||
|
||||
for(int i = 0; i < nelem(pipe->attribs); i++){
|
||||
PipeAttribute *a = pipe->attribs[i];
|
||||
if(a == &saXYZADC)
|
||||
instanceSAPositions(g, m, adc->adcFormatted ? adc->adcBits : NULL,
|
||||
(int16*)data[i], vertScale);
|
||||
if(a == &saUV)
|
||||
instanceSATex(g, m, (int16*)data[i]);
|
||||
if(a == &saUV2)
|
||||
instanceSADualTex(g, m, (int16*)data[i]);
|
||||
if(a == &saRGBA)
|
||||
instanceSAColors(g, m, (uint8*)data[i]);
|
||||
if(a == &saRGBA2)
|
||||
instanceSADualColors(g, m, (uint8*)data[i]);
|
||||
if(a == &saNormal)
|
||||
instanceSANormals(g, m, (int8*)data[i]);
|
||||
if(a == &saWeights){
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||
instanceSkinData(g, m, skin, (uint32*)data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
19
src/mdl.cpp
19
src/mdl.cpp
|
@ -136,20 +136,10 @@ skipUnpack(uint32 *p)
|
|||
return p + (n*unpackSize(p[0])+3 >> 2) + 1;
|
||||
}
|
||||
|
||||
struct RslVertex
|
||||
{
|
||||
float32 p[3];
|
||||
float32 n[3];
|
||||
float32 t[2];
|
||||
uint8 c[4];
|
||||
float32 w[4];
|
||||
uint8 i[4];
|
||||
};
|
||||
|
||||
void
|
||||
convertRslMesh(Geometry *g, RslGeometry *rg, Mesh *m, RslMesh *rm)
|
||||
{
|
||||
RslVertex v;
|
||||
ps2::SkinVertex v;
|
||||
uint32 mask = 0x1001; // tex coords, vertices
|
||||
if(g->geoflags & Geometry::NORMALS)
|
||||
mask |= 0x10;
|
||||
|
@ -168,9 +158,6 @@ convertRslMesh(Geometry *g, RslGeometry *rg, Mesh *m, RslMesh *rm)
|
|||
mask |= 0x10000;
|
||||
}
|
||||
|
||||
//float uScale = //halfFloat(rm->uvScale[0]);
|
||||
//float vScale = //halfFloat(rm->uvScale[1]);
|
||||
|
||||
int16 *vuVerts = NULL;
|
||||
int8 *vuNorms = NULL;
|
||||
uint8 *vuTex = NULL;
|
||||
|
@ -265,7 +252,7 @@ convertRslMesh(Geometry *g, RslGeometry *rg, Mesh *m, RslMesh *rm)
|
|||
}
|
||||
}
|
||||
|
||||
int32 idx = ps2::findVertexSkin(g, NULL, mask, 0, v.p, v.t, NULL, v.c, v.n, v.w, v.i);
|
||||
int32 idx = ps2::findVertexSkin(g, NULL, mask, &v);
|
||||
if(idx < 0)
|
||||
idx = g->numVertices++;
|
||||
/* Insert mesh joining indices when we get the index of the first vertex
|
||||
|
@ -278,7 +265,7 @@ convertRslMesh(Geometry *g, RslGeometry *rg, Mesh *m, RslMesh *rm)
|
|||
m->indices[m->numIndices++] = idx;
|
||||
}
|
||||
m->indices[m->numIndices++] = idx;
|
||||
ps2::insertVertexSkin(g, idx, mask, v.p, v.t, NULL, v.c, v.n, v.w, v.i);
|
||||
ps2::insertVertexSkin(g, idx, mask, &v);
|
||||
|
||||
vuVerts += 3;
|
||||
vuTex += 2;
|
||||
|
|
177
src/ps2.cpp
177
src/ps2.cpp
|
@ -445,7 +445,7 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||
uint8 **dp = datap;
|
||||
for(uint i = 0; i < nelem(this->attribs); i++)
|
||||
if((a = this->attribs[i]) && a->attrib & AT_RW)
|
||||
*dp++ = inst->data + im.attribPos[i]*0x10;
|
||||
dp[i] = inst->data + im.attribPos[i]*0x10;
|
||||
|
||||
uint32 idx = 0;
|
||||
uint32 *p = (uint32*)inst->data;
|
||||
|
@ -532,8 +532,8 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||
}
|
||||
}
|
||||
|
||||
if(instanceCB)
|
||||
instanceCB(this, g, m, datap, im.numBrokenAttribs);
|
||||
if(this->instanceCB)
|
||||
this->instanceCB(this, g, m, datap);
|
||||
}
|
||||
|
||||
uint8*
|
||||
|
@ -717,36 +717,30 @@ ObjPipeline::uninstance(Atomic *atomic)
|
|||
}
|
||||
|
||||
int32
|
||||
findVertex(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
||||
float *v, float *t0, float *t1, uint8 *c, float *n)
|
||||
findVertex(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
|
||||
{
|
||||
float32 *verts = &g->morphTargets[0].vertices[first*3];
|
||||
float32 *tex0 = &g->texCoords[0][first*2];
|
||||
float32 *tex1 = &g->texCoords[1][first*2];
|
||||
float32 *norms = &g->morphTargets[0].normals[first*3];
|
||||
uint8 *cols = &g->colors[first*4];
|
||||
float32 *verts = g->morphTargets[0].vertices;
|
||||
float32 *tex = g->texCoords[0];
|
||||
float32 *norms = g->morphTargets[0].normals;
|
||||
uint8 *cols = g->colors;
|
||||
|
||||
for(int32 i = first; i < g->numVertices; i++){
|
||||
for(int32 i = 0; i < g->numVertices; i++){
|
||||
if(mask & flags[i] & 0x1 &&
|
||||
!(verts[0] == v[0] && verts[1] == v[1] && verts[2] == v[2]))
|
||||
!(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2]))
|
||||
goto cont;
|
||||
if(mask & flags[i] & 0x10 &&
|
||||
!(norms[0] == n[0] && norms[1] == n[1] && norms[2] == n[2]))
|
||||
!(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
|
||||
goto cont;
|
||||
if(mask & flags[i] & 0x100 &&
|
||||
!(cols[0] == c[0] && cols[1] == c[1] && cols[2] == c[2] && cols[3] == c[3]))
|
||||
!(cols[0] == v->c[0] && cols[1] == v->c[1] && cols[2] == v->c[2] && cols[3] == v->c[3]))
|
||||
goto cont;
|
||||
if(mask & flags[i] & 0x1000 &&
|
||||
!(tex0[0] == t0[0] && tex0[1] == t0[1]))
|
||||
goto cont;
|
||||
if(mask & flags[i] & 0x2000 &&
|
||||
!(tex1[0] == t1[0] && tex1[1] == t1[1]))
|
||||
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
|
||||
goto cont;
|
||||
return i;
|
||||
cont:
|
||||
verts += 3;
|
||||
tex0 += 2;
|
||||
tex1 += 2;
|
||||
tex += 2;
|
||||
norms += 3;
|
||||
cols += 4;
|
||||
}
|
||||
|
@ -754,18 +748,16 @@ findVertex(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
|||
}
|
||||
|
||||
void
|
||||
insertVertex(Geometry *geo, int32 i, uint32 mask, float *v, float *t0, float *t1, uint8 *c, float *n)
|
||||
insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v)
|
||||
{
|
||||
if(mask & 0x1)
|
||||
memcpy(&geo->morphTargets[0].vertices[i*3], v, 12);
|
||||
memcpy(&geo->morphTargets[0].vertices[i*3], v->p, 12);
|
||||
if(mask & 0x10)
|
||||
memcpy(&geo->morphTargets[0].normals[i*3], n, 12);
|
||||
memcpy(&geo->morphTargets[0].normals[i*3], v->n, 12);
|
||||
if(mask & 0x100)
|
||||
memcpy(&geo->colors[i*4], c, 4);
|
||||
memcpy(&geo->colors[i*4], v->c, 4);
|
||||
if(mask & 0x1000)
|
||||
memcpy(&geo->texCoords[0][i*2], t0, 8);
|
||||
if(mask & 0x2000)
|
||||
memcpy(&geo->texCoords[1][i*2], t1, 8);
|
||||
memcpy(&geo->texCoords[0][i*2], v->t, 8);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -784,18 +776,26 @@ defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
|
|||
mask |= 0x1000;
|
||||
|
||||
float32 n[3];
|
||||
Vertex v;
|
||||
for(uint32 i = 0; i < mesh->numIndices; i++){
|
||||
if(mask & 0x1)
|
||||
memcpy(&v.p, verts, 12);
|
||||
if(mask & 0x10){
|
||||
n[0] = norms[0]/127.0f;
|
||||
n[1] = norms[1]/127.0f;
|
||||
n[2] = norms[2]/127.0f;
|
||||
}
|
||||
int32 idx = findVertex(geo, flags, mask, 0, verts, texcoords, NULL, colors, n);
|
||||
if(mask & 0x100)
|
||||
memcpy(&v.c, colors, 4);
|
||||
if(mask & 0x1000)
|
||||
memcpy(&v.t, texcoords, 8);
|
||||
|
||||
int32 idx = findVertex(geo, flags, mask, &v);
|
||||
if(idx < 0)
|
||||
idx = geo->numVertices++;
|
||||
mesh->indices[i] = idx;
|
||||
flags[idx] = mask;
|
||||
insertVertex(geo, idx, mask, verts, texcoords, NULL, colors, n);
|
||||
insertVertex(geo, idx, mask, &v);
|
||||
verts += 3;
|
||||
texcoords += 2;
|
||||
colors += 4;
|
||||
|
@ -828,7 +828,7 @@ makeDefaultPipeline(void)
|
|||
return defaultObjPipe;
|
||||
}
|
||||
|
||||
static void skinInstanceCB(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
|
||||
static void skinInstanceCB(MatPipeline*, Geometry*, Mesh*, uint8**);
|
||||
static void skinUninstanceCB(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
||||
|
||||
ObjPipeline*
|
||||
|
@ -965,84 +965,73 @@ getSizeNativeSkin(void *object, int32 offset)
|
|||
return size;
|
||||
}
|
||||
|
||||
static void
|
||||
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data, int32 n)
|
||||
void
|
||||
instanceSkinData(Geometry *g, Mesh *m, Skin *skin, uint32 *data)
|
||||
{
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||
if(skin == NULL || n < 1)
|
||||
return;
|
||||
float32 *weights = (float32*)data[0];
|
||||
uint32 *indices = (uint32*)data[0];
|
||||
uint16 j;
|
||||
float32 *weights = (float32*)data;
|
||||
uint32 *indices = data;
|
||||
for(uint32 i = 0; i < m->numIndices; i++){
|
||||
j = m->indices[i];
|
||||
*weights++ = skin->weights[j*4+0];
|
||||
*indices &= ~0x3FF;
|
||||
*indices++ |= skin->indices[j*4+0] && skin->weights[j*4+0] ?
|
||||
(skin->indices[j*4+0]+1) << 2 : 0;
|
||||
*weights++ = skin->weights[j*4+1];
|
||||
*indices &= ~0x3FF;
|
||||
*indices++ |= skin->indices[j*4+1] && skin->weights[j*4+1] ?
|
||||
(skin->indices[j*4+1]+1) << 2 : 0;
|
||||
*weights++ = skin->weights[j*4+2];
|
||||
*indices &= ~0x3FF;
|
||||
*indices++ |= skin->indices[j*4+2] && skin->weights[j*4+2] ?
|
||||
(skin->indices[j*4+2]+1) << 2 : 0;
|
||||
*weights++ = skin->weights[j*4+3];
|
||||
*indices &= ~0x3FF;
|
||||
*indices++ |= skin->indices[j*4+3] && skin->weights[j*4+3] ?
|
||||
(skin->indices[j*4+3]+1) << 2 : 0;
|
||||
for(int32 k = 0; k < 4; k++){
|
||||
*weights++ = skin->weights[j*4+k];
|
||||
*indices &= ~0x3FF;
|
||||
*indices++ |= skin->indices[j*4+k] && skin->weights[j*4+k] ?
|
||||
(skin->indices[j*4+k]+1) << 2 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data)
|
||||
{
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||
if(skin == NULL)
|
||||
return;
|
||||
instanceSkinData(g, m, skin, (uint32*)data[4]);
|
||||
}
|
||||
|
||||
// TODO: call base function perhaps?
|
||||
int32
|
||||
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
||||
float32 *v, float32 *t0, float32 *t1, uint8 *c, float32 *n,
|
||||
float32 *w, uint8 *ix)
|
||||
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, SkinVertex *v)
|
||||
{
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||
float32 *wghts = NULL;
|
||||
uint8 *inds = NULL;
|
||||
if(skin){
|
||||
wghts = &skin->weights[first*4];
|
||||
inds = &skin->indices[first*4];
|
||||
wghts = skin->weights;
|
||||
inds = skin->indices;
|
||||
}
|
||||
|
||||
float32 *verts = &g->morphTargets[0].vertices[first*3];
|
||||
float32 *tex0 = &g->texCoords[0][first*2];
|
||||
float32 *tex1 = &g->texCoords[1][first*2];
|
||||
float32 *norms = &g->morphTargets[0].normals[first*3];
|
||||
uint8 *cols = &g->colors[first*4];
|
||||
float32 *verts = g->morphTargets[0].vertices;
|
||||
float32 *tex = g->texCoords[0];
|
||||
float32 *norms = g->morphTargets[0].normals;
|
||||
uint8 *cols = g->colors;
|
||||
|
||||
for(int32 i = first; i < g->numVertices; i++){
|
||||
for(int32 i = 0; i < g->numVertices; i++){
|
||||
uint32 flag = flags ? flags[i] : ~0;
|
||||
if(mask & flag & 0x1 &&
|
||||
!(verts[0] == v[0] && verts[1] == v[1] && verts[2] == v[2]))
|
||||
!(verts[0] == v->p[0] && verts[1] == v->p[1] && verts[2] == v->p[2]))
|
||||
goto cont;
|
||||
if(mask & flag & 0x10 &&
|
||||
!(norms[0] == n[0] && norms[1] == n[1] && norms[2] == n[2]))
|
||||
!(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
|
||||
goto cont;
|
||||
if(mask & flag & 0x100 &&
|
||||
!(cols[0] == c[0] && cols[1] == c[1] && cols[2] == c[2] && cols[3] == c[3]))
|
||||
!(cols[0] == v->c[0] && cols[1] == v->c[1] && cols[2] == v->c[2] && cols[3] == v->c[3]))
|
||||
goto cont;
|
||||
if(mask & flag & 0x1000 &&
|
||||
!(tex0[0] == t0[0] && tex0[1] == t0[1]))
|
||||
goto cont;
|
||||
if(mask & flag & 0x2000 &&
|
||||
!(tex1[0] == t1[0] && tex1[1] == t1[1]))
|
||||
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
|
||||
goto cont;
|
||||
if(mask & flag & 0x10000 &&
|
||||
!(wghts[0] == w[0] && wghts[1] == w[1] &&
|
||||
wghts[2] == w[2] && wghts[3] == w[3] &&
|
||||
inds[0] == ix[0] && inds[1] == ix[1] &&
|
||||
inds[2] == ix[2] && inds[3] == ix[3]))
|
||||
!(wghts[0] == v->w[0] && wghts[1] == v->w[1] &&
|
||||
wghts[2] == v->w[2] && wghts[3] == v->w[3] &&
|
||||
inds[0] == v->i[0] && inds[1] == v->i[1] &&
|
||||
inds[2] == v->i[2] && inds[3] == v->i[3]))
|
||||
goto cont;
|
||||
return i;
|
||||
cont:
|
||||
verts += 3;
|
||||
tex0 += 2;
|
||||
tex1 += 2;
|
||||
tex += 2;
|
||||
norms += 3;
|
||||
cols += 4;
|
||||
wghts += 4;
|
||||
|
@ -1052,14 +1041,13 @@ findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
|||
}
|
||||
|
||||
void
|
||||
insertVertexSkin(Geometry *geo, int32 i, uint32 mask, float32 *v, float32 *t0, float32 *t1, uint8 *c, float32 *n,
|
||||
float32 *w, uint8 *ix)
|
||||
insertVertexSkin(Geometry *geo, int32 i, uint32 mask, SkinVertex *v)
|
||||
{
|
||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||
insertVertex(geo, i, mask, v, t0, t1, c, n);
|
||||
insertVertex(geo, i, mask, v);
|
||||
if(mask & 0x10000){
|
||||
memcpy(&skin->weights[i*4], w, 16);
|
||||
memcpy(&skin->indices[i*4], ix, 4);
|
||||
memcpy(&skin->weights[i*4], v->w, 16);
|
||||
memcpy(&skin->indices[i*4], v->i, 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1083,24 +1071,31 @@ skinUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh, u
|
|||
float32 n[3];
|
||||
float32 w[4];
|
||||
uint8 ix[4];
|
||||
SkinVertex v;
|
||||
for(uint32 i = 0; i < mesh->numIndices; i++){
|
||||
if(mask & 0x1)
|
||||
memcpy(&v.p, verts, 12);
|
||||
if(mask & 0x10){
|
||||
n[0] = norms[0]/127.0f;
|
||||
n[1] = norms[1]/127.0f;
|
||||
n[2] = norms[2]/127.0f;
|
||||
v.n[0] = norms[0]/127.0f;
|
||||
v.n[1] = norms[1]/127.0f;
|
||||
v.n[2] = norms[2]/127.0f;
|
||||
}
|
||||
if(mask & 0x100)
|
||||
memcpy(&v.c, colors, 4);
|
||||
if(mask & 0x1000)
|
||||
memcpy(&v.t, texcoords, 8);
|
||||
for(int j = 0; j < 4; j++){
|
||||
((uint32*)w)[j] = wghts[j] & ~0x3FF;
|
||||
ix[j] = (wghts[j] & 0x3FF) >> 2;
|
||||
if(ix[j]) ix[j]--;
|
||||
if(w[j] == 0.0f) ix[j] = 0;
|
||||
((uint32*)v.w)[j] = wghts[j] & ~0x3FF;
|
||||
v.i[j] = (wghts[j] & 0x3FF) >> 2;
|
||||
if(v.i[j]) v.i[j]--;
|
||||
if(v.w[j] == 0.0f) v.i[j] = 0;
|
||||
}
|
||||
int32 idx = findVertexSkin(geo, flags, mask, 0, verts, texcoords, NULL, colors, n, w, ix);
|
||||
int32 idx = findVertexSkin(geo, flags, mask, &v);
|
||||
if(idx < 0)
|
||||
idx = geo->numVertices++;
|
||||
mesh->indices[i] = idx;
|
||||
flags[idx] = mask;
|
||||
insertVertexSkin(geo, idx, mask, verts, texcoords, NULL, colors, n, w, ix);
|
||||
insertVertexSkin(geo, idx, mask, &v);
|
||||
verts += 3;
|
||||
texcoords += 2;
|
||||
colors += 4;
|
||||
|
|
27
src/rwps2.h
27
src/rwps2.h
|
@ -66,7 +66,7 @@ public:
|
|||
uint32 inputStride;
|
||||
uint32 triStripCount, triListCount;
|
||||
PipeAttribute *attribs[10];
|
||||
void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
|
||||
void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**);
|
||||
void (*uninstanceCB)(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
||||
void (*preUninstCB)(MatPipeline*, Geometry*);
|
||||
void (*postUninstCB)(MatPipeline*, Geometry*);
|
||||
|
@ -93,13 +93,14 @@ public:
|
|||
virtual void uninstance(Atomic *atomic);
|
||||
};
|
||||
|
||||
// TODO: better use a struct, this is terrible
|
||||
void insertVertex(Geometry *geo, int32 i, uint32 mask, float *v, float *t0, float *t1, uint8 *c, float *n);
|
||||
void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, float32 *v, float32 *t0, float32 *t1, uint8 *c, float32 *n,
|
||||
float32 *w, uint8 *ix);
|
||||
int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
||||
float32 *v, float32 *t0, float32 *t1, uint8 *c, float32 *n,
|
||||
float32 *w, uint8 *ix);
|
||||
struct Vertex {
|
||||
float32 p[3];
|
||||
float32 t[2];
|
||||
uint8 c[4];
|
||||
float32 n[3];
|
||||
};
|
||||
|
||||
void insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v);
|
||||
|
||||
extern ObjPipeline *defaultObjPipe;
|
||||
extern MatPipeline *defaultMatPipe;
|
||||
|
@ -111,10 +112,20 @@ void dumpPipeline(rw::Pipeline *pipe);
|
|||
|
||||
// Skin plugin
|
||||
|
||||
struct SkinVertex : Vertex {
|
||||
float32 w[4];
|
||||
uint8 i[4];
|
||||
};
|
||||
|
||||
void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, SkinVertex *v);
|
||||
int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, SkinVertex *v);
|
||||
|
||||
void readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||
int32 getSizeNativeSkin(void *object, int32 offset);
|
||||
|
||||
void instanceSkinData(Geometry *g, Mesh *m, Skin *skin, uint32 *data);
|
||||
|
||||
void skinPreCB(MatPipeline*, Geometry*);
|
||||
void skinPostCB(MatPipeline*, Geometry*);
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ main(int argc, char *argv[])
|
|||
rw::version = 0;
|
||||
// rw::version = 0x34003;
|
||||
// rw::version = 0x33002;
|
||||
// rw::platform = rw::PLATFORM_PS2;
|
||||
rw::platform = rw::PLATFORM_PS2;
|
||||
// rw::platform = rw::PLATFORM_OGL;
|
||||
// rw::platform = rw::PLATFORM_XBOX;
|
||||
rw::platform = rw::PLATFORM_D3D8;
|
||||
// rw::platform = rw::PLATFORM_D3D8;
|
||||
// rw::platform = rw::PLATFORM_D3D9;
|
||||
|
||||
int uninstance = 0;
|
||||
|
@ -86,7 +86,7 @@ main(int argc, char *argv[])
|
|||
ObjPipeline *p = a->getPipeline();
|
||||
if(uninstance){
|
||||
p->uninstance(a);
|
||||
ps2::unconvertADC(a->geometry);
|
||||
//ps2::unconvertADC(a->geometry);
|
||||
}else
|
||||
p->instance(a);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue