int G2_AddSurface(CGhoul2Info *ghoul2, int surfaceNumber, int polyNumber, float BarycentricI, float BarycentricJ, int lod ) { lod = G2_DecideTraceLod(*ghoul2, lod); // first up, see if we have a free one already set up - look only from the end of the constant surfaces onwards unsigned int i; for (i=0; i<ghoul2->mSlist.size(); i++) { // is the surface count -1? That would indicate it's free if (ghoul2->mSlist[i].surface == -1) { break; } } if (i==ghoul2->mSlist.size()) { ghoul2->mSlist.push_back(surfaceInfo_t()); } ghoul2->mSlist[i].offFlags = G2SURFACEFLAG_GENERATED; ghoul2->mSlist[i].surface = 10000; // no model will ever have 10000 surfaces ghoul2->mSlist[i].genBarycentricI = BarycentricI; ghoul2->mSlist[i].genBarycentricJ = BarycentricJ; ghoul2->mSlist[i].genPolySurfaceIndex = ((polyNumber & 0xffff) << 16) | (surfaceNumber & 0xffff); ghoul2->mSlist[i].genLod = lod; return i; }
void G2_TraceModels(CGhoul2Info_v &ghoul2, vec3_t rayStart, vec3_t rayEnd, CCollisionRecord *collRecMap, int entNum, EG2_Collision eG2TraceType, int useLod, float fRadius) { int i, lod; skin_t *skin; shader_t *cust_shader; // walk each possible model for this entity and try tracing against it for (i=0; i<ghoul2.size(); i++) { // don't bother with models that we don't care about. if (!ghoul2[i].mValid) { continue; } assert(G2_MODEL_OK(&ghoul2[i])); // do we really want to collide with this object? if (ghoul2[i].mFlags & GHOUL2_NOCOLLIDE) { continue; } if (ghoul2[i].mCustomShader) { cust_shader = R_GetShaderByHandle(ghoul2[i].mCustomShader ); } else { cust_shader = NULL; } // figure out the custom skin thing if ( ghoul2[i].mSkin > 0 && ghoul2[i].mSkin < tr.numSkins ) { skin = R_GetSkinByHandle( ghoul2[i].mSkin ); } else { skin = NULL; } lod = G2_DecideTraceLod(ghoul2[i],useLod); //reset the quick surface override lookup G2_FindOverrideSurface(-1, ghoul2[i].mSlist); CTraceSurface TS(ghoul2[i].mSurfaceRoot, ghoul2[i].mSlist, ghoul2[i].currentModel, lod, rayStart, rayEnd, collRecMap, entNum, i, skin, cust_shader, ghoul2[i].mTransformedVertsArray, eG2TraceType, fRadius); // start the surface recursion loop G2_TraceSurfaces(TS); // if we've hit one surface on one model, don't bother doing the rest if (TS.hitOne) { break; } } }
// main calling point for the model transform for collision detection. At this point all of the skeleton has been transformed. void G2_TransformModel(CGhoul2Info_v &ghoul2, const int frameNum, vec3_t scale, CMiniHeap *G2VertSpace, int useLod) { int i, lod; vec3_t correctScale; VectorCopy(scale, correctScale); // check for scales of 0 - that's the default I believe if (!scale[0]) { correctScale[0] = 1.0; } if (!scale[1]) { correctScale[1] = 1.0; } if (!scale[2]) { correctScale[2] = 1.0; } // walk each possible model for this entity and try rendering it out for (i=0; i<ghoul2.size(); i++) { CGhoul2Info &g=ghoul2[i]; // don't bother with models that we don't care about. if (!g.mValid) { continue; } assert(g.mBoneCache); assert(G2_MODEL_OK(&g)); // stop us building this model more than once per frame g.mMeshFrameNum = frameNum; // decide the LOD lod = G2_DecideTraceLod(g, useLod); // give us space for the transformed vertex array to be put in ghoul2[i].mTransformedVertsArray = (int*)G2VertSpace->MiniHeapAlloc(g.currentModel->mdxm->numSurfaces * 4); if (!g.mTransformedVertsArray) { Com_Error(ERR_DROP, "Ran out of transform space for Ghoul2 Models. Adjust MiniHeapSize in SV_SpawnServer.\n"); } memset(g.mTransformedVertsArray, 0,(g.currentModel->mdxm->numSurfaces * 4)); G2_FindOverrideSurface(-1,g.mSlist); //reset the quick surface override lookup; // recursively call the model surface transform G2_TransformSurfaces(g.mSurfaceRoot, g.mSlist, g.mBoneCache, g.currentModel, lod, correctScale, G2VertSpace, g.mTransformedVertsArray, false); } }