Пример #1
0
 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;
 }
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #5
0
float Geometry::CalcArea()
{
	float s=0;
	for(int i=0;i<tr.size();i++)
	{
		s += TriangleArea(tr[i]);
	}
	return s/2;
}
Пример #6
0
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; 
}
Пример #7
0
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;
}
Пример #8
0
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();
}
Пример #9
0
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();*/
}
Пример #10
0
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;

	 }	//(所有三角形遍历)			
  }
}