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;
|
return id == 0x53f20083 || id == 0x53f2008f;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SaVert {
|
struct SaVert : ps2::Vertex {
|
||||||
float32 p[3];
|
|
||||||
float32 n[3];
|
|
||||||
float32 t0[2];
|
|
||||||
float32 t1[2];
|
|
||||||
uint8 c0[4];
|
|
||||||
uint8 c1[4];
|
|
||||||
float32 w[4];
|
float32 w[4];
|
||||||
uint8 i[4];
|
uint8 i[4];
|
||||||
|
float32 t1[2];
|
||||||
|
uint8 c1[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
saPreCB(MatPipeline *p, Geometry *geo)
|
saPreCB(MatPipeline *p, Geometry *geo)
|
||||||
{
|
{
|
||||||
// allocate ADC, extra colors, skin
|
|
||||||
allocateADC(geo);
|
allocateADC(geo);
|
||||||
if(hasColors2(p->pluginData) && extraVertColorOffset)
|
if(hasColors2(p->pluginData) && extraVertColorOffset)
|
||||||
allocateExtraVertColors(geo);
|
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]))
|
!(norms[0] == v->n[0] && norms[1] == v->n[1] && norms[2] == v->n[2]))
|
||||||
goto cont;
|
goto cont;
|
||||||
if(mask & flags[i] & 0x100 &&
|
if(mask & flags[i] & 0x100 &&
|
||||||
!(cols0[0] == v->c0[0] && cols0[1] == v->c0[1] &&
|
!(cols0[0] == v->c[0] && cols0[1] == v->c[1] &&
|
||||||
cols0[2] == v->c0[2] && cols0[3] == v->c0[3]))
|
cols0[2] == v->c[2] && cols0[3] == v->c[3]))
|
||||||
goto cont;
|
goto cont;
|
||||||
if(mask & flags[i] & 0x200 &&
|
if(mask & flags[i] & 0x200 &&
|
||||||
!(cols1[0] == v->c1[0] && cols1[1] == v->c1[1] &&
|
!(cols1[0] == v->c1[0] && cols1[1] == v->c1[1] &&
|
||||||
cols1[2] == v->c1[2] && cols1[3] == v->c1[3]))
|
cols1[2] == v->c1[2] && cols1[3] == v->c1[3]))
|
||||||
goto cont;
|
goto cont;
|
||||||
if(mask & flags[i] & 0x1000 &&
|
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;
|
goto cont;
|
||||||
if(mask & flags[i] & 0x2000 &&
|
if(mask & flags[i] & 0x2000 &&
|
||||||
!(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
|
!(tex1[0] == v->t1[0] && tex1[1] == v->t1[1]))
|
||||||
|
@ -960,7 +955,9 @@ findSAVertex(Geometry *g, uint32 flags[], uint32 mask, SaVert *v)
|
||||||
void
|
void
|
||||||
insertSAVertex(Geometry *geo, int32 i, uint32 mask, SaVert *v)
|
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){
|
if(mask & 0x200 && extraVertColorOffset){
|
||||||
uint8 *cols1 =
|
uint8 *cols1 =
|
||||||
&PLUGINOFFSET(ExtraVertColors, geo, extraVertColorOffset)->nightColors[i*4];
|
&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;
|
v.n[2] = norms[2]/127.0f;
|
||||||
}
|
}
|
||||||
if(mask & 0x200){
|
if(mask & 0x200){
|
||||||
v.c0[0] = colors[0];
|
v.c[0] = colors[0];
|
||||||
v.c0[1] = colors[2];
|
v.c[1] = colors[2];
|
||||||
v.c0[2] = colors[4];
|
v.c[2] = colors[4];
|
||||||
v.c0[3] = colors[6];
|
v.c[3] = colors[6];
|
||||||
v.c1[0] = colors[1];
|
v.c1[0] = colors[1];
|
||||||
v.c1[1] = colors[3];
|
v.c1[1] = colors[3];
|
||||||
v.c1[2] = colors[5];
|
v.c1[2] = colors[5];
|
||||||
v.c1[3] = colors[7];
|
v.c1[3] = colors[7];
|
||||||
}else if(mask & 0x100){
|
}else if(mask & 0x100){
|
||||||
v.c0[0] = colors[0];
|
v.c[0] = colors[0];
|
||||||
v.c0[1] = colors[1];
|
v.c[1] = colors[1];
|
||||||
v.c0[2] = colors[2];
|
v.c[2] = colors[2];
|
||||||
v.c0[3] = colors[3];
|
v.c[3] = colors[3];
|
||||||
}
|
}
|
||||||
if(mask & 0x1000){
|
if(mask & 0x1000){
|
||||||
v.t0[0] = texcoords[0]/4096.0f;
|
v.t[0] = texcoords[0]/4096.0f;
|
||||||
v.t0[1] = texcoords[1]/4096.0f;
|
v.t[1] = texcoords[1]/4096.0f;
|
||||||
}
|
}
|
||||||
if(mask & 0x2000){
|
if(mask & 0x2000){
|
||||||
v.t1[0] = texcoords[2]/4096.0f;
|
v.t1[0] = texcoords[2]/4096.0f;
|
||||||
|
@ -1071,8 +1068,162 @@ saUninstanceCB(ps2::MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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
|
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;
|
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
|
void
|
||||||
convertRslMesh(Geometry *g, RslGeometry *rg, Mesh *m, RslMesh *rm)
|
convertRslMesh(Geometry *g, RslGeometry *rg, Mesh *m, RslMesh *rm)
|
||||||
{
|
{
|
||||||
RslVertex v;
|
ps2::SkinVertex v;
|
||||||
uint32 mask = 0x1001; // tex coords, vertices
|
uint32 mask = 0x1001; // tex coords, vertices
|
||||||
if(g->geoflags & Geometry::NORMALS)
|
if(g->geoflags & Geometry::NORMALS)
|
||||||
mask |= 0x10;
|
mask |= 0x10;
|
||||||
|
@ -168,9 +158,6 @@ convertRslMesh(Geometry *g, RslGeometry *rg, Mesh *m, RslMesh *rm)
|
||||||
mask |= 0x10000;
|
mask |= 0x10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
//float uScale = //halfFloat(rm->uvScale[0]);
|
|
||||||
//float vScale = //halfFloat(rm->uvScale[1]);
|
|
||||||
|
|
||||||
int16 *vuVerts = NULL;
|
int16 *vuVerts = NULL;
|
||||||
int8 *vuNorms = NULL;
|
int8 *vuNorms = NULL;
|
||||||
uint8 *vuTex = 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)
|
if(idx < 0)
|
||||||
idx = g->numVertices++;
|
idx = g->numVertices++;
|
||||||
/* Insert mesh joining indices when we get the index of the first vertex
|
/* 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;
|
||||||
}
|
}
|
||||||
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;
|
vuVerts += 3;
|
||||||
vuTex += 2;
|
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;
|
uint8 **dp = datap;
|
||||||
for(uint i = 0; i < nelem(this->attribs); i++)
|
for(uint i = 0; i < nelem(this->attribs); i++)
|
||||||
if((a = this->attribs[i]) && a->attrib & AT_RW)
|
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 idx = 0;
|
||||||
uint32 *p = (uint32*)inst->data;
|
uint32 *p = (uint32*)inst->data;
|
||||||
|
@ -532,8 +532,8 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(instanceCB)
|
if(this->instanceCB)
|
||||||
instanceCB(this, g, m, datap, im.numBrokenAttribs);
|
this->instanceCB(this, g, m, datap);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8*
|
uint8*
|
||||||
|
@ -717,36 +717,30 @@ ObjPipeline::uninstance(Atomic *atomic)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32
|
int32
|
||||||
findVertex(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
findVertex(Geometry *g, uint32 flags[], uint32 mask, Vertex *v)
|
||||||
float *v, float *t0, float *t1, uint8 *c, float *n)
|
|
||||||
{
|
{
|
||||||
float32 *verts = &g->morphTargets[0].vertices[first*3];
|
float32 *verts = g->morphTargets[0].vertices;
|
||||||
float32 *tex0 = &g->texCoords[0][first*2];
|
float32 *tex = g->texCoords[0];
|
||||||
float32 *tex1 = &g->texCoords[1][first*2];
|
float32 *norms = g->morphTargets[0].normals;
|
||||||
float32 *norms = &g->morphTargets[0].normals[first*3];
|
uint8 *cols = g->colors;
|
||||||
uint8 *cols = &g->colors[first*4];
|
|
||||||
|
|
||||||
for(int32 i = first; i < g->numVertices; i++){
|
for(int32 i = 0; i < g->numVertices; i++){
|
||||||
if(mask & flags[i] & 0x1 &&
|
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;
|
goto cont;
|
||||||
if(mask & flags[i] & 0x10 &&
|
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;
|
goto cont;
|
||||||
if(mask & flags[i] & 0x100 &&
|
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;
|
goto cont;
|
||||||
if(mask & flags[i] & 0x1000 &&
|
if(mask & flags[i] & 0x1000 &&
|
||||||
!(tex0[0] == t0[0] && tex0[1] == t0[1]))
|
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
|
||||||
goto cont;
|
|
||||||
if(mask & flags[i] & 0x2000 &&
|
|
||||||
!(tex1[0] == t1[0] && tex1[1] == t1[1]))
|
|
||||||
goto cont;
|
goto cont;
|
||||||
return i;
|
return i;
|
||||||
cont:
|
cont:
|
||||||
verts += 3;
|
verts += 3;
|
||||||
tex0 += 2;
|
tex += 2;
|
||||||
tex1 += 2;
|
|
||||||
norms += 3;
|
norms += 3;
|
||||||
cols += 4;
|
cols += 4;
|
||||||
}
|
}
|
||||||
|
@ -754,18 +748,16 @@ findVertex(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)
|
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)
|
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)
|
if(mask & 0x100)
|
||||||
memcpy(&geo->colors[i*4], c, 4);
|
memcpy(&geo->colors[i*4], v->c, 4);
|
||||||
if(mask & 0x1000)
|
if(mask & 0x1000)
|
||||||
memcpy(&geo->texCoords[0][i*2], t0, 8);
|
memcpy(&geo->texCoords[0][i*2], v->t, 8);
|
||||||
if(mask & 0x2000)
|
|
||||||
memcpy(&geo->texCoords[1][i*2], t1, 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -784,18 +776,26 @@ defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
|
||||||
mask |= 0x1000;
|
mask |= 0x1000;
|
||||||
|
|
||||||
float32 n[3];
|
float32 n[3];
|
||||||
|
Vertex v;
|
||||||
for(uint32 i = 0; i < mesh->numIndices; i++){
|
for(uint32 i = 0; i < mesh->numIndices; i++){
|
||||||
|
if(mask & 0x1)
|
||||||
|
memcpy(&v.p, verts, 12);
|
||||||
if(mask & 0x10){
|
if(mask & 0x10){
|
||||||
n[0] = norms[0]/127.0f;
|
n[0] = norms[0]/127.0f;
|
||||||
n[1] = norms[1]/127.0f;
|
n[1] = norms[1]/127.0f;
|
||||||
n[2] = norms[2]/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)
|
if(idx < 0)
|
||||||
idx = geo->numVertices++;
|
idx = geo->numVertices++;
|
||||||
mesh->indices[i] = idx;
|
mesh->indices[i] = idx;
|
||||||
flags[idx] = mask;
|
flags[idx] = mask;
|
||||||
insertVertex(geo, idx, mask, verts, texcoords, NULL, colors, n);
|
insertVertex(geo, idx, mask, &v);
|
||||||
verts += 3;
|
verts += 3;
|
||||||
texcoords += 2;
|
texcoords += 2;
|
||||||
colors += 4;
|
colors += 4;
|
||||||
|
@ -828,7 +828,7 @@ makeDefaultPipeline(void)
|
||||||
return defaultObjPipe;
|
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**);
|
static void skinUninstanceCB(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
||||||
|
|
||||||
ObjPipeline*
|
ObjPipeline*
|
||||||
|
@ -965,84 +965,73 @@ getSizeNativeSkin(void *object, int32 offset)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
skinInstanceCB(MatPipeline *, Geometry *g, Mesh *m, uint8 **data, int32 n)
|
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;
|
uint16 j;
|
||||||
|
float32 *weights = (float32*)data;
|
||||||
|
uint32 *indices = data;
|
||||||
for(uint32 i = 0; i < m->numIndices; i++){
|
for(uint32 i = 0; i < m->numIndices; i++){
|
||||||
j = m->indices[i];
|
j = m->indices[i];
|
||||||
*weights++ = skin->weights[j*4+0];
|
for(int32 k = 0; k < 4; k++){
|
||||||
*indices &= ~0x3FF;
|
*weights++ = skin->weights[j*4+k];
|
||||||
*indices++ |= skin->indices[j*4+0] && skin->weights[j*4+0] ?
|
*indices &= ~0x3FF;
|
||||||
(skin->indices[j*4+0]+1) << 2 : 0;
|
*indices++ |= skin->indices[j*4+k] && skin->weights[j*4+k] ?
|
||||||
*weights++ = skin->weights[j*4+1];
|
(skin->indices[j*4+k]+1) << 2 : 0;
|
||||||
*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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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?
|
// TODO: call base function perhaps?
|
||||||
int32
|
int32
|
||||||
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, SkinVertex *v)
|
||||||
float32 *v, float32 *t0, float32 *t1, uint8 *c, float32 *n,
|
|
||||||
float32 *w, uint8 *ix)
|
|
||||||
{
|
{
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
Skin *skin = *PLUGINOFFSET(Skin*, g, skinGlobals.offset);
|
||||||
float32 *wghts = NULL;
|
float32 *wghts = NULL;
|
||||||
uint8 *inds = NULL;
|
uint8 *inds = NULL;
|
||||||
if(skin){
|
if(skin){
|
||||||
wghts = &skin->weights[first*4];
|
wghts = skin->weights;
|
||||||
inds = &skin->indices[first*4];
|
inds = skin->indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
float32 *verts = &g->morphTargets[0].vertices[first*3];
|
float32 *verts = g->morphTargets[0].vertices;
|
||||||
float32 *tex0 = &g->texCoords[0][first*2];
|
float32 *tex = g->texCoords[0];
|
||||||
float32 *tex1 = &g->texCoords[1][first*2];
|
float32 *norms = g->morphTargets[0].normals;
|
||||||
float32 *norms = &g->morphTargets[0].normals[first*3];
|
uint8 *cols = g->colors;
|
||||||
uint8 *cols = &g->colors[first*4];
|
|
||||||
|
|
||||||
for(int32 i = first; i < g->numVertices; i++){
|
for(int32 i = 0; i < g->numVertices; i++){
|
||||||
uint32 flag = flags ? flags[i] : ~0;
|
uint32 flag = flags ? flags[i] : ~0;
|
||||||
if(mask & flag & 0x1 &&
|
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;
|
goto cont;
|
||||||
if(mask & flag & 0x10 &&
|
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;
|
goto cont;
|
||||||
if(mask & flag & 0x100 &&
|
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;
|
goto cont;
|
||||||
if(mask & flag & 0x1000 &&
|
if(mask & flag & 0x1000 &&
|
||||||
!(tex0[0] == t0[0] && tex0[1] == t0[1]))
|
!(tex[0] == v->t[0] && tex[1] == v->t[1]))
|
||||||
goto cont;
|
|
||||||
if(mask & flag & 0x2000 &&
|
|
||||||
!(tex1[0] == t1[0] && tex1[1] == t1[1]))
|
|
||||||
goto cont;
|
goto cont;
|
||||||
if(mask & flag & 0x10000 &&
|
if(mask & flag & 0x10000 &&
|
||||||
!(wghts[0] == w[0] && wghts[1] == w[1] &&
|
!(wghts[0] == v->w[0] && wghts[1] == v->w[1] &&
|
||||||
wghts[2] == w[2] && wghts[3] == w[3] &&
|
wghts[2] == v->w[2] && wghts[3] == v->w[3] &&
|
||||||
inds[0] == ix[0] && inds[1] == ix[1] &&
|
inds[0] == v->i[0] && inds[1] == v->i[1] &&
|
||||||
inds[2] == ix[2] && inds[3] == ix[3]))
|
inds[2] == v->i[2] && inds[3] == v->i[3]))
|
||||||
goto cont;
|
goto cont;
|
||||||
return i;
|
return i;
|
||||||
cont:
|
cont:
|
||||||
verts += 3;
|
verts += 3;
|
||||||
tex0 += 2;
|
tex += 2;
|
||||||
tex1 += 2;
|
|
||||||
norms += 3;
|
norms += 3;
|
||||||
cols += 4;
|
cols += 4;
|
||||||
wghts += 4;
|
wghts += 4;
|
||||||
|
@ -1052,14 +1041,13 @@ findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
insertVertexSkin(Geometry *geo, int32 i, uint32 mask, float32 *v, float32 *t0, float32 *t1, uint8 *c, float32 *n,
|
insertVertexSkin(Geometry *geo, int32 i, uint32 mask, SkinVertex *v)
|
||||||
float32 *w, uint8 *ix)
|
|
||||||
{
|
{
|
||||||
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
Skin *skin = *PLUGINOFFSET(Skin*, geo, skinGlobals.offset);
|
||||||
insertVertex(geo, i, mask, v, t0, t1, c, n);
|
insertVertex(geo, i, mask, v);
|
||||||
if(mask & 0x10000){
|
if(mask & 0x10000){
|
||||||
memcpy(&skin->weights[i*4], w, 16);
|
memcpy(&skin->weights[i*4], v->w, 16);
|
||||||
memcpy(&skin->indices[i*4], ix, 4);
|
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 n[3];
|
||||||
float32 w[4];
|
float32 w[4];
|
||||||
uint8 ix[4];
|
uint8 ix[4];
|
||||||
|
SkinVertex v;
|
||||||
for(uint32 i = 0; i < mesh->numIndices; i++){
|
for(uint32 i = 0; i < mesh->numIndices; i++){
|
||||||
|
if(mask & 0x1)
|
||||||
|
memcpy(&v.p, verts, 12);
|
||||||
if(mask & 0x10){
|
if(mask & 0x10){
|
||||||
n[0] = norms[0]/127.0f;
|
v.n[0] = norms[0]/127.0f;
|
||||||
n[1] = norms[1]/127.0f;
|
v.n[1] = norms[1]/127.0f;
|
||||||
n[2] = norms[2]/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++){
|
for(int j = 0; j < 4; j++){
|
||||||
((uint32*)w)[j] = wghts[j] & ~0x3FF;
|
((uint32*)v.w)[j] = wghts[j] & ~0x3FF;
|
||||||
ix[j] = (wghts[j] & 0x3FF) >> 2;
|
v.i[j] = (wghts[j] & 0x3FF) >> 2;
|
||||||
if(ix[j]) ix[j]--;
|
if(v.i[j]) v.i[j]--;
|
||||||
if(w[j] == 0.0f) ix[j] = 0;
|
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)
|
if(idx < 0)
|
||||||
idx = geo->numVertices++;
|
idx = geo->numVertices++;
|
||||||
mesh->indices[i] = idx;
|
mesh->indices[i] = idx;
|
||||||
flags[idx] = mask;
|
flags[idx] = mask;
|
||||||
insertVertexSkin(geo, idx, mask, verts, texcoords, NULL, colors, n, w, ix);
|
insertVertexSkin(geo, idx, mask, &v);
|
||||||
verts += 3;
|
verts += 3;
|
||||||
texcoords += 2;
|
texcoords += 2;
|
||||||
colors += 4;
|
colors += 4;
|
||||||
|
|
27
src/rwps2.h
27
src/rwps2.h
|
@ -66,7 +66,7 @@ public:
|
||||||
uint32 inputStride;
|
uint32 inputStride;
|
||||||
uint32 triStripCount, triListCount;
|
uint32 triStripCount, triListCount;
|
||||||
PipeAttribute *attribs[10];
|
PipeAttribute *attribs[10];
|
||||||
void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**, int32);
|
void (*instanceCB)(MatPipeline*, Geometry*, Mesh*, uint8**);
|
||||||
void (*uninstanceCB)(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
void (*uninstanceCB)(MatPipeline*, Geometry*, uint32*, Mesh*, uint8**);
|
||||||
void (*preUninstCB)(MatPipeline*, Geometry*);
|
void (*preUninstCB)(MatPipeline*, Geometry*);
|
||||||
void (*postUninstCB)(MatPipeline*, Geometry*);
|
void (*postUninstCB)(MatPipeline*, Geometry*);
|
||||||
|
@ -93,13 +93,14 @@ public:
|
||||||
virtual void uninstance(Atomic *atomic);
|
virtual void uninstance(Atomic *atomic);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: better use a struct, this is terrible
|
struct Vertex {
|
||||||
void insertVertex(Geometry *geo, int32 i, uint32 mask, float *v, float *t0, float *t1, uint8 *c, float *n);
|
float32 p[3];
|
||||||
void insertVertexSkin(Geometry *geo, int32 i, uint32 mask, float32 *v, float32 *t0, float32 *t1, uint8 *c, float32 *n,
|
float32 t[2];
|
||||||
float32 *w, uint8 *ix);
|
uint8 c[4];
|
||||||
int32 findVertexSkin(Geometry *g, uint32 flags[], uint32 mask, int32 first,
|
float32 n[3];
|
||||||
float32 *v, float32 *t0, float32 *t1, uint8 *c, float32 *n,
|
};
|
||||||
float32 *w, uint8 *ix);
|
|
||||||
|
void insertVertex(Geometry *geo, int32 i, uint32 mask, Vertex *v);
|
||||||
|
|
||||||
extern ObjPipeline *defaultObjPipe;
|
extern ObjPipeline *defaultObjPipe;
|
||||||
extern MatPipeline *defaultMatPipe;
|
extern MatPipeline *defaultMatPipe;
|
||||||
|
@ -111,10 +112,20 @@ void dumpPipeline(rw::Pipeline *pipe);
|
||||||
|
|
||||||
// Skin plugin
|
// 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 readNativeSkin(Stream *stream, int32, void *object, int32 offset);
|
||||||
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
void writeNativeSkin(Stream *stream, int32 len, void *object, int32 offset);
|
||||||
int32 getSizeNativeSkin(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 skinPreCB(MatPipeline*, Geometry*);
|
||||||
void skinPostCB(MatPipeline*, Geometry*);
|
void skinPostCB(MatPipeline*, Geometry*);
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,10 @@ main(int argc, char *argv[])
|
||||||
rw::version = 0;
|
rw::version = 0;
|
||||||
// rw::version = 0x34003;
|
// rw::version = 0x34003;
|
||||||
// rw::version = 0x33002;
|
// rw::version = 0x33002;
|
||||||
// rw::platform = rw::PLATFORM_PS2;
|
rw::platform = rw::PLATFORM_PS2;
|
||||||
// rw::platform = rw::PLATFORM_OGL;
|
// rw::platform = rw::PLATFORM_OGL;
|
||||||
// rw::platform = rw::PLATFORM_XBOX;
|
// rw::platform = rw::PLATFORM_XBOX;
|
||||||
rw::platform = rw::PLATFORM_D3D8;
|
// rw::platform = rw::PLATFORM_D3D8;
|
||||||
// rw::platform = rw::PLATFORM_D3D9;
|
// rw::platform = rw::PLATFORM_D3D9;
|
||||||
|
|
||||||
int uninstance = 0;
|
int uninstance = 0;
|
||||||
|
@ -86,7 +86,7 @@ main(int argc, char *argv[])
|
||||||
ObjPipeline *p = a->getPipeline();
|
ObjPipeline *p = a->getPipeline();
|
||||||
if(uninstance){
|
if(uninstance){
|
||||||
p->uninstance(a);
|
p->uninstance(a);
|
||||||
ps2::unconvertADC(a->geometry);
|
//ps2::unconvertADC(a->geometry);
|
||||||
}else
|
}else
|
||||||
p->instance(a);
|
p->instance(a);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue