static void MakePatchCapTexture(PatchMesh &pmesh, Matrix3 &itm, int pstart, int pend, BOOL usePhysUVs) { if(pstart == pend) return; // Find out which verts are used by the cap BitArray capVerts(pmesh.numVerts); capVerts.ClearAll(); for(int i = pstart; i < pend; ++i) { Patch &p = pmesh.patches[i]; capVerts.Set(p.v[0]); capVerts.Set(p.v[1]); capVerts.Set(p.v[2]); if(p.type == PATCH_QUAD) capVerts.Set(p.v[3]); } // Minmax the verts involved in X/Y axis and total them Box3 bounds; int numCapVerts = 0; int numCapPatches = pend - pstart; IntTab capIndexes; capIndexes.SetCount(pmesh.numVerts); int baseTVert = pmesh.getNumTVerts(); for(int i = 0; i < pmesh.numVerts; ++i) { if(capVerts[i]) { capIndexes[i] = baseTVert + numCapVerts++; bounds += pmesh.verts[i].p * itm; } } pmesh.setNumTVerts(baseTVert + numCapVerts, TRUE); Point3 s; if (usePhysUVs) s = Point3(1.0f, 1.0f, 0.0f); else s = Point3(1.0f / bounds.Width().x, 1.0f / bounds.Width().y, 0.0f); Point3 t(-bounds.Min().x, -bounds.Min().y, 0.0f); // Do the TVerts for(int i = 0; i < pmesh.numVerts; ++i) { if(capVerts[i]) pmesh.setTVert(baseTVert++, ((pmesh.verts[i].p * itm) + t) * s); } // Do the TVPatches for(int i = pstart; i < pend; ++i) { Patch &p = pmesh.patches[i]; TVPatch &tp = pmesh.getTVPatch(i); if(p.type == PATCH_TRI) tp.setTVerts(capIndexes[p.v[0]], capIndexes[p.v[1]], capIndexes[p.v[2]]); else tp.setTVerts(capIndexes[p.v[0]], capIndexes[p.v[1]], capIndexes[p.v[2]], capIndexes[p.v[3]]); } }
static void MakeMeshCapTexture(Mesh &mesh, Matrix3 &itm, int fstart, int fend, BOOL usePhysUVs) { if(fstart == fend) return; // Find out which verts are used by the cap BitArray capVerts(mesh.numVerts); capVerts.ClearAll(); for(int i = fstart; i < fend; ++i) { Face &f = mesh.faces[i]; capVerts.Set(f.v[0]); capVerts.Set(f.v[1]); capVerts.Set(f.v[2]); } // Minmax the verts involved in X/Y axis and total them Box3 bounds; int numCapVerts = 0; int numCapFaces = fend - fstart; IntTab capIndexes; capIndexes.SetCount(mesh.numVerts); int baseTVert = mesh.getNumTVerts(); for(int i = 0; i < mesh.numVerts; ++i) { if(capVerts[i]) { capIndexes[i] = baseTVert + numCapVerts++; bounds += mesh.verts[i] * itm; } } mesh.setNumTVerts(baseTVert + numCapVerts, TRUE); Point3 s; if (usePhysUVs) s = Point3(1.0f, 1.0f, 0.0f); else s = Point3(1.0f / bounds.Width().x, 1.0f / bounds.Width().y, 0.0f); Point3 t(-bounds.Min().x, -bounds.Min().y, 0.0f); // Do the TVerts for(int i = 0; i < mesh.numVerts; ++i) { if(capVerts[i]) mesh.setTVert(baseTVert++, ((mesh.verts[i] * itm) + t) * s); } // Do the TVFaces for(int i = fstart; i < fend; ++i) { Face &f = mesh.faces[i]; mesh.tvFace[i] = TVFace(capIndexes[f.v[0]], capIndexes[f.v[1]], capIndexes[f.v[2]]); } }
void DeletePatchParts(PatchMesh *patch, RPatchMesh *rpatch, BitArray &delVerts, BitArray &delPatches) { int patches = patch->getNumPatches(); int verts = patch->getNumVerts(); int vecs = patch->getNumVecs(); int dest; // We treat vectors specially in order to clean up after welds. First, we tag 'em all, // then untag only those on unselected patches so that any dangling vectors will be deleted. BitArray delVectors(vecs); delVectors.SetAll(); // Untag vectors that are on nondeleted patches int i; for (i = 0; i < patches; ++i) { if (!delPatches[i]) { Patch& p = patch->patches[i]; int j; for (j = 0; j <(p.type * 2); ++j) { delVectors.Clear(p.vec[j]); } for (j = 0; j < p.type; ++j) delVectors.Clear(p.interior[j]); } } // Make a table of vertices that are still in use -- Used to // delete those vertices which are floating, unused, in space. BitArray usedVerts(verts); usedVerts.ClearAll(); for (i = 0; i < patches; ++i) { if (!delPatches[i]) { Patch& p = patch->patches[i]; for (int j = 0; j < p.type; ++j) { usedVerts.Set(p.v[j]); } } } for (i = 0; i < verts; ++i) { if (!usedVerts[i]) delVerts.Set(i); } // If we have texture vertices, handle them, too for (int chan = 0; chan < patch->getNumMaps(); ++chan) { int tverts = patch->numTVerts[chan]; if (tverts && patch->tvPatches[chan]) { BitArray delTVerts(tverts); delTVerts.SetAll(); for (i = 0; i < patches; ++i) { if (!delPatches[i]) { Patch& p = patch->patches[i]; TVPatch& tp = patch->tvPatches[chan][i]; for (int j = 0; j < p.type; ++j) delTVerts.Clear(tp.tv[j]); } } // Got the list of tverts to delete -- now delete 'em // Build a table of redirected texture vertex indices int newTVerts = tverts - delTVerts.NumberSet(); IntTab tVertIndex; tVertIndex.SetCount(tverts); UVVert *newTVertArray = new UVVert[newTVerts]; dest = 0; for (i = 0; i < tverts; ++i) { if (!delTVerts[i]) { newTVertArray[dest] = patch->tVerts[chan][i]; tVertIndex[i] = dest++; } } delete[] patch->tVerts[chan]; #if MAX_RELEASE <= 3100 patch->tVerts[chan] = newTVertArray; #else *(patch->tVerts[chan]) = *newTVertArray; #endif patch->numTVerts[chan] = newTVerts; // Now, copy the untagged texture patches to a new array // While you're at it, redirect the vertex indices int newTVPatches = patches - delPatches.NumberSet(); TVPatch *newArray = new TVPatch[newTVPatches]; dest = 0; for (i = 0; i < patches; ++i) { if (!delPatches[i]) { Patch& p = patch->patches[i]; TVPatch& tp = newArray[dest++]; tp = patch->tvPatches[chan][i]; for (int j = 0; j < p.type; ++j) tp.tv[j] = tVertIndex[tp.tv[j]]; } } delete[] patch->tvPatches[chan]; patch->tvPatches[chan] = newArray;; } } // Build a table of redirected vector indices IntTab vecIndex; vecIndex.SetCount(vecs); int newVectors = vecs - delVectors.NumberSet(); PatchVec *newVecArray = new PatchVec[newVectors]; dest = 0; for (i = 0; i < vecs; ++i) { if (!delVectors[i]) { newVecArray[dest] = patch->vecs[i]; vecIndex[i] = dest++; } else vecIndex[i] = -1; } delete[] patch->vecs; patch->vecs = newVecArray; patch->numVecs = newVectors; // Build a table of redirected vertex indices int newVerts = verts - delVerts.NumberSet(); IntTab vertIndex; vertIndex.SetCount(verts); PatchVert *newVertArray = new PatchVert[newVerts]; BitArray newVertSel(newVerts); newVertSel.ClearAll(); dest = 0; for (i = 0; i < verts; ++i) { if (!delVerts[i]) { newVertArray[dest] = patch->verts[i]; newVertSel.Set(dest, patch->vertSel[i]); // redirect & adjust attached vector list PatchVert& v = newVertArray[dest]; for (int j = 0; j < v.vectors.Count(); ++j) { v.vectors[j] = vecIndex[v.vectors[j]]; if (v.vectors[j] < 0) { v.vectors.Delete(j, 1); j--; // realign index } } vertIndex[i] = dest++; } } delete[] patch->verts; patch->verts = newVertArray; patch->numVerts = newVerts; patch->vertSel = newVertSel; // Now, copy the untagged patches to a new array // While you're at it, redirect the vertex and vector indices int newPatches = patches - delPatches.NumberSet(); Patch *newArray = new Patch[newPatches]; BitArray newPatchSel(newPatches); newPatchSel.ClearAll(); dest = 0; for (i = 0; i < patches; ++i) { if (!delPatches[i]) { newArray[dest] = patch->patches[i]; Patch& p = newArray[dest]; int j; for (j = 0; j < p.type; ++j) p.v[j] = vertIndex[p.v[j]]; for (j = 0; j <(p.type * 2); ++j) p.vec[j] = vecIndex[p.vec[j]]; for (j = 0; j < p.type; ++j) p.interior[j] = vecIndex[p.interior[j]]; newPatchSel.Set(dest++, patch->patchSel[i]); } } // Rebuild info in rpatch rpatch->DeleteAndSweep (delVerts, delPatches, *patch); delete[] patch->patches; patch->patches = newArray;; patch->numPatches = newPatches; patch->patchSel.SetSize(newPatches, TRUE); patch->patchSel = newPatchSel; patch->buildLinkages(); }