vec3_t *G2Exporter_Surface_GetVertNormal(int iSurfaceIndex, int iVertIndex, int iLODIndex) { static vec3_t v3={0}; memset(v3,0,sizeof(v3)); if (iLODIndex == giNumLODs-1) { // q3data surface... // if (iSurfaceIndex < giNumSurfaces) { // standard surface... // md3SurfaceData_t *pSurfaceData = GetMD3SurfaceData(iSurfaceIndex); if (pSurfaceData) { // this logic is kinda gay, not sure why the *6 etc, but that's how other q3data code works, so... // float **ppVerts = pSurfaceData->verts; memcpy(v3,(vec3_t*) &ppVerts[0][iVertIndex*6+3], sizeof(v3)); { Matrix4 Swap; Swap.Identity(); if (1) { Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f)); Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f)); } Swap.CalcFlags(); Vect3 v3In((const float *)v3); static Vect3 v3Out; Swap.XFormVect(v3Out,v3In); return (vec3_t*) &v3Out; } } } else { // tag surface... // // I don't think tag-surfaces normals have any meaning for ghoul2, so... // return &v3; } } else { // imported surface... // vec3_t &v3Src = ImportedModel.ImportedLODs[iLODIndex].ImportedSurfaces[ImportedModel.SurfaceIndexRemaps[iSurfaceIndex]].ImportedVerts[iVertIndex].normal; memcpy(v3,v3Src,sizeof(v3)); return &v3; } assert(0); return &v3; }
int FindPKeys(TxtNode *t) { if (t->child) { TxtNode *sib=t->child; if (!sib) return 200; char framename[100]; { if (!sib->child) return 201; if (!sib->child->text) return 202; if (!strncmp("frm-",sib->child->text,4)) mystrncpy(framename,sib->child->text+4,sib->child->length-4); else { if (!strncmp("SCENE",sib->child->text,4)) return 0; mystrncpy(framename,sib->child->text,sib->child->length); } sib=sib->sibling; } int foundkeys=0; maxmatframe=0; while (sib) { if (sib->text&&!mystrncmp("SI_AnimationKey",sib->text,sib->length)) { if (!sib->sibling) return 103; sib=sib->sibling; int err=ProcNKeys(sib,foundkeys); if (err) return err; } sib=sib->sibling; } { if (maxmatframe>maxframe) maxframe=maxmatframe; int i; for (i=0;i<nsNodes;i++) { if (!strcmp(sNodes[i].name,framename)) { int j; if (sNodes[i].nanimat<maxmatframe+1) { delete[] sNodes[i].animat; sNodes[i].nanimat=maxmatframe+1; sNodes[i].animat=new Matrix4[maxmatframe+1]; for (j=0;j<=maxmatframe;j++) sNodes[i].animat[j].Identity(); } for (j=0;j<=maxmatframe;j++) { Matrix4 xf; xf=sNodes[i].mat; Vect3 tt,t2; if (foundkeys&1) { mats[j].GetRow(3,tt); xf.SetRow(3,tt); } if (foundkeys&2) { float l; xf.GetRow(0,t2); l=t2.Len(); mats[j].GetRow(0,tt); tt*=l; xf.SetRow(0,tt); xf.GetRow(1,t2); l=t2.Len(); mats[j].GetRow(1,tt); tt*=l; xf.SetRow(1,tt); xf.GetRow(2,t2); l=t2.Len(); mats[j].GetRow(2,tt); tt*=l; xf.SetRow(2,tt); } if (foundkeys&4) { xf.GetRow(0,tt); tt.Norm(); tt*=scales[j].x(); xf.SetRow(0,tt); xf.GetRow(1,tt); tt.Norm(); tt*=scales[j].x(); xf.SetRow(1,tt); xf.GetRow(2,tt); tt.Norm(); tt*=scales[j].x(); xf.SetRow(2,tt); } xf.CalcFlags(); Matrix4 par,tmat; if (sNodes[i].parent) { if (j<sNodes[i].parent->nanimat) par=sNodes[i].parent->animat[j]; else par=sNodes[i].parent->BaseMat; tmat.Concat(xf,par); } else tmat=xf; sNodes[i].animat[j]=tmat; #if 0 par.Inverse(sNodes[i].BaseMat); tmat.Concat(par,sNodes[i].animat[j]); char tmp[1000]; int r; sprintf(tmp,"final frame %d %s\n",j,sNodes[i].name); OutputDebugString(tmp); for (r=0;r<4;r++) { sprintf(tmp,"%6f %6f %6f\n",tmat[r][0],tmat[r][1],tmat[r][2]); OutputDebugString(tmp); } sprintf(tmp,"baseinv frame %d %s\n",j,sNodes[i].name); OutputDebugString(tmp); for (r=0;r<4;r++) { sprintf(tmp,"%6f %6f %6f\n",par[r][0],par[r][1],par[r][2]); OutputDebugString(tmp); } sprintf(tmp,"bone frame %d %s\n",j,sNodes[i].name); OutputDebugString(tmp); for (r=0;r<4;r++) { sprintf(tmp,"%6f %6f %6f\n",sNodes[i].animat[j][r][0],sNodes[i].animat[j][r][1],sNodes[i].animat[j][r][2]); OutputDebugString(tmp); } #endif } } } } } return 0; }
vec3_t *G2Exporter_Surface_GetVertCoords(int iSurfaceIndex, int iVertIndex, int iLODIndex) { static vec3_t v3={0}; memset(&v3,0,sizeof(v3)); if (iLODIndex == giNumLODs-1) { // q3data surface... // if (iSurfaceIndex < giNumSurfaces) { // standard surface... // md3SurfaceData_t *pSurfaceData = GetMD3SurfaceData(iSurfaceIndex); if (pSurfaceData) { // this logic is kinda gay, not sure why the *6 etc, but that's how other q3data code works, so... // float **ppVerts = pSurfaceData->verts; static vec3_t v3; for (int i=0; i<3; i++) { v3[i] = ppVerts[0][iVertIndex*6+i];// /MD3_XYZ_SCALE; } // return &v3; Matrix4 Swap; Swap.Identity(); if (1) { Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f)); Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f)); } Swap.CalcFlags(); Vect3 v3In((const float *)v3); static Vect3 v3Out; Swap.XFormVect(v3Out,v3In); return (vec3_t*) &v3Out; } } else { // tag surface... // assert(iVertIndex<3); md3Tag_t *pTag = &g_data.tags[0][iSurfaceIndex - giNumSurfaces]; vec3_t v3New; //#ifdef PERFECT_CONVERSION v3New[0] = pTag->axis[0][iVertIndex] ; v3New[1] = pTag->axis[1][iVertIndex] ; v3New[2] = pTag->axis[2][iVertIndex] ; // don't worry about how this crap works, it just does (arrived at by empirical methods... :-) // // (mega-thanks to Gil as usual) // if (iVertIndex==2) { VectorCopy(pTag->origin,v3); } else if (iVertIndex==1) { v3New[0] = 2.0f * pTag->axis[1][iG2_TRISIDE_MIDDLE]; v3New[1] = -(2.0f * pTag->axis[0][iG2_TRISIDE_MIDDLE]); v3New[2] = 2.0f * pTag->axis[2][iG2_TRISIDE_MIDDLE]; VectorSubtract(pTag->origin,v3New,v3); } else { v3New[0] = pTag->axis[1][iG2_TRISIDE_LONGEST]; v3New[1] = -pTag->axis[0][iG2_TRISIDE_LONGEST]; v3New[2] = pTag->axis[2][iG2_TRISIDE_LONGEST]; VectorSubtract(pTag->origin,v3New,v3); } // return (vec3_t*) &v3; Matrix4 Swap; Swap.Identity(); if (1) { Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f)); Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f)); } Swap.CalcFlags(); Vect3 v3In((const float *)v3); static Vect3 v3Out; Swap.XFormVect(v3Out,v3In); return (vec3_t*) &v3Out; } } else { // imported surface... // vec3_t &v3Src = ImportedModel.ImportedLODs[iLODIndex].ImportedSurfaces[ImportedModel.SurfaceIndexRemaps[iSurfaceIndex]].ImportedVerts[iVertIndex].vertCoords; memcpy(v3,v3Src,sizeof(v3)); return &v3; } assert(0); return &v3; }