void Triangle::Barycentric2(const float3 &P, float3 &bary) const { float abc = GetArea(); bary.x = TriangleArea(P,B,C)/abc; bary.y = TriangleArea(A,P,C)/abc; bary.z = 1.0f -bary.x - bary.y; }
static float TriangleDistance(float v0[2], float v1[2], float v2[2], float p[2]) { float areas[3]; int signs[2]; float e[3][2]; float d[3][2]; MakeEdgePlane(e[0], d[0], v0, v1); MakeEdgePlane(e[1], d[1], v1, v2); MakeEdgePlane(e[2], d[2], v2, v0); // figure out we're in a vertex region { PlaneDistance(e[0], d[0][0]), PlaneDistance( } p[0] = -1; p[1] = 1.5; areas[0] = -TriangleArea(v0, v1, p); areas[1] = -TriangleArea(v1, v2, p); areas[2] = -TriangleArea(v2, v0, p); signs[0] = signs[1] = 0; for(int i = 0; i < 3; i++) { if(areas[i] <= 0.0f) signs[0]++; else signs[1]++; } // if all are negative then inside of triangle if(!signs[0] == 3) { return 0.0f; } // if one is positive then we're closer to an edge if(signs[1] == 1) { // take the max of the distance to all edges printf("edge\n"); return max(EdgeDistance(v0, v1, p), max(EdgeDistance(v1, v2, p), EdgeDistance(v2, v0, p))); } // two are positive then we're closer to a vertex if(signs[1] == 2) { // take the min of the the distance to all vertices printf("vertex\n"); return min(VertexDistance(v0, p), min(VertexDistance(v1, p), VertexDistance(v2, p))); } return 0.0f; }
double PolygonArea( const std::vector< PlyValueVertex< Real > >& vertices , const std::vector< int >& polygon ) { if( polygon.size()<3 ) return 0.; else if( polygon.size()==3 ) return TriangleArea( vertices[polygon[0]].point , vertices[polygon[1]].point , vertices[polygon[2]].point ); else { Point3D< Real > center; for( size_t i=0 ; i<polygon.size() ; i++ ) center += vertices[ polygon[i] ].point; center /= Real( polygon.size() ); double area = 0; for( size_t i=0 ; i<polygon.size() ; i++ ) area += TriangleArea( center , vertices[ polygon[i] ].point , vertices[ polygon[ (i+1)%polygon.size() ] ].point ); return area; } }
float CPhysicsCollision::ConvexSurfaceArea( CPhysConvex *pConvex ) { IVP_Compact_Ledge *pLedge = (IVP_Compact_Ledge *)pConvex; int triangleCount = pLedge->get_n_triangles(); IVP_Compact_Triangle *pTri = pLedge->get_first_triangle(); float area = 0; for ( int j = 0; j < triangleCount; j++ ) { Vector points[3]; for ( int k = 0; k < 3; k++ ) { const IVP_Compact_Edge *pEdge = pTri->get_edge( k ); const IVP_U_Float_Point *pPoint = pEdge->get_start_point( pLedge ); ConvertPositionToHL( *pPoint, points[k] ); } area += TriangleArea( points[0], points[1], points[2] ); pTri = pTri->get_next_tri(); } return area; }
float Geometry::CalcArea() { float s=0; for(int i=0;i<tr.size();i++) { s += TriangleArea(tr[i]); } return s/2; }
float Poly::area() { float s = 0; // Zmienna na pole for(int i=0;i<size-2;i++) // Liczy pole sumuj¹c pola trójk¹tów utworzonych za pomoc¹ kolejnych przek¹tnych i boków { s += TriangleArea( vertices[0] , vertices[i+1] , vertices[i+2] ); } return s; }
Poly::Poly(Vec2 * tab , int n) { body = NULL; size = n; // Pobieram iloœæ wierzcho³ków GlobNorm = new Vec2[n]; // Tworzê tablicê na wierzcho³ki i normalne GlobVert = new Vec2[n]; vertices = new Vec2[n]; for(int i=0;i<n;i++) { vertices[i] = tab[i]; // Kopiujê wierzcho³ki } Vec2 center(0,0); // Zmienna na œrodek ciê¿koœci wielok¹tu Vec2 * centers = new Vec2[n-2]; // Tablica œrodków poszczególnych trójk¹tów (triangulizacja wielok¹tu ) float area = 0.0f; // Pole figury float * areas = new float[n-2]; // Pola trójk¹tó ( triangulizacja ) // Triangulizacja for (int i=2; i < size ; i++) { centers[i - 2] = Vec2( (vertices[0].x+vertices[i-1].x+vertices[i].x)/3 , (vertices[0].y+vertices[i-1].y+vertices[i].y)/3 ); // Œriednia kolejnych wierzcho³ków areas[i-2] = TriangleArea(vertices[0] , vertices[i] , vertices[i-1] ); // Pole trójk¹ta area += areas[i-2] ; } for (int i=0; i < n-2 ; i++) center = center + centers[i]*areas[i]; // Sumujemy œrodki trójk¹tów pomno¿one przez ich pole center = center / area; // Dzielimy przez ³¹czne pole delete[] areas; delete[] centers; // Przesuwamy k¹zdy wierzcho³ek tak ¿eby œrodek ciê¿koœci by³ punktem (0,0) for (int i=0; i<size; i++) vertices[i] = vertices[i] - center; // Szukam promienia okrêgu opisuj¹cego radius = 0; float r; for(int i=0;i<size;i++) // Szukam minimalnego promienia okrêgu okalaj¹cego wielok¹t { r = vertices[i].x * vertices[i].x + vertices[i].y * vertices[i].y; // Liczê kwadraty odleg³oœci wierzcho³ków od œrodka if( r > radius) // Porównuje je radius = r; // Przepisuje wiêksz¹ wartoœæ } radius = sqrt(radius); // Na sam koniec pierwiastkuje minimaln¹ wartoœæ global = false; type = polygon; child = false; orient = NULL; }
void EssExporter::AddMesh(const EH_Mesh& model, const std::string &modelName) { mWriter.BeginNode("poly", modelName.c_str()); mWriter.AddPointArray("pos_list", (eiVector*)model.verts, model.num_verts); std::vector<uint_t> filter_vert_index; std::vector<uint_t> filter_mtl_index; std::vector<uint_t> filter_n_index; std::vector<uint_t> filter_uv_index; filter_vert_index.reserve(model.num_faces * 3); filter_n_index.reserve(model.num_faces * 3); filter_uv_index.reserve(model.num_faces * 3); if (model.mtl_indices) { filter_mtl_index.reserve(model.num_faces); } for (int i = 0; i < model.num_faces; ++i) { uint_t *p_index = (uint_t*)model.face_indices + (i * 3); uint_t *n_index = (uint_t*)model.n_indices + (i * 3); uint_t *uv_index = (uint_t*)model.uv_indices + (i * 3); uint_t index0 = (*p_index); uint_t index1 = (*(p_index + 1)); uint_t index2 = (*(p_index + 2)); eiVector *p0 = (eiVector*)model.verts + index0; eiVector *p1 = (eiVector*)model.verts + index1; eiVector *p2 = (eiVector*)model.verts + index2; if (TriangleArea(*p0, *p1, *p2) > ER_TRIANGLE_AREA_EPS) { filter_vert_index.push_back(index0); filter_vert_index.push_back(index1); filter_vert_index.push_back(index2); if (model.n_indices != NULL) { filter_n_index.push_back(*n_index); filter_n_index.push_back(*(n_index + 1)); filter_n_index.push_back(*(n_index + 2)); } if (model.uv_indices != NULL) { filter_uv_index.push_back(*uv_index); filter_uv_index.push_back(*(uv_index + 1)); filter_uv_index.push_back(*(uv_index + 2)); } if (model.mtl_indices) { filter_mtl_index.push_back(*(model.mtl_indices + i)); } } } mWriter.AddIndexArray("triangle_list", &filter_vert_index[0], filter_vert_index.size(), false); if (model.normals) { if (model.n_indices == NULL) { mWriter.AddDeclare("vector[]", "N", "varying"); mWriter.AddPointArray("N", (eiVector*)model.normals, model.num_verts); } else { mWriter.AddDeclare("vector[]", "N", "facevarying"); mWriter.AddPointArray("N", (eiVector*)model.normals, model.num_verts); mWriter.AddDeclare("index[]", "N_idx", "facevarying"); mWriter.AddIndexArray("N_idx", &filter_n_index[0], filter_n_index.size(), false); } } if(model.uvs) { if (model.uv_indices == NULL) { mWriter.AddDeclare("vector2[]", "uv0", "varying"); mWriter.AddVector2Array("uv0", (eiVector2*)model.uvs, model.num_verts); } else { mWriter.AddDeclare("vector2[]", "uv0", "facevarying"); mWriter.AddVector2Array("uv0", (eiVector2*)model.uvs, model.num_verts); mWriter.AddDeclare("index[]", "uv0_idx", "facevarying"); mWriter.AddIndexArray("uv0_idx", &filter_uv_index[0], filter_uv_index.size(), false); } } if (model.mtl_indices) { mWriter.AddDeclare("index[]", "mtl_index", "uniform"); mWriter.AddIndexArray("mtl_index", &filter_mtl_index[0], filter_mtl_index.size(), false); } mWriter.EndNode(); }
void ConstrainedFire::Init(ObjReader * obj) { FireVertex vertex; FireTriangle triangle; int end; //存储模型顶点 end = (int)obj->Positions.size(); for(int i=0;i<end;i++) { vertex.position = obj->Positions[i]*2.6; m_Vertices.push_back(vertex); } //存储模型面信息 end = (int) obj->m_Object[0]->posIndices.size(); for(int i=0;i<end;) { triangle.index[0] = obj->m_Object[0]->posIndices[i++]; triangle.index[1] = obj->m_Object[0]->posIndices[i++]; triangle.index[2] = obj->m_Object[0]->posIndices[i++]; triangle.area = TriangleArea(triangle.index[0],triangle.index[1],triangle.index[2]); m_Faces.push_back(triangle); } Normalize();//归一化顶点数据 Subdivide();//细分模型 objectImported =true; objVertexNum = (int)m_Vertices.size(); numParticlesSecondExp=m_Vertices.size()*1.8; KMeans(m_K);//聚类操作 GenerateQuadrantByKMean();//生成发射区域 //8个二次爆炸的粒子发生器的位置限制,注意顺序要与对象顶点分区编号对应 /*Point3f expP; expP=modelCenter(m_Quadrant0); expEmitter[0].pos.X()=expP.X(); expEmitter[0].pos.Y()=expP.Y(); expEmitter[0].pos.Z()=expP.Z(); expP=modelCenter(m_Quadrant1); expEmitter[1].pos.X()=expP.X(); expEmitter[1].pos.Y()=expP.Y(); expEmitter[1].pos.Z()=expP.Z(); expP=modelCenter(m_Quadrant2); expEmitter[2].pos.X()=expP.X(); expEmitter[2].pos.Y()=expP.Y(); expEmitter[2].pos.Z()=expP.Z(); expP=modelCenter(m_Quadrant3); expEmitter[3].pos.X()=expP.X(); expEmitter[3].pos.Y()=expP.Y(); expEmitter[3].pos.Z()=expP.Z(); expP=modelCenter(m_Quadrant4); expEmitter[4].pos.X()=expP.X(); expEmitter[4].pos.Y()=expP.Y(); expEmitter[4].pos.Z()=expP.Z(); expP=modelCenter(m_Quadrant5); expEmitter[5].pos.X()=expP.X(); expEmitter[5].pos.Y()=expP.Y(); expEmitter[5].pos.Z()=expP.Z(); expP=modelCenter(m_Quadrant6); expEmitter[6].pos.X()=expP.X(); expEmitter[6].pos.Y()=expP.Y(); expEmitter[6].pos.Z()=expP.Z(); expP=modelCenter(m_Quadrant7); expEmitter[7].pos.X()=expP.X(); expEmitter[7].pos.Y()=expP.Y(); expEmitter[7].pos.Z()=expP.Z();*/ }
void ConstrainedFire::Subdivide() { int j,i; int oldMaxVertex,oldMaxTriangle; FireVertex vertex; FireTriangle triangle; bool pInV1,pInV2,pInV3; //标记点是否已在模型的顶点数组中 int index1,index2,index3; //新增加的顶点索引值 Point3f tp1,tp2,tp3; while(m_Vertices.size()<m_VertexThreshhold) { //计算三角形面积的平均值 float aveArea=0.0; oldMaxVertex = (int)m_Vertices.size(); //细分之前的模型顶点数,用于顶点搜索的开始位置 oldMaxTriangle = (int)m_Faces.size(); //添加新三角形之前的三角形个数,对新增加的三角形不用细分 for (i=0;i<oldMaxTriangle;i++) aveArea += m_Faces[i].area; aveArea /= (float)oldMaxTriangle; for (i=0;i<oldMaxTriangle;i++) //对新增加的三角形不进行判断和细化 { //对面积大于平均值的三角形,将各边中点相连 if(m_Faces[i].area < aveArea) continue; //计算各边中点 tp1=pointMid(m_Faces[i].index[0],m_Faces[i].index[1]); tp2=pointMid(m_Faces[i].index[1],m_Faces[i].index[2]); tp3=pointMid(m_Faces[i].index[2],m_Faces[i].index[0]); //判断各中点是否已在顶点数组中。若没有,则将中点添加到顶点数组末 //由于(仅)可能会在相邻三角形的细化过程中已被添加,所以只需从oldMaxVertex开始搜索 pInV1=false; //初始状态为不在数组中 pInV2=false; pInV3=false; //对第1个点tp1 for (j=oldMaxVertex;j<(int)m_Vertices.size();j++) { if(tp1==m_Vertices[j].position) { pInV1=true; index1=j; break; } } if(!pInV1) { //tp1不在数组中,添加到数组末尾 vertex.position = tp1; m_Vertices.push_back(vertex); index1 = (int)m_Vertices.size()-1; } //对第2个点tp2 for(j=oldMaxVertex;j<(int)m_Vertices.size();j++) { if(tp2 == m_Vertices[j].position) { pInV2=true; index2=j; break; } } if (!pInV2) { //tp2不在数组中,添加 vertex.position =tp2; m_Vertices.push_back(vertex); index2 = (int)m_Vertices.size()-1; } //对第3个点tp3 for(j=oldMaxVertex;j<(int)m_Vertices.size();j++) { if (tp3 == m_Vertices[j].position) { pInV3=true; index3=j; break; } } if (!pInV3) { //tp3不在数组中,添加 vertex.position = tp3; m_Vertices.push_back(vertex); index3 = (int)m_Vertices.size()-1; } //修改当前三角形objTriangle[i]的顶点值,并在三角形数组末添加三个三角形 //添加三角形index1,objTriangle[i].v2,index2 triangle.index[0] = index1; triangle.index[1] = m_Faces[i].index[1]; triangle.index[2] = index2; triangle.area=TriangleArea(triangle.index[0],triangle.index[1],triangle.index[2]); m_Faces.push_back(triangle); //添加三角形index2,objTriangle[i].v3,index3 triangle.index[0]=index2; triangle.index[1]=m_Faces[i].index[2]; triangle.index[2]=index3; triangle.area=TriangleArea(triangle.index[0],triangle.index[1],triangle.index[2]); m_Faces.push_back(triangle); //添加三角形index1,index2,index3 triangle.index[0]=index1; triangle.index[1]=index2; triangle.index[2]=index3; triangle.area=TriangleArea(triangle.index[0],triangle.index[1],triangle.index[2]); m_Faces.push_back(triangle); //修改当前三角形objTriangle[i]的顶点值为objTriangle[i].v1,index1,index3 triangle.index[0]=m_Faces[i].index[0]; triangle.index[1]=index1; triangle.index[2]=index3; triangle.area=TriangleArea(triangle.index[0],triangle.index[1],triangle.index[2]); m_Faces[i].index[0]=triangle.index[0]; m_Faces[i].index[1]=triangle.index[1]; m_Faces[i].index[2]=triangle.index[2]; m_Faces[i].area=triangle.area; } //(所有三角形遍历) } }