float Poly::Selector::Score(Vector3 &pos, float /*camdis*/) { assert (mesh); const vector<Vertex>& v=mesh->verts; Plane plane; Vector3 vrt[3]; for (int a=0;a<3;a++) transform.apply(&v[poly->verts[a]].pos, &vrt[a]); plane.MakePlane (vrt[0],vrt[1],vrt[2]); float dis = plane.Dis (&pos); return fabs (dis); }
// In short, the reason for the complexity of this function is: // - creates a list of vertices where every vertex has a unique position (UV ignored) // - doesn't allow the same poly normal to be added to the same vertex twice void PolyMesh::CalculateNormals() { vector<Vector3> vertPos; vector<int> old2new; GenerateUniqueVectors(verts, vertPos, old2new); vector<vector<int> > new2old; new2old.resize(vertPos.size()); for (unsigned int a=0;a<old2new.size();a++) new2old[old2new[a]].push_back(a); vector<std::vector<Vector3> > normals; normals.resize(vertPos.size()); for (unsigned int a=0;a<poly.size();a++) { Poly *pl = poly[a]; Plane plane; plane.MakePlane( vertPos[old2new[pl->verts[0]]], vertPos[old2new[pl->verts[1]]], vertPos[old2new[pl->verts[2]]]); Vector3 plnorm = plane.GetVector(); for (unsigned int b=0;b<pl->verts.size();b++) { vector<Vector3>& norms = normals[old2new[pl->verts[b]]]; unsigned int c; for (c=0;c<norms.size();c++) if (norms[c] == plnorm) break; if (c == norms.size()) norms.push_back(plnorm); } } for (unsigned int a=0;a<normals.size();a++) { Vector3 sum; vector<Vector3>& vn = normals[a]; for(unsigned int b=0;b<vn.size();b++) sum+=vn[b]; if (sum.length()>0.0f) sum.normalize (); vector<int>& vlist=new2old[a]; for(unsigned int b=0;b<vlist.size();b++) verts[vlist[b]].normal = sum; } }
float Poly::Selector::Score(Vector3 &pos, float camdis) { assert (object); const vector<Vertex>& v=object->verts; Plane plane; Vector3 vrt[3]; Matrix transform; object->GetFullTransform(transform); for (int a=0;a<3;a++) transform.apply(&v[poly->verts[a]].pos, &vrt[a]); plane.MakePlane (vrt[0],vrt[1],vrt[2]); float dis = plane.Dis (&pos); return fabs (dis); }
void MdlObject::CalculateNormals() { vector<Vector3> normals; normals.resize(verts.size()); for (int a=0;a<poly.size();a++) { Poly *pl = poly[a]; Plane plane; plane.MakePlane(verts[pl->verts [0]].pos,verts[pl->verts[1]].pos,verts[pl->verts[2]].pos); for (int b=0;b<pl->verts.size();b++) normals[pl->verts[b]] += plane.GetVector (); } for (int a=0;a<verts.size();a++) { if (normals[a].length()>0.0f) normals[a].normalize (); verts[a].normal=normals[a]; } }
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; }
Plane Poly::CalcPlane (const vector<Vertex>& vrt) { Plane plane; plane.MakePlane (vrt[verts[0]].pos,vrt[verts[1]].pos,vrt[verts[2]].pos); return plane; }