Exemplo n.º 1
0
float DistanceToQuad(const vec3& p, const vec3& v1, const vec3& v2, const vec3& v3, const vec3& v4, const vec3& n)
{
	float flPlaneDistance = DistanceToPlane(p, v1, n);

	if (PointInTriangle(p, v1, v2, v3))
		return flPlaneDistance;

	if (PointInTriangle(p, v1, v3, v4))
		return flPlaneDistance;

	float flClosestPointSqr = (v1 - p).LengthSqr();

	float flV2Sqr = (v2 - p).LengthSqr();
	float flV3Sqr = (v3 - p).LengthSqr();
	float flV4Sqr = (v4 - p).LengthSqr();

	flClosestPointSqr = smaller(flClosestPointSqr, smaller(flV2Sqr, smaller(flV3Sqr, flV4Sqr)));

	float flClosestPoint = sqrt(flClosestPointSqr);

	float flV12 = DistanceToLineSegment(p, v1, v2);
	float flV23 = DistanceToLineSegment(p, v2, v3);
	float flV34 = DistanceToLineSegment(p, v3, v4);
	float flV41 = DistanceToLineSegment(p, v4, v1);

	flClosestPoint = smaller(flClosestPoint, smaller(flV12, smaller(flV23, smaller(flV34, flV41))));

	return flClosestPoint;
}
Exemplo n.º 2
0
int Quake3BSP_GL::FindLeafIntersection(int nodeIndex, const Vector &vPos)
{
	float distance = 0.0f;
	int currentIndex = 0;

	// This function is similar to the FindLeaf function with one major difference.  This function
	// searches through the BSP tree and looks for the face that has intersected with a ray cast from a 
	// camera, not just the leaf the camera is in.  So first it sorts for a leaf the camera is in, then
	// does point in triangle test for intersection, if no intersection, the search continues.  If an
	// intersection did occur, we pass the triangle vertices to the renderer to render that triangle
	// differently to display the intersection
	
	if(nodeIndex < 0 ){
		return nodeIndex;
	} else {
		// Still have not found the leaf, keep looking.  First we get the node, and it's splitter plane.
		// From there, we check the distance from the camera position to the splitter plane.  So,
		// if it is positive, we are on the front of the plane, negative, back of the plane.
		
		const BSPNode&  node = m_pNodes[nodeIndex];
		const BSPPlane& plane = m_pPlanes[node.plane];

		// Plane equation to check distance.
		distance =	plane.vNormal.x * vPos.x + 
					plane.vNormal.y * vPos.y + 
					plane.vNormal.z * vPos.z - plane.d;

		// Camera in front of the plane
        if(distance >= 0){
			// We treat sitting on the plane as being in front.
			currentIndex = FindLeafIntersection(node.front, vPos);
			if(currentIndex < 0){
				m_foundLeaf = PointInTriangle(~currentIndex, vPos, plane.vNormal, plane.d);
			}
			if(!m_foundLeaf){
				currentIndex = FindLeafIntersection(node.back, vPos);
				if(currentIndex < 0){
					m_foundLeaf = PointInTriangle(~currentIndex, vPos, plane.vNormal, plane.d);
				}
			}
        } else {
			// Behind the plane
			if(!m_foundLeaf){
        		currentIndex = FindLeafIntersection(node.back, vPos);
				if(currentIndex < 0){
					m_foundLeaf = PointInTriangle(~currentIndex, vPos, plane.vNormal, plane.d);
				}
			}
			if(!m_foundLeaf){
				currentIndex = FindLeafIntersection(node.front, vPos);
				if(currentIndex < 0){
					m_foundLeaf = PointInTriangle(~currentIndex, vPos, plane.vNormal, plane.d);
				}
			}
        }
		// Either found a leaf, or not, either way just exit back out of the recursion returning the index
		return m_foundIndex;
    }
}
Exemplo n.º 3
0
void C_BspNode::CleanUpPointSet(C_BspNode* node , vector<C_Vertex>& points)
{
   unsigned int cPoint = 0;

   /// Remove points outside the bbox
   while(cPoint < points.size()) {
      if(node->bbox.IsInside(&points[cPoint]) == false) {
         points.erase(points.begin() + cPoint);
         cPoint--;
      }

      cPoint++;
   }

   /// Remove points coinciding with the triangles of the given node
   /// NOTE: VERY BRUTE FORCE WAY. MUST FIND SOMETHING FASTER.
   for(int cTri = 0 ; cTri < node->nTriangles ; cTri++) {
      cPoint = 0;
      while(cPoint < points.size()) {
         if(PointInTriangle(&points[cPoint] , &node->triangles[cTri])) {
            points.erase(points.begin() + cPoint);
            cPoint--;
         }

         cPoint++;
      }
   }
}
Exemplo n.º 4
0
//---------------------------------------------------------------------------//
bool TriangleSegmentIntersection
(
	LTVector3f&			pi,	//point of intersection
	const LTVector3f&	v0,	//triangle vertices
	const LTVector3f&	v1,
	const LTVector3f&	v2,
	const LTVector3f&	l0,	//line segment
	const LTVector3f&	l1
)
{
	//face normal (don't need to normalize)
	const LTVector3f n = (v1-v0).Cross(v2-v0);
	//intersection with plane
	const float d0 = n.Dot(l0 - v0);
	const float d1 = n.Dot(l1 - v0);

	if( d0*d1 <= 0 )//opposite sides, or touching
	{
		const float diff = d0 - d1;

		if( diff != 0 )
			pi = (d0*l1 - d1*l0) / diff;//interpolate
		else
			pi = l0;//single point in the plane

		return PointInTriangle( pi, v0, v1, v2 );
	}

	return false;
}
Exemplo n.º 5
0
/**
 * Test if a given 2D point (x, y) is inside a triangle of this TIN (given
 * by index).  If so, return true and give the elevation value by reference.
 */
bool vtTin::TestTriangle(int tri, const DPoint2 &p, float &fAltitude) const
{
	// get points
	const int v0 = m_tri[tri*3];
	const int v1 = m_tri[tri*3+1];
	const int v2 = m_tri[tri*3+2];
	const DPoint2 &p1 = m_vert[v0];
	const DPoint2 &p2 = m_vert[v1];
	const DPoint2 &p3 = m_vert[v2];

	// First try to identify which triangle
	if (PointInTriangle(p, p1, p2, p3))
	{
		double bary[3];
		if (BarycentricCoords(p1, p2, p3, p, bary))
		{
			// compute barycentric combination of function values at vertices
			const double val = bary[0] * m_z[v0] +
							   bary[1] * m_z[v1] +
							   bary[2] * m_z[v2];
			fAltitude = (float) val;
			return true;
		}
	}
	return false;
}
Exemplo n.º 6
0
bool    pfGUIControlMod::PointInBounds( const hsPoint3 &point )
{
    UpdateBounds();

    if( fBounds.GetType() != kBoundsEmpty && fBounds.GetType() != kBoundsUninitialized && fBounds.IsInside( &point ) )
    {
        if( fBoundsPoints.GetCount() > 0 )
        {
            // We have a more-accurate bounds set, so use it
            int     i;


            for( i = 1; i < fBoundsPoints.GetCount() - 1; i++ )
            {
                // Test the triangle (0,i,i+1)
                if( PointInTriangle( fBoundsPoints[ 0 ], fBoundsPoints[ i ], fBoundsPoints[ i + 1 ], point ) )
                    return true;
            }
            return false;
        }
        else
            return true;
    }
    return false;
}
Exemplo n.º 7
0
size_t FindEar(const tvector<vec3>& avecPoints)
{
	size_t iPoints = avecPoints.size();

	// A triangle is always an ear.
	if (iPoints <= 3)
		return 0;

	size_t i;

	vec3 vecFaceNormal;

	// Calculate the face normal.
	for (i = 0; i < iPoints; i++)
	{
		size_t iNext = (i+1)%iPoints;

		vec3 vecPoint = avecPoints[i];
		vec3 vecNextPoint = avecPoints[iNext];

		vecFaceNormal.x += (vecPoint.y - vecNextPoint.y) * (vecPoint.z + vecNextPoint.z);
		vecFaceNormal.y += (vecPoint.z - vecNextPoint.z) * (vecPoint.x + vecNextPoint.x);
		vecFaceNormal.z += (vecPoint.x - vecNextPoint.x) * (vecPoint.y + vecNextPoint.y);
	}

	vecFaceNormal.Normalize();

	for (i = 0; i < iPoints; i++)
	{
		size_t iLast = i==0?iPoints-1:i-1;
		size_t iNext = i==iPoints-1?0:i+1;

		vec3 vecLast = avecPoints[iLast];
		vec3 vecThis = avecPoints[i];
		vec3 vecNext = avecPoints[iNext];

		// Concave ones can not be ears.
		if ((vecLast-vecThis).Cross(vecLast-vecNext).Dot(vecFaceNormal) < 0)
			continue;

		bool bFoundPoint = false;
		for (size_t j = 0; j < iPoints; j++)
		{
			if (j == i || j == iLast || j == iNext)
				continue;

			if (PointInTriangle(avecPoints[j], vecLast, vecThis, vecNext))
			{
				bFoundPoint = true;
				break;
			}
		}

		if (!bFoundPoint)
			return i;
	}

	return 0;
}
Exemplo n.º 8
0
int RayInTriangle(Coord start, Coord dir, Coord t1, Coord t2, Coord t3, Coord *contact)
{
  Coord normal;
  int n;
  n = RayInPlane(start, dir, t1, t2, t3, contact, &normal); 

  if(n == 0)return 0;
  if(PointInTriangle(*contact, t1, t2, t3) == 1)return (1 * n);
  return 0;
}
int MeshModel::getFaceUnderPoint(Point2 point) const
{
	for (unsigned int i=0; i < getNumFaces() ; i++) {
		Face& face = (*faces)[i];
		if (PointInTriangle(point, vertices[face.a()],vertices[face.b()],vertices[face.c()]))
			return i;
	}

	return -1;
}
Exemplo n.º 10
0
void bBoard::draw_balls()
{
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glEnable(GL_TEXTURE_2D);
    shadow.bind();
    for( int i=0; i<ball_size; ++i ) {
        ball[i]->draw_shadow( bVector3(0.0, 8.0, 0.0) );
    }
    
    ball_shader.enable( bShader::B_BOTH );
    ball_shader.bind( bShader::B_BOTH );
    
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glEnable(GL_TEXTURE_2D);
    ball_num.bind();
    
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);
    ball_tex.bind();
    
    glMultiTexCoord3fARB( GL_TEXTURE2_ARB, 3.0f, 2.0, -2.5f );
    for( int i=0; i<ball_size; ++i ) {
		if( i > 0 ) ball[i]->set_visibility( false );
		for(int j=0; j<DESK_SEGMENTS-2; ++j ) {
			if( PointInTriangle( ball[i]->pos, 
					bVector( desk_data[j].x, desk_data[j].y ), 
					bVector( desk_data[j+1].x, desk_data[j+1].y ), 
					bVector( desk_data[j+2].x, desk_data[j+2].y ) ) ) {
				ball[i]->set_visibility( true );
				break;
			}
		}
		ball[i]->draw( &ball_shader );
    }
    
    glActiveTextureARB(GL_TEXTURE0_ARB);
    
    ball_shader.disable( bShader::B_BOTH );
    
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);
    glDisable( GL_BLEND );
    
    glEnable( GL_DEPTH_TEST );   
}
Exemplo n.º 11
0
float DistanceToPolygon(const vec3& p, tvector<vec3>& v, vec3 n)
{
	float flPlaneDistance = DistanceToPlane(p, v[0], n);

	size_t i;

	bool bFoundPoint = false;

	for (i = 0; i < v.size()-2; i++)
	{
		if (PointInTriangle(p, v[0], v[i+1], v[i+2]))
		{
			bFoundPoint = true;
			break;
		}
	}

	if (bFoundPoint)
		return flPlaneDistance;

	float flClosestPoint = -1;
	for (i = 0; i < v.size(); i++)
	{
		float flPointDistance = (v[i] - p).Length();
		if (flClosestPoint == -1 || (flPointDistance < flClosestPoint))
			flClosestPoint = flPointDistance;

		float flLineDistance;
		if (i == v.size() - 1)
			flLineDistance = DistanceToLineSegment(p, v[i], v[0]);
		else
			flLineDistance = DistanceToLineSegment(p, v[i], v[i+1]);

		if (flClosestPoint == -1 || (flLineDistance < flClosestPoint))
			flClosestPoint = flLineDistance;
	}

	return flClosestPoint;
}
Exemplo n.º 12
0
void Terrain::SplitTriangle(Node* T)
{
	Triangle t = TriangleTree.getCurrentNode(T);
	TriangleTree.ExpandNode(T);
	
	// Step 1 : Get the old triangles points		
	Vector Apex = t.Apex;
	Vector Left = t.Left;
	Vector Right = t.Right;

	// Step 2 : Get new Apex point which is the midpoint between Left and Right		
	int lx = static_cast<int>(Left.x);
	int ly = static_cast<int>(Left.y);
	int rx = static_cast<int>(Right.x);
	int ry = static_cast<int>(Right.y);
	Vector newApex = Vector(static_cast<float>((lx + rx) / 2), static_cast<float>((ly + ry) / 2));    

	// Step 3 : Create first triangle and add to tree ( This is left half of old triangle )	
	double TriangleLeft = CalculateError(Apex , Left);				
	Triangle NewTLeft = Triangle(newApex, Apex, Left); // Apex = new Apex, Left = old Left, Right = Old Apex			
	for(int i = 0; (unsigned)i < t.Tree.size(); i++)
	{	
		Vector Current = t.Tree[i];
		if(PointInTriangle(Vector(Current.x, Current.y), Vector(newApex.x, newApex.y), Vector(Apex.x, Apex.y), Vector(Left.x, Left.y)))		
		{
			NewTLeft.Tree.push_back(Current);			
		}
	}

	// Step 4 : Create the second triangle and add to tree	
	double TriangleRight = CalculateError(Right , Apex);				
	Triangle NewTRight = Triangle(newApex, Right, Apex);	
	for(int i = 0; (unsigned)i < t.Tree.size(); i++)
	{	
		Vector Current = t.Tree[i];
		if(PointInTriangle(Vector(Current.x, Current.y), Vector(newApex.x, newApex.y), Vector(Right.x, Right.y), Vector(Apex.x, Apex.y) ))	
		{
			NewTRight.Tree.push_back(Current);			
		}
	}


	T->LeftChild->LeftNeighbour = T->RightChild;
	T->RightChild->RightNeighbour = T->LeftChild;	
	T->LeftChild->BaseNeighbour = T->LeftNeighbour;	
	T->RightChild->BaseNeighbour = T->RightNeighbour;
	
	if(T->LeftNeighbour != NULL)
	{		    
	   	if(T->LeftNeighbour->BaseNeighbour == T)
		{	
          	T->LeftNeighbour->BaseNeighbour = T->LeftChild;
			T->LeftNeighbour->Parent->RightNeighbour = T->LeftChild;		
		}
		else
		{		 
			T->LeftNeighbour->RightNeighbour = T->LeftChild;
		}
	}
	if(T->RightNeighbour != NULL)
	{
		if(T->RightNeighbour->BaseNeighbour == T)
		{		    
			T->RightNeighbour->BaseNeighbour = T->RightChild;
			T->RightNeighbour->Parent->LeftNeighbour = T->RightChild;
		}
		else
		{ 			    
			T->RightNeighbour->LeftNeighbour = T->RightChild;
		}
	}	
	TriangleTree.InsertAtNode(T->LeftChild, NewTLeft, TriangleLeft);
	TriangleTree.InsertAtNode(T->RightChild, NewTRight, TriangleRight);	
}
Exemplo n.º 13
0
bool PointInTriangle(Triangle & tri, Vector3f & point)
{
	return PointInTriangle(tri.v[0].pos, tri.v[1].pos, tri.v[2].pos, point);
}
Exemplo n.º 14
0
/**
 * intersects a triangle ABC with a line PQ
 *
 * return values:
 * -1: error
 * 0: no intersection
 * 1: intersects in a point
 * 2: intersects in a line
 */
int SegmentTriangleIntersect(
    const ON_3dPoint& a,
    const ON_3dPoint& b,
    const ON_3dPoint& c,
    const ON_3dPoint& p,
    const ON_3dPoint& q,
    ON_3dPoint out[2],
    double tol
    )
{
    ON_3dPoint triangle[3] = {a, b, c}; /* it'll be nice to have this as an array too*/

    /* First we need to get our plane into point normal form (N \dot (P - P0) = 0)
     * Where N is a normal vector, and P0 is a point in the plane
     * P0 can be any of {a, b, c} so that's easy
     * Finding N
     */

    double normal[3];
    VCROSS(normal, b - a, c - a);
    VUNITIZE(normal);

    ON_3dPoint P0 = a; /* could be b or c*/

    /* Now we've got our plane in a manageable form (two of them actually)
     * So here's the rest of the plan:
     * Every point P on the line can be written as: P = p + u (q - p)
     * We just need to find u
     * We know that when u is correct:
     * normal dot (q + u * (q-p) = N dot P0
     *		   N dot (P0 - p)
     * so u =      --------------
     *		   N dot (q - p)
     */

    if (!NEAR_ZERO(VDOT(normal, (p-q)), tol)) {/* if this is 0 it indicates the line and plane are parallel*/
	double u = VDOT(normal, (P0 - p))/VDOT(normal, (q - p));
	if (u < 0.0 || u > 1.0)	/* this means we're on the line but not the line segment*/
	    return 0;		/* so we can return early*/
	ON_3dPoint P = p + u * (q - p);

	if (PointInTriangle(a, b, c, P, tol)) {
	    out[0] = P;
	    return 1;
	}
	return 0;

    } else {
	/* If we're here it means that the line and plane are parallel*/

	if (NEAR_ZERO(VDOT(normal, p-P0), tol)) {/* yahtzee!!*/
	    /* The line segment is in the same plane as the triangle*/
	    /* So first we check if the points are inside or outside the triangle*/
	    bool p_in = PointInTriangle(a, b, c, p, tol);
	    bool q_in = PointInTriangle(a, b , c , q , tol);
	    ON_3dPoint x[2]; /* a place to put our results*/

	    if (q_in && p_in) {
		out[0] = p;
		out[1] = q;
		return 2;
	    } else if (q_in || p_in) {
		if (q_in)
		    out[0] = q;
		else
		    out[0] = p;

		int i;
		int rv;
		for (i=0; i<3; i++) {
		    rv = SegmentSegmentIntersect(triangle[i], triangle[(i+1)%3], p, q, x, tol);
		    if (rv == 1) {
			out[1] = x[0];
			return 1;
		    } else if (rv == 2) {
			out[0] = x[0];
			out[1] = x[1];
			return 2;
		    }
		}
	    } else {
		/* neither q nor p is in the triangle*/

		int i;
		int points_found = 0;
		int rv;
		for (i = 0; i < 3; i++) {
		    rv = SegmentSegmentIntersect(triangle[i], triangle[(i+1)%3], p, q, x, tol);
		    if (rv == 1) {
			if (points_found == 0 || !VNEAR_EQUAL(out[0], x[0], tol)) { /* in rare cases we can get the same point twice*/
			    out[points_found] = x[0];
			    points_found++;
			}
		    } else if (rv == 2) {
			out[0] = x[0];
			out[1] = x[1];
			return 2;
		    }
		}
		return points_found;
	    }
	} else
	    return 0;
    }
    return -1;
}
Exemplo n.º 15
0
int main(){
    int N_nodes = sizeOfFile("nodepos.dat",2);
    int N_patch = sizeOfFile("patch_node.dat",3);

    InstArry(N_nodes,N_patch);
    readNodePos();
    readpatchNode();

    int curnum = 0;
    for(int i=1;i<=N_patch;i++){
        for(int j=1;j<=3;j++){
            curnum = (i-1)*3+j;
            edgeInfo[curnum][1] = i;
            edgeInfo[curnum][2] = j;
            if (patchNode[i][next(j)]<patchNode[i][next(next(j))]){
                edgeInfo[curnum][3] = patchNode[i][next(j)];
                edgeInfo[curnum][4] = patchNode[i][next(next(j))];
            }else{
                edgeInfo[curnum][3] = patchNode[i][next(next(j))];
                edgeInfo[curnum][4] = patchNode[i][next(j)];
            }
        }
    }


    sortArry(N_patch);

    edgeLink[1][1] = edgeInfo[1][3];
    edgeLink[1][2] = edgeInfo[1][4];
    patch_edge[edgeInfo[1][1]][edgeInfo[1][2]] = 1;

    int N_edge = 1;

    for(int i=2;i<=3*N_patch;i++){
        if((edgeInfo[i][3]!=edgeInfo[i-1][3])||(edgeInfo[i][4]!=edgeInfo[i-1][4])){
            N_edge++;
            edgeLink[i][1] = edgeInfo[i][3];
            edgeLink[i][2] = edgeInfo[i][4];
            patch_edge[edgeInfo[i][1]][edgeInfo[i][2]] = N_edge;
        }else{
            patch_edge[edgeInfo[i][1]][edgeInfo[i][2]] = N_edge;
        }
    }
    int Nb = 0;
    InstArryAdd(N_patch,N_edge,Nb);

    CalcEFieldPos(N_edge,N_patch);
    CalcHfieldPos(N_edge,N_patch, 0.01);

//Output all the data (test)
    writeGrid("pos_nodes.dat","vertiic.dat",N_nodes,N_patch);
    writeFiledPos(N_edge,N_patch);

//form a general matrix of coefs
    for(int i = 1;i<=N_patch;i++){
 // all electric field global numbers corresponding to givern patch
        for(int j=1;j<=3;j++){
            coefMat[i][2*j-1] = 2*patch_edge[i][j]-1;
            coefMat[i][2*j] = 2*patch_edge[i][j];
        }
        coefMat[i][7] = 2*N_edge+2*i-1;
        coefMat[i][8] = 2*N_edge+2*i;

        for(int j=1;j<=3;j++){
            if (PointInTriangle(i, 4*patch_edge[i][j]-3)== true){
                coefMat[i][2*(j+4)-1] = 4*patch_edge[i][j]-3;
            } else{
                coefMat[i][2*(j+4)-1] = 4*patch_edge[i][j]-2;
            }

            if (PointInTriangle(i, 4*patch_edge[i][j]-1)== true){
                coefMat[i][2*(j+4)] = 4*patch_edge[i][j]-1;
            } else{
                coefMat[i][2*(j+4)] = 4*patch_edge[i][j];
            }
        }
        coefMat[i][15] = 4*N_edge+4*i-3;
        coefMat[i][16] = 4*N_edge+4*i-2;

        coefMat[i][17] = 4*N_edge+4*i-1;
        coefMat[i][18] = 4*N_edge+4*i;
// area of the triangle

        double x1 = nodePos[edgeLinkS[patch_edge[i][2]][2]][1];
        double y1 = nodePos[edgeLinkS[patch_edge[i][2]][2]][2];

        double x2 = nodePos[edgeLinkS[patch_edge[i][3]][2]][1];
		double y2 = nodePos[edgeLinkS[patch_edge[i][3]][2]][2];

		double x3 = nodePos[edgeLinkS[patch_edge[i][1]][2]][1];
		double y3 = nodePos[edgeLinkS[patch_edge[i][1]][2]][2];

		area[i] = fabs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));
       //area[i] =x1;
    }

	ofstream out1;
	out1.open("Matrix.dat");
	for(int i = 1;i<=N_patch;i++){
		out1<<i<<" "<<coefMat[i][1]<<" "<<coefMat[i][2]<<" "<<coefMat[i][3]<<" "<<coefMat[i][4]<<" "<<coefMat[i][5]<<" "<<coefMat[i][6]<<" "<<coefMat[i][7]<<" "<<coefMat[i][8]<<" "<<coefMat[i][9]<<" "<<coefMat[i][10]<<" "<<coefMat[i][11]<<" "<<coefMat[i][12]<<" "<<coefMat[i][13]<<" "<<coefMat[i][14]<<" "<<coefMat[i][15]<<" "<<coefMat[i][16]<<" "<<coefMat[i][17]<<" "<<coefMat[i][18]<<" "<<area[i]<<endl;
		//out1<<i<<" "<<nodePos[edgeLinkS[patch_edge[i][2]][2]][2]<<" "<<nodePos[edgeLinkS[patch_edge[i][1]][1]][2]<<" "<<nodePos[edgeLinkS[patch_edge[i][1]][2]][2]<<endl;
	}

    return 0;
}
void Triangulation2D_Delaunay::InsertPoint(Point* newPoint) {
	if(_triangles.empty()) {
		// 1er point
		if(_points.empty()) {
			_points.push_back(newPoint);
		}
		// 2em point
		else if(_points.size() == 1) {
			_points.push_back(newPoint);
			_edges.push_back(new Line(_points[0], newPoint));
		}
		// 3+em point
		else {
			_points.push_back(newPoint);
			// Si le point est colinéaire aux autres
			if(isOnLine(_edges[0], newPoint)) {
				// Si le point est à l'extremité "basse" des points colinéaires
				Point* minPoint = getMinCoordinates(_points);
				Point* maxPoint = getMaxCoordinates(_points);

				if(newPoint->getX() < minPoint->getX() || (newPoint->getX() == minPoint->getX() && newPoint->getY() < minPoint->getY())) {
					_edges.push_back(new Line(newPoint, nullptr));
				}
				// Si le point est à l'extremité "haute" des points colinéaires
				else if(newPoint->getX() > maxPoint->getX() || (newPoint->getX() == maxPoint->getX() && newPoint->getY() > maxPoint->getY())) {
					_edges.push_back(new Line(nullptr, newPoint));
				}
				// Si le point est en plein milieu
				// On update l'ancienne arete et on ajoute une nouvelle arête
				else {
					Point* pointBefore = getMiddleCoordinates(_points, newPoint);
					for(auto edge : _edges) {
						if(edge->getStartPoint() == pointBefore) {
							_edges.push_back(new Line(newPoint, edge->getEndPoint()));
							edge->setEndPoint(newPoint);
							break;
						}
					}

				}

				delete minPoint;
				delete maxPoint;
			}
			// Si le point n'est pas colinéaire
			// (on passera ici qu'une fois normalement)
			else {
				for(auto point : _points) {
					Line* tempLine = new Line(point, newPoint);
					_edges.push_back(tempLine);
					point->setLine(tempLine);
				}

				for(auto edge : _edges) {
					Line* tempLineA = edge->getStartPoint()->getLine();
					Line* tempLineB = edge->getEndPoint()->getLine();
					// Peut etre à l'envers
					_triangles.push_back(new Triangle(edge, tempLineA, tempLineB));
					// ou 
					//_triangles.push_back(new Triangle(edge, tempLineB, tempLineA));
					// en fonction de la position de newPoint ?
				}
			}
		}
	}
	// Y'a deja des triangles
	else {
		_points.push_back(newPoint);
		// Si le point est dans un triangle
		bool inTriangle = false;
		Triangle* triangleContainingPoint = nullptr;
		std::vector<Line*> edges;

		std::vector<Triangle*>::iterator it;
		for(it = _triangles.begin(); it != _triangles.end(); it++) {
			Triangle* triangle = *it;
			if(PointInTriangle(*newPoint, *triangle->getPointA(), *triangle->getPointB(), *triangle->getPointC())) {
				inTriangle = true;
				triangleContainingPoint = triangle;
				break;
			}
		}
		if(inTriangle) {
			_triangles.erase(it);
			edges.push_back(triangleContainingPoint->LineA());
			edges.push_back(triangleContainingPoint->LineB());
			edges.push_back(triangleContainingPoint->LineC());
		}
		else {
			//TODO: déterminer la liste des aretes vues par le point
			// Avec l'enveloppe c'est plus opti
			for(auto edge : _edges) {
				Point normal(-(edge->getEndPoint()->getY() - (edge->getStartPoint()->getY())), edge->getEndPoint()->getX() - (edge->getStartPoint())->getX());
				Point edgee(newPoint->getX() - edge->getEndPoint()->getX(), newPoint->getY() - edge->getEndPoint()->getY());
				double dot = dotProduct(normal, edgee);
				if(dot < 0) {
					edges.push_back(edge);
				}
			}
		}

		while(!edges.empty()) {
			Line* a = edges.back();
			edges.pop_back();

			bool pointInCircle = false;
			std::vector<Triangle*>::iterator it2;
			for(it2 = _triangles.begin(); it2 != _triangles.end(); it2++) {
				Triangle* triangle2 = *it2;
				if(inCircle(triangle2->getPointA(), triangle2->getPointB(), triangle2->getPointC(), newPoint)) {
					pointInCircle = true;
					break;
				}
			}

			// Si l'arete a un triangle incident t dont le cercle circonscrit contient newPoint, suprimer le triangle t et l'arete a et ajouter les 2 autres aretes du triangle à la liste
			if(pointInCircle) {
				std::cout << "je passe jamais !" << std::endl;
				Triangle* triangle = *it;
				edges.erase(edges.begin());
				if(triangle->LineA() != a) {
					edges.push_back(triangle->LineA());
				}
				if(triangle->LineB() != a) {
					edges.push_back(triangle->LineB());
				}
				if(triangle->LineC() != a) {
					edges.push_back(triangle->LineC());
				}
				_triangles.erase(it);
			}
			else {
				// creer aretes start - new et end - new et le triangle a a1 a2 (ou a2 a1 a)
				Line* a1 = new Line(a->getStartPoint(), newPoint);
				Line* a2 = new Line(a->getEndPoint(), newPoint);
				_edges.push_back(a1);
				_edges.push_back(a2);
				_triangles.push_back(new Triangle(a, a1, a2));
			}
		}
	}
}
Exemplo n.º 17
0
Arquivo: ao.cpp Projeto: ezhangle/SMAK
void CAOGenerator::GenerateTriangleByTexel(CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, size_t v1, size_t v2, size_t v3, raytrace::CRaytracer* pTracer, size_t& iRendered)
{
    CConversionVertex* pV1 = pFace->GetVertex(v1);
    CConversionVertex* pV2 = pFace->GetVertex(v2);
    CConversionVertex* pV3 = pFace->GetVertex(v3);

    CConversionMesh* pMesh = pMeshInstance->GetMesh();

    Vector vu1 = pMesh->GetUV(pV1->vu);
    Vector vu2 = pMesh->GetUV(pV2->vu);
    Vector vu3 = pMesh->GetUV(pV3->vu);

    Vector vecLoUV = vu1;
    Vector vecHiUV = vu1;

    if (vu2.x < vecLoUV.x)
        vecLoUV.x = vu2.x;
    if (vu3.x < vecLoUV.x)
        vecLoUV.x = vu3.x;
    if (vu2.x > vecHiUV.x)
        vecHiUV.x = vu2.x;
    if (vu3.x > vecHiUV.x)
        vecHiUV.x = vu3.x;

    if (vu2.y < vecLoUV.y)
        vecLoUV.y = vu2.y;
    if (vu3.y < vecLoUV.y)
        vecLoUV.y = vu3.y;
    if (vu2.y > vecHiUV.y)
        vecHiUV.y = vu2.y;
    if (vu3.y > vecHiUV.y)
        vecHiUV.y = vu3.y;

    size_t iLoX = (size_t)(vecLoUV.x * m_iWidth);
    size_t iLoY = (size_t)(vecLoUV.y * m_iHeight);
    size_t iHiX = (size_t)(vecHiUV.x * m_iWidth);
    size_t iHiY = (size_t)(vecHiUV.y * m_iHeight);

    for (size_t i = iLoX; i <= iHiX; i++)
    {
        for (size_t j = iLoY; j <= iHiY; j++)
        {
            float flU = ((float)i + 0.5f)/(float)m_iWidth;
            float flV = ((float)j + 0.5f)/(float)m_iHeight;

            bool bInside = PointInTriangle(Vector(flU,flV,0), vu1, vu2, vu3);

            if (!bInside)
                continue;

            Vector v1 = pMeshInstance->GetVertex(pV1->v);
            Vector v2 = pMeshInstance->GetVertex(pV2->v);
            Vector v3 = pMeshInstance->GetVertex(pV3->v);

            Vector vn1 = pMeshInstance->GetNormal(pV1->vn);
            Vector vn2 = pMeshInstance->GetNormal(pV2->vn);
            Vector vn3 = pMeshInstance->GetNormal(pV3->vn);

            // Find where the UV is in world space.

            // First build 2x2 a "matrix" of the UV values.
            float mta = vu2.x - vu1.x;
            float mtb = vu3.x - vu1.x;
            float mtc = vu2.y - vu1.y;
            float mtd = vu3.y - vu1.y;

            // Invert it.
            float d = mta*mtd - mtb*mtc;
            float mtia =  mtd / d;
            float mtib = -mtb / d;
            float mtic = -mtc / d;
            float mtid =  mta / d;

            // Now build a 2x3 "matrix" of the vertices.
            float mva = v2.x - v1.x;
            float mvb = v3.x - v1.x;
            float mvc = v2.y - v1.y;
            float mvd = v3.y - v1.y;
            float mve = v2.z - v1.z;
            float mvf = v3.z - v1.z;

            // Multiply them together.
            // [a b]   [a b]   [a b]
            // [c d] * [c d] = [c d]
            // [e f]           [e f]
            // Really wish I had a matrix math library about now!
            float mra = mva*mtia + mvb*mtic;
            float mrb = mva*mtib + mvb*mtid;
            float mrc = mvc*mtia + mvd*mtic;
            float mrd = mvc*mtib + mvd*mtid;
            float mre = mve*mtia + mvf*mtic;
            float mrf = mve*mtib + mvf*mtid;

            // These vectors should be the U and V axis in world space.
            Vector vecUAxis(mra, mrc, mre);
            Vector vecVAxis(mrb, mrd, mrf);

            Vector vecUVOrigin = v1 - vecUAxis * vu1.x - vecVAxis * vu1.y;

            Vector vecUVPosition = vecUVOrigin + vecUAxis * flU + vecVAxis * flV;

            Vector vecNormal;

            if (m_bCreaseEdges)
                vecNormal = pFace->GetNormal();
            else
            {
                float wv1 = DistanceToLine(vecUVPosition, v2, v3) / DistanceToLine(v1, v2, v3);
                float wv2 = DistanceToLine(vecUVPosition, v1, v3) / DistanceToLine(v2, v1, v3);
                float wv3 = DistanceToLine(vecUVPosition, v1, v2) / DistanceToLine(v3, v1, v2);

                vecNormal = vn1 * wv1 + vn2 * wv2 + vn3 * wv3;
            }

            if (ao_debug.GetInt() > 1)
                SMAKWindow()->AddDebugLine(vecUVPosition, vecUVPosition + vecNormal/2);

            size_t iTexel;
            if (!Texel(i, j, iTexel, false))
                continue;

            if (m_eAOMethod == AOMETHOD_RENDER)
            {
                // Render the scene from this location
                m_avecShadowValues[iTexel] += RenderSceneFromPosition(vecUVPosition, vecNormal, pFace);
            }
            else if (m_eAOMethod == AOMETHOD_RAYTRACE)
            {
                RaytraceSceneMultithreaded(pTracer, vecUVPosition, vecNormal, pMeshInstance, pFace, iTexel);
            }

            m_aiShadowReads[iTexel]++;
            m_bPixelMask[iTexel] = true;

            m_pWorkListener->WorkProgress(++iRendered);

            if (m_bStopGenerating)
                break;
        }
        if (m_bStopGenerating)
            break;
    }
}
Exemplo n.º 18
0
std::vector<GameObject*> CollisionManager::getGameObjectBetween(Vector2d upright, Vector2d upleft, Vector2d downright, Vector2d downleft)
{
	std::vector<GameObject*> list;
	GameObject* gameObject = NULL;
	Vector2d position;
	float radius;
	for(std::size_t i = 0; i < colliderEnemyList.size(); i++)
	{
		position = colliderEnemyList[i]->getGameObject()->position;
		gameObject = colliderEnemyList[i]->getGameObject();
		radius = Math::sqrt(colliderEnemyList[i]->getSqrCollisionRadius());
		if (PointInTriangle(position,upleft,downleft,downright))
		{
			list.push_back(gameObject);
		}
		else if(PointInTriangle(position,upleft,upright,downright))
		{
			list.push_back(gameObject);
		}
		else if(VertexRectangleInCircle(position,radius,upleft,downleft,downright,upright))
		{
			list.push_back(gameObject);
		}
		else if(LineCircleIntersect(position,radius,downright,upright))
		{
			list.push_back(gameObject);
		}
		else if(LineCircleIntersect(position,radius,downleft,downright))
		{
			list.push_back(gameObject);
		}
		else if(LineCircleIntersect(position,radius,upleft,downleft))
		{
			list.push_back(gameObject);
		}
		else if(LineCircleIntersect(position,radius,upleft,upright))
		{
			list.push_back(gameObject);
		}
	}
	
	for(std::size_t i = 0; i < colliderAlliesList.size(); i++)
	{
		position = colliderAlliesList[i]->getGameObject()->position;
		gameObject = colliderAlliesList[i]->getGameObject();
		radius = Math::sqrt(colliderAlliesList[i]->getSqrCollisionRadius());
		if (PointInTriangle(position,upleft,downleft,downright))
		{
			list.push_back(gameObject);
		}
		else if(PointInTriangle(position,upleft,upright,downright))
		{
			list.push_back(gameObject);
		}
		else if(VertexRectangleInCircle(position,radius,upleft,downleft,downright,upright))
		{
			list.push_back(gameObject);
		}
		else if(LineCircleIntersect(position,radius,downright,upright))
		{
			list.push_back(gameObject);
		}
		else if(LineCircleIntersect(position,radius,downleft,downright))
		{
			list.push_back(gameObject);
		}
		else if(LineCircleIntersect(position,radius,upleft,downleft))
		{
			list.push_back(gameObject);
		}
		else if(LineCircleIntersect(position,radius,upleft,upright))
		{
			list.push_back(gameObject);
		}
	}
	return list;
}
Exemplo n.º 19
0
void CTexelGenerator::FindHiResMeshLocation(CConversionMeshInstance* pMeshInstance, CConversionFace* pFace, CConversionVertex* pV1, CConversionVertex* pV2, CConversionVertex* pV3, size_t i, size_t j, raytrace::CRaytracer* pTracer)
{
	CConversionMesh* pMesh = pMeshInstance->GetMesh();

	Vector vu1 = pMesh->GetUV(pV1->vu);
	Vector vu2 = pMesh->GetUV(pV2->vu);
	Vector vu3 = pMesh->GetUV(pV3->vu);

	float flU = ((float)i + 0.5f)/(float)m_iWidth;
	float flV = ((float)j + 0.5f)/(float)m_iHeight;

	bool bInside = PointInTriangle(Vector(flU,flV,0), vu1, vu2, vu3);

	if (!bInside)
		return;

	Vector v1 = pMeshInstance->GetVertex(pV1->v);
	Vector v2 = pMeshInstance->GetVertex(pV2->v);
	Vector v3 = pMeshInstance->GetVertex(pV3->v);

	// Find where the UV is in world space.

	// First build 2x2 a "matrix" of the UV values.
	float mta = vu2.x - vu1.x;
	float mtb = vu3.x - vu1.x;
	float mtc = vu2.y - vu1.y;
	float mtd = vu3.y - vu1.y;

	// Invert it.
	float d = mta*mtd - mtb*mtc;
	float mtia =  mtd / d;
	float mtib = -mtb / d;
	float mtic = -mtc / d;
	float mtid =  mta / d;

	// Now build a 2x3 "matrix" of the vertices.
	float mva = v2.x - v1.x;
	float mvb = v3.x - v1.x;
	float mvc = v2.y - v1.y;
	float mvd = v3.y - v1.y;
	float mve = v2.z - v1.z;
	float mvf = v3.z - v1.z;

	// Multiply them together.
	// [a b]   [a b]   [a b]
	// [c d] * [c d] = [c d]
	// [e f]           [e f]
	// Really wish I had a matrix math library about now!
	float mra = mva*mtia + mvb*mtic;
	float mrb = mva*mtib + mvb*mtid;
	float mrc = mvc*mtia + mvd*mtic;
	float mrd = mvc*mtib + mvd*mtid;
	float mre = mve*mtia + mvf*mtic;
	float mrf = mve*mtib + mvf*mtid;

	// These vectors should be the U and V axis in world space.
	Vector vecUAxis(mra, mrc, mre);
	Vector vecVAxis(mrb, mrd, mrf);

	Vector vecUVOrigin = v1 - vecUAxis * vu1.x - vecVAxis * vu1.y;

	Vector vecUVPosition = vecUVOrigin + vecUAxis * flU + vecVAxis * flV;

	Vector vecNormal = pFace->GetNormal(vecUVPosition, pMeshInstance);

	size_t iTexel;
	Texel(i, j, iTexel, false);

	// Maybe use a closest-poly check here to eliminate the need for some raytracing?

	raytrace::CTraceResult trFront;
	bool bHitFront = pTracer->Raytrace(Ray(vecUVPosition, vecNormal), &trFront);

	raytrace::CTraceResult trBack;
	bool bHitBack = pTracer->Raytrace(Ray(vecUVPosition, -vecNormal), &trBack);

#ifdef NORMAL_DEBUG
	GetParallelizer()->LockData();
	if (bHitFront && (vecUVPosition - trFront.m_vecHit).LengthSqr() > 0.001f)
		SMAKWindow()->AddDebugLine(vecUVPosition, trFront.m_vecHit);
	if (bHitBack && (vecUVPosition - trBack.m_vecHit).LengthSqr() > 0.001f)
		SMAKWindow()->AddDebugLine(vecUVPosition, trBack.m_vecHit);
	GetParallelizer()->UnlockData();
#endif

	if (!bHitBack && !bHitFront)
		return;

	raytrace::CTraceResult* trFinal;

	if (bHitFront && !bHitBack)
		trFinal = &trFront;
	else if (bHitBack && !bHitFront)
		trFinal = &trBack;
	else
	{
		float flHitFront = (vecUVPosition - trFront.m_vecHit).LengthSqr();
		float flHitBack = (vecUVPosition - trBack.m_vecHit).LengthSqr();

		if (flHitFront < flHitBack)
			trFinal = &trFront;
		else
			trFinal = &trBack;
	}

#ifdef NORMAL_DEBUG
	GetParallelizer()->LockData();
//	SMAKWindow()->AddDebugLine(vecUVPosition, vecUVPosition+vecHitNormal);
	if (bHitFront && (vecUVPosition - trFront.m_vecHit).LengthSqr() > 0.001f)
		SMAKWindow()->AddDebugLine(trFront.m_vecHit, trFront.m_vecHit + trFront.m_pFace->GetNormal(trFront.m_vecHit, trFront.m_pMeshInstance));
	if (bHitBack && (vecUVPosition - trBack.m_vecHit).LengthSqr() > 0.001f)
		SMAKWindow()->AddDebugLine(trBack.m_vecHit, trBack.m_vecHit + trBack.m_pFace->GetNormal(trBack.m_vecHit, trBack.m_pMeshInstance));
	GetParallelizer()->UnlockData();
#endif

	for (size_t i = 0; i < m_apMethods.size(); i++)
	{
		m_apMethods[i]->GenerateTexel(iTexel, pMeshInstance, pFace, pV1, pV2, pV3, trFinal, vecUVPosition, pTracer);
	}
}
Exemplo n.º 20
0
float D3DPicking::Pick(const XMMATRIX& worldSpace)
{ 		
	//Loop through each triangle in the object
	for(int i = 0; i < m_IndexData.size()/3; i++)
	{
		//Triangle's vertices V1, V2, V3
		XMVECTOR tri1V1 = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
		XMVECTOR tri1V2 = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
		XMVECTOR tri1V3 = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);

		//Temporary 3d floats for each vertex
		XMFLOAT3 tV1, tV2, tV3;

		//Get triangle 
		tV1 = m_PosData[m_IndexData[(i*3)+0]];
		tV2 = m_PosData[m_IndexData[(i*3)+1]];
		tV3 = m_PosData[m_IndexData[(i*3)+2]];

		tri1V1 = XMVectorSet(tV1.x, tV1.y, tV1.z, 0.0f);
		tri1V2 = XMVectorSet(tV2.x, tV2.y, tV2.z, 0.0f);
		tri1V3 = XMVectorSet(tV3.x, tV3.y, tV3.z, 0.0f);

		//Transform the vertices to world space
		tri1V1 = XMVector3TransformCoord(tri1V1, worldSpace);
		tri1V2 = XMVector3TransformCoord(tri1V2, worldSpace);
		tri1V3 = XMVector3TransformCoord(tri1V3, worldSpace);

		//Find the normal using U, V coordinates (two edges)
		XMVECTOR U = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
		XMVECTOR V = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
		XMVECTOR faceNormal = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);

		U = tri1V2 - tri1V1;
		V = tri1V3 - tri1V1;

		//Compute face normal by crossing U, V
		faceNormal = XMVector3Cross(U, V);

		faceNormal = XMVector3Normalize(faceNormal);

		//Calculate a point on the triangle for the plane equation
		XMVECTOR triPoint = tri1V1;

		//Get plane equation ("Ax + By + Cz + D = 0") Variables
		float tri1A = XMVectorGetX(faceNormal);
		float tri1B = XMVectorGetY(faceNormal);
		float tri1C = XMVectorGetZ(faceNormal);
		float tri1D = (-tri1A*XMVectorGetX(triPoint) - tri1B*XMVectorGetY(triPoint) - tri1C*XMVectorGetZ(triPoint));

		//Now we find where (on the ray) the ray intersects with the triangles plane
		float ep1, ep2, t = 0.0f;
		float planeIntersectX, planeIntersectY, planeIntersectZ = 0.0f;
		XMVECTOR pointInPlane = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);

		ep1 = (XMVectorGetX(m_pickRayPos) * tri1A) + (XMVectorGetY(m_pickRayPos) * tri1B) + (XMVectorGetZ(m_pickRayPos) * tri1C);
		ep2 = (XMVectorGetX(m_pickRayDir) * tri1A) + (XMVectorGetY(m_pickRayDir) * tri1B) + (XMVectorGetZ(m_pickRayDir) * tri1C);

		//Make sure there are no divide-by-zeros
		if(ep2 != 0.0f)
			t = -(ep1 + tri1D)/(ep2);

		if(t > 0.0f)    //Make sure you don't pick objects behind the camera
		{
			//Get the point on the plane
			planeIntersectX = XMVectorGetX(m_pickRayPos) + XMVectorGetX(m_pickRayDir) * t;
			planeIntersectY = XMVectorGetY(m_pickRayPos) + XMVectorGetY(m_pickRayDir) * t;
			planeIntersectZ = XMVectorGetZ(m_pickRayPos) + XMVectorGetZ(m_pickRayDir) * t;

			pointInPlane = XMVectorSet(planeIntersectX, planeIntersectY, planeIntersectZ, 0.0f);

			//Call function to check if point is in the triangle
			if(PointInTriangle(tri1V1, tri1V2, tri1V3, pointInPlane))
			{
				//Return the distance to the hit, so you can check all the other pickable objects in your scene
				//and choose whichever object is closest to the camera
				return t/2.0f;
			}
		}
	}
	//return the max float value (near infinity) if an object was not picked
	return FLT_MAX;
}
Exemplo n.º 21
0
bool ATriangle::IsInside(Vector p)
{
	return (PointInTriangle(p) ^ inverted);
}
Exemplo n.º 22
0
void glFinalWidget::RepositionInteriorPoints()
{
    for (int vIndex = 0; vIndex < m_qVertices->size(); ++vIndex)
    {
        glMeshSelectWidget::vertex* currentVertex = m_qVertices->value(vIndex);

        if (HasThePoint(currentVertex))
        {
            continue;
        }

        bool pointInPatch = false;
        for (int pIndex = 0; pIndex < m_validTriangulations.size(); ++pIndex)
        {
            glProgressWidget::validateTriangulation currentTriangle = m_validTriangulations[pIndex];

            glMeshSelectWidget::vertex* vertexA;
            glMeshSelectWidget::vertex* vertexB;
            glMeshSelectWidget::vertex* vertexC;

            vertexA = currentTriangle.edgeA->startVertex;
            if (vertexA == currentTriangle.edgeB->startVertex)
            {
                vertexB = currentTriangle.edgeB->targetVertex;
            }
            else
            {
                vertexB = currentTriangle.edgeB->startVertex;
            }

            if (currentTriangle.edgeC->startVertex == vertexA || currentTriangle.edgeC->startVertex == vertexB)
            {
                vertexC = currentTriangle.edgeC->targetVertex;
            }
            else
            {
                vertexC = currentTriangle.edgeC->startVertex;
            }

            pointInPatch = PointInTriangle(*currentVertex, *vertexA, *vertexB, *vertexC);

            // if patch is found
            if (pointInPatch)
            {
                // Find all neighbors
                QVector<glMeshSelectWidget::vertex*> neighbors;
                for (int eIndex = 0; eIndex < currentVertex->edgeIndicies.size(); ++eIndex)
                {
                    int edgeIndex = currentVertex->edgeIndicies[eIndex];
                    if (m_qEdges->value(edgeIndex)->vertexA == currentVertex)
                    {
                        neighbors.push_back(m_qEdges->value(edgeIndex)->vertexB);
                    }
                    else if (m_qEdges->value(edgeIndex)->vertexB == currentVertex)
                    {
                        neighbors.push_back(m_qEdges->value(edgeIndex)->vertexA);
                    }
                }

                // re-compute the position
                glMeshSelectWidget::vertex sum;
                sum.x = 0.0;
                sum.y = 0.0;
                sum.z = 0.0;

                for (int nIndex = 0; nIndex < neighbors.size(); ++nIndex)
                {
                    sum.x += neighbors[nIndex]->x;
                    sum.y += neighbors[nIndex]->y;
                    sum.z += neighbors[nIndex]->z;
                }

                int num = neighbors.size();
                if (num > 0)
                {
                    sum.x = sum.x/(GLfloat)num;
                    sum.y = sum.y/(GLfloat)num;
                    sum.z = sum.z/(GLfloat)num;

                    // re-assign
                    currentVertex->x = sum.x;
                    currentVertex->y = sum.y;
                    currentVertex->z = sum.z;
                }
                break;
            }
        }
    }
}
Exemplo n.º 23
0
void Terrain::GenerateHeightMap(int Iterations, double Height, double HDecay)
{
	HeightMap.calculate(Iterations, Height, HDecay);	
	int Select = 1 + rand() % (4 - 1 + 1);		
	// Load .3DS file into model structure	
	if(Select == 1)
	{
		GenerateTerrainObjects(50, 2 , 40, 10);
		g_Load3ds.Import3DS(&g_3DModel, "Textures/Tilesets/Desert/Models/PILLAR.3DS");
		double Ratio = 0.25;
		O1Offset = 0.0f;
		BuildLists(Ratio, 1, g_3DModel);		
		for(int i = 0; i < g_3DModel.numOfObjects; i++)
		{
			// Free the faces, normals, vertices, and texture coordinates.
			delete [] g_3DModel.pObject[i].pFaces;
			delete [] g_3DModel.pObject[i].pNormals;
			delete [] g_3DModel.pObject[i].pVerts;
			delete [] g_3DModel.pObject[i].pTexVerts;
		}	
		
		g_Load3ds.Import3DS(&g_3DModel1, "Textures/Tilesets/Desert/Models/STATUE.3DS");
		Ratio = 0.25;
		O1Offset = 0.0f;
		BuildLists(Ratio, 2, g_3DModel1);

		// Go through all the objects in the scene
		for(int i = 0; i < g_3DModel1.numOfObjects; i++)
		{
			// Free the faces, normals, vertices, and texture coordinates.
			delete [] g_3DModel1.pObject[i].pFaces;
			delete [] g_3DModel1.pObject[i].pNormals;
			delete [] g_3DModel1.pObject[i].pVerts;
			delete [] g_3DModel1.pObject[i].pTexVerts;
		}			
	}
	else if(Select == 2)
	{		
		GenerateTerrainObjects(100, 2 , 50, 50);
		g_Load3ds.Import3DS(&g_3DModel, "Textures/Tilesets/Mountains/Models/PINE.3DS");
		double Ratio = 0.25;
		O1Offset = 15.5f;
		BuildLists(Ratio, 1, g_3DModel);		
		for(int i = 0; i < g_3DModel.numOfObjects; i++)
		{
			// Free the faces, normals, vertices, and texture coordinates.
			delete [] g_3DModel.pObject[i].pFaces;
			delete [] g_3DModel.pObject[i].pNormals;
			delete [] g_3DModel.pObject[i].pVerts;
			delete [] g_3DModel.pObject[i].pTexVerts;
		}	
		
		g_Load3ds.Import3DS(&g_3DModel1, "Textures/Tilesets/Mountains/Models/MAPLE.3DS");
		Ratio = 5.0;
		O2Offset = 0.0f;
		BuildLists(Ratio, 2, g_3DModel1);

		// Go through all the objects in the scene
		for(int i = 0; i < g_3DModel1.numOfObjects; i++)
		{
			// Free the faces, normals, vertices, and texture coordinates.
			delete [] g_3DModel1.pObject[i].pFaces;
			delete [] g_3DModel1.pObject[i].pNormals;
			delete [] g_3DModel1.pObject[i].pVerts;
			delete [] g_3DModel1.pObject[i].pTexVerts;
		}		
	}
	else if(Select == 3)
	{
		GenerateTerrainObjects(100, 2 , 50, 50);
		g_Load3ds.Import3DS(&g_3DModel, "Textures/Tilesets/Tropics/Models/TREE3.3DS");
		double Ratio = 0.5;
		O1Offset = 0.0f;
		BuildLists(Ratio, 1, g_3DModel);		
		for(int i = 0; i < g_3DModel.numOfObjects; i++)
		{
			// Free the faces, normals, vertices, and texture coordinates.
			delete [] g_3DModel.pObject[i].pFaces;
			delete [] g_3DModel.pObject[i].pNormals;
			delete [] g_3DModel.pObject[i].pVerts;
			delete [] g_3DModel.pObject[i].pTexVerts;
		}	
		
		g_Load3ds.Import3DS(&g_3DModel1, "Textures/Tilesets/Tropics/Models/PALM.3DS");
		Ratio = 0.75;
		O2Offset = 10.0f;
		BuildLists(Ratio, 2, g_3DModel1);

		// Go through all the objects in the scene
		for(int i = 0; i < g_3DModel1.numOfObjects; i++)
		{
			// Free the faces, normals, vertices, and texture coordinates.
			delete [] g_3DModel1.pObject[i].pFaces;
			delete [] g_3DModel1.pObject[i].pNormals;
			delete [] g_3DModel1.pObject[i].pVerts;
			delete [] g_3DModel1.pObject[i].pTexVerts;
		}		
	
	}
	else if(Select == 4)
	{		
		GenerateTerrainObjects(100, 2 , 75, 15);
		g_Load3ds.Import3DS(&g_3DModel, "Textures/Tilesets/Volcanic/Models/DEADTREE.3DS");
		double Ratio = 0.1;
		O1Offset = -1.0f;
		BuildLists(Ratio, 1, g_3DModel);		
		for(int i = 0; i < g_3DModel.numOfObjects; i++)
		{
			// Free the faces, normals, vertices, and texture coordinates.
			delete [] g_3DModel.pObject[i].pFaces;
			delete [] g_3DModel.pObject[i].pNormals;
			delete [] g_3DModel.pObject[i].pVerts;
			delete [] g_3DModel.pObject[i].pTexVerts;
		}	
		
		g_Load3ds.Import3DS(&g_3DModel1, "Textures/Tilesets/Volcanic/Models/TREE1.3DS");
		Ratio = 0.15;
		O2Offset = 2.0f;
		BuildLists(Ratio, 2, g_3DModel1);

		// Go through all the objects in the scene
		for(int i = 0; i < g_3DModel1.numOfObjects; i++)
		{
			// Free the faces, normals, vertices, and texture coordinates.
			delete [] g_3DModel1.pObject[i].pFaces;
			delete [] g_3DModel1.pObject[i].pNormals;
			delete [] g_3DModel1.pObject[i].pVerts;
			delete [] g_3DModel1.pObject[i].pTexVerts;
		}	
	
	}
	SurfaceCreator s1 = SurfaceCreator(HeightMap.Height_Map, HeightMap.getTerrainSize() - 1, static_cast<float>(Height), Select);
	multitextureSupported = initMultitexture();

	TriangleTree.ExpandNode(TriangleTree.root);
	Node* Current = TriangleTree.root;
	
	//Create Triangle t1	
	Vector Apex = Vector(0, 0, HeightMap.Height_Map[0][0]);
	Vector Left = Vector(0, static_cast<float>(HeightMap.getTerrainSize() - 1), HeightMap.Height_Map[0][HeightMap.getTerrainSize() - 1]);
	Vector Right = Vector(static_cast<float>(HeightMap.getTerrainSize() - 1), 0,HeightMap.Height_Map[HeightMap.getTerrainSize() - 1][0] );
	Triangle t = Triangle(Apex, Left, Right);
	for(int i = 0; i < 100; i++)
	{	
		if(PointInTriangle(Vector(Forests[i].x, Forests[i].y), Apex, Left, Right))	
		{
			t.Tree.push_back(Forests[i]);
		}
	}
	double E = CalculateError(Left, Right);		
	Current->LeftChild->BaseNeighbour = Current->RightChild;
	TriangleTree.InsertAtNode(Current->LeftChild, t, E);	

	// Create Triangle t2	
	Apex.set(static_cast<float>(HeightMap.getTerrainSize() - 1) , static_cast<float>(HeightMap.getTerrainSize() - 1), HeightMap.Height_Map[HeightMap.getTerrainSize() - 1][HeightMap.getTerrainSize() - 1]);
	Left.set(static_cast<float>(HeightMap.getTerrainSize() - 1), 0, HeightMap.Height_Map[HeightMap.getTerrainSize() - 1][0]);
	Right.set(0, static_cast<float>(HeightMap.getTerrainSize() - 1), HeightMap.Height_Map[0][HeightMap.getTerrainSize() - 1]);
	Triangle t2 = Triangle(Apex, Left, Right);	
	for(int i = 0; i < 100; i++)
	{	
		if(PointInTriangle(Vector(Forests[i].x, Forests[i].y), Apex, Left, Right))
		{
			t2.Tree.push_back(Forests[i]);
		}
	}	
	Current->RightChild->BaseNeighbour = Current->LeftChild;
	TriangleTree.InsertAtNode(Current->RightChild, t2, E);	

	LoadTGA(&SkyBoxTexture, "SkyBox/CLOUDS.tga");
	LoadGLTextures(&WaterTexture, "Textures/WATER1.bmp");
	LoadGLTextures(&SurfaceTexture , "Data/Surface.bmp");
	LoadGLTextures(&ShadowTexture  , "Data/Shadows.bmp");	
}