int MatchPolygon (MdlObject *root, vector<Vector3>& pverts, int& startVertex) { for (int a=0;a<root->poly.size();a++) { Poly *pl = root->poly[a]; if (pl->verts.size() != pverts.size()) continue; // An early out plane comparision, will also make sure that "double-sided" polgyon pairs // are handled correctly Plane plane = pl->CalcPlane (root->verts); Plane tplane; tplane.MakePlane (pverts[0],pverts[1],pverts[2]); if (!plane.EpsilonCompare(tplane, EPSILON)) continue; // in case the polygon vertices have been reordered, // this takes care of finding "the first" vertex again int startv = 0; for (;startv < pverts.size();startv++) { if ((root->verts[pl->verts [0]].pos-pverts[startv]).length () < EPSILON) break; } // no start vertex has been found if (startv == pverts.size()) continue; // compare the polygon vertices with eachother... int v = 0; for (;v<pverts.size();v++) { if ((root->verts[pl->verts[v]].pos - pverts[(v+startv)%pverts.size()]).length () >= EPSILON) break; } if (v==pverts.size()) { startVertex=startv; return a; } } return -1; }
void Object::GenerateFromPolyMesh(PolyMesh *o) { std::vector<int> old2new; std::vector<Vector3> vertPos; GenerateUniqueVectors(o->verts, vertPos, old2new); vertices.resize(o->verts.size()); copy(o->verts.begin(),o->verts.end(),vertices.begin()); std::map<Poly*, Face*> poly2face; // maps edge to first vertex index std::map<int, std::vector<Edge*> > edgeMap; // simple definition: intersecting edges are edges with the same vertex pair // use o->poly, because the edges from non-curved polygons are needed as well for (uint a=0;a<o->poly.size();a++) { Poly* pl = o->poly[a]; Face *f = new Face; poly2face[pl] = f; faces.push_back(f); f->plane = pl->CalcPlane(o->verts); for (uint e=0;e<pl->verts.size();e++) { Edge* edge = new Edge; edge->meshVerts[0] = pl->verts[e]; edge->meshVerts[1] = pl->verts[(e+1)%pl->verts.size()]; for(int x=0;x<2;x++) edge->pos [x] = old2new[edge->meshVerts[x]]; edge->face = f; edge->dir = o->verts[edge->meshVerts[1]].pos - o->verts[edge->meshVerts[0]].pos; edges.push_back(edge); f->edges.push_back(edge); edgeMap[edge->pos[0]].push_back (edge); } } for (uint a=0;a<edges.size();a++) { Edge *edge = edges[a]; // parallel edge with same direction std::vector<Edge*>& v = edgeMap[edge->pos[0]]; for (uint b=0;b<v.size();b++) { if (v[b] != edge && v[b]->pos[1] == edge->pos[1]) { d_trace("Matching parallel edge (%d, %d) with (%d, %d)\n", v[b]->pos[0], v[b]->pos[1], edge->pos[0], edge->pos[1]); edge->intersecting.push_back(v[b]); } } // opposite direction std::vector<Edge*>& w = edgeMap[edge->pos[1]]; for (uint b=0;b<w.size();b++) { if (w[b]->pos[1] == edge->pos[0] && w[b] != edge) { d_trace("Matching opposite edge (%d, %d) with (%d, %d)\n", w[b]->pos[0], w[b]->pos[1], edge->pos[0], edge->pos[1]); edge->intersecting.push_back(w[b]); } } } edgeMap.clear(); // calculate edge normals for (uint a=0;a<edges.size();a++) { Edge* e = edges[a]; e->normal = e->face->plane.GetVector(); for (uint b=0;b<e->intersecting.size();b++) e->normal += e->intersecting[b]->face->plane.GetVector(); e->normal.normalize(); } std::vector<Vector3> tmpvrt; const int steps=10; int numCurvedPoly = 0; for (std::map<Poly*,Face*>::iterator pit=poly2face.begin();pit!=poly2face.end();++pit) if (pit->first->verts.size() == 4) numCurvedPoly ++; indexBuffer.Init(sizeof(uint) * 3 * 2 * (steps-1) * (steps-1) * numCurvedPoly); vertexBuffer.Init(sizeof(Vector3) * steps * steps * numCurvedPoly); uint *indexData = (uint*)indexBuffer.LockData(); Vector3* vertexData = (Vector3*)vertexBuffer.LockData(); Vector3* curPos = vertexData; uint* curIndex = indexData; uint vertexOffset = 0; for (std::map<Poly*,Face*>::iterator pit=poly2face.begin();pit!=poly2face.end();++pit) { Poly* pl = pit->first; Face* face = pit->second; if (pl->verts.size() == 4) { const float step = 1.0f / (float)(steps-1); //Edge* Xedge = face->edges[0]; //Edge* Yedges[2] = { face->edges[1], face->edges[3] }; // const Vector3& start = vertices[face->edges[0]->meshVerts[0]].pos; const Vector3& leftEdge = face->edges[3]->dir; const Vector3& rightEdge = face->edges[1]->dir; for (int yp=0;yp<steps;yp++) { float y = yp * step; Vector3 rowStart = vertices[face->edges[0]->meshVerts[0]].pos - leftEdge * y; Vector3 rowEnd = vertices[face->edges[0]->meshVerts[1]].pos + rightEdge * y; Vector3 row = rowEnd-rowStart; for (int xp=0;xp<steps;xp++) { float x = xp * step; *(curPos++) = rowStart + row * x + face->plane.GetVector() * 0.2f; } } for (int y=1;y<steps;y++) for (int x=1;x<steps;x++) { *(curIndex++) = vertexOffset + (y-1)*steps + (x-1); *(curIndex++) = vertexOffset + (y-1)*steps + x; *(curIndex++) = vertexOffset + y*steps + x; *(curIndex++) = vertexOffset + (y-1)*steps + (x-1); *(curIndex++) = vertexOffset + y*steps + x; *(curIndex++) = vertexOffset + y*steps + (x-1); } vertexOffset += steps * steps; } } d_trace("Numtris: %d, NumVerts: %d, VertexOffset=%d\n", curIndex - indexData, curPos - vertexData, vertexOffset); indexBuffer.UnlockData (); vertexBuffer.UnlockData (); }