bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p )
{
    const btVector3* p1 = &vertices[0];
    const btVector3* p2 = &vertices[1];
    const btVector3* p3 = &vertices[2];

    btVector3 edge1( *p2 - *p1 );
    btVector3 edge2( *p3 - *p2 );
    btVector3 edge3( *p1 - *p3 );

    btVector3 p1_to_p( *p - *p1 );
    btVector3 p2_to_p( *p - *p2 );
    btVector3 p3_to_p( *p - *p3 );

    btVector3 edge1_normal( edge1.cross(normal));
    btVector3 edge2_normal( edge2.cross(normal));
    btVector3 edge3_normal( edge3.cross(normal));

    btScalar r1, r2, r3;
    r1 = edge1_normal.dot( p1_to_p );
    r2 = edge2_normal.dot( p2_to_p );
    r3 = edge3_normal.dot( p3_to_p );
    if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) ||
            ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) )
        return true;
    return false;

}
Beispiel #2
0
Vector3 Mesh::faceNormal(const Point3 &p0, const Point3 &p1, const Point3 &p2)
{
    //
    // Copy your previous (PA04) solution here.
    //
    
    // Get two edges (DOUBLE CHECK THIS)
    double e0x = p2.u.g.x - p1.u.g.x;
    double e0y = p2.u.g.y - p1.u.g.y;
    double e0z = p2.u.g.z - p1.u.g.z;

    double e1x = p1.u.g.x - p0.u.g.x;
    double e1y = p1.u.g.y - p0.u.g.y;
    double e1z = p1.u.g.z - p0.u.g.z;

    Vector3 edge0(e0x, e0y, e0z);
    Vector3 edge1(e1x, e1y, e1z);

    // Compute their cross product
    Vector3 cross = edge1.cross(edge0);

    // Find the normal
    //double magnitude = cross.mag();
    //Vector3 normal = cross / magnitude;

    return cross.normalized(); // permits template to compile cleanly
}
Beispiel #3
0
//三角形v0,v1,v2
//判断点v是不是在三角形上只需要知道 O+ Dt = (1 - u - v)V0 + uV1 + vV2
//详细讲解参照:http://www.cnblogs.com/graphics/archive/2010/08/09/1795348.html
float ORay::HitDistance(const OVector3& v0, const OVector3& v1, const OVector3& v2, OVector3* outNormal) const
{
	// Based on Fast, Minimum Storage ORay/Triangle Intersection by M鰈ler & Trumbore
	// http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
	// Calculate edge vectors
	OVector3 edge1(v1 - v0);
	OVector3 edge2(v2 - v0);

	// Calculate determinant & check backfacing
	OVector3 p( Vec3_CrossProduct( m_direction, edge2));
	float det = Vec3_Dotf( edge1, p );
	if (det >= EPSILON)
	{
		// Calculate u & v parameters and test
		OVector3 t(m_origin - v0);
		float u = Vec3_Dotf(t, p);
		if (u >= 0.0f && u <= det)
		{
			OVector3 q(Vec3_CrossProduct(t, edge1));
			float v = Vec3_Dotf( m_direction, q );
			if (v >= 0.0f && u + v <= det)
			{
				// There is an intersection, so calculate distance & optional normal
				if (outNormal)
					*outNormal = Vec3_CrossProduct(edge1, edge2);

				return Vec3_Dotf(edge2, q) / det;
			}
		}
	}

	return INFINITY;
}
Beispiel #4
0
// Add an edge from node1 to node2, and from node2 to node1, with
// the given cost. If the cost is < 0, throw a string exception.
void Graph::addEdge(int node1, int node2, double cost)
{
	if (cost < 0) {
		throw std::string("error: cost is < 0");
	}
	
	if (getCost(node1, node2) == -1.0) {
		// no edge exists yet, add them
		
		Edge edge1(cost, node2);
		Edge edge2(cost, node1);

		adjList[node1].edgeList.push_back(edge1);
		adjList[node2].edgeList.push_back(edge2);
	} else {
		// this edge already exists, just update its value
		
		auto iterator = std::find_if(std::begin(adjList[node1].edgeList),
					     std::end(adjList[node1].edgeList),
					     [&] (const Edge &edge) {
					             return edge.dest == node2;
					     });
					     
		iterator->dest = node2;
		
		iterator = std::find_if(std::begin(adjList[node2].edgeList),
					     std::end(adjList[node2].edgeList),
					     [&] (const Edge &edge) {
					             return edge.dest == node1;
					     });
					     
		iterator->dest = node1;
	}
}
double
SurfaceOverlapFacet::projected_overlap( SurfaceOverlapFacet &other_facet, CubitBoolean draw_overlap )
{
  double tmp_double = agt->ProjectedOverlap( t, other_facet.t, draw_overlap );

  if( tmp_double > 0.00 ) 
  {
    CubitVector edge0(t.e0.x, t.e0.y, t.e0.z);  
    CubitVector edge1(t.e1.x, t.e1.y, t.e1.z);  
    CubitVector normal = edge0 * edge1;
    double area_facet1 = normal.length() / 2;

    edge0.set(other_facet.t.e0.x, other_facet.t.e0.y, other_facet.t.e0.z);  
    edge1.set(other_facet.t.e1.x, other_facet.t.e1.y, other_facet.t.e1.z);  
    normal = edge0 * edge1;
    double area_facet2 = normal.length() / 2;
    
    //don't report overlapping area between facets unless it is greater 
    //than one hundredth of the area of the smaller facet
    if( area_facet1 < area_facet2 )
    {
      if( tmp_double < (area_facet1*0.01))
        tmp_double = 0.0;
    }
    else if( tmp_double < (area_facet2*0.01 ))
      tmp_double = 0.0;
  }
  return tmp_double;
}
Beispiel #6
0
float Ray::HitDistance(const Vector3& v0, const Vector3& v1, const Vector3& v2, Vector3* outNormal) const
{
    // Based on Fast, Minimum Storage Ray/Triangle Intersection by Möller & Trumbore
    // http://www.graphics.cornell.edu/pubs/1997/MT97.pdf
    // Calculate edge vectors
    Vector3 edge1(v1 - v0);
    Vector3 edge2(v2 - v0);
    
    // Calculate determinant & check backfacing
    Vector3 p(direction_.CrossProduct(edge2));
    float det = edge1.DotProduct(p);
    if (det >= M_EPSILON)
    {
        // Calculate u & v parameters and test
        Vector3 t(origin_ - v0);
        float u = t.DotProduct(p);
        if (u >= 0.0f && u <= det)
        {
            Vector3 q(t.CrossProduct(edge1));
            float v = direction_.DotProduct(q);
            if (v >= 0.0f && u + v <= det)
            {
                // There is an intersection, so calculate distance & optional normal
                if (outNormal)
                    *outNormal = edge1.CrossProduct(edge2);
                
                return edge2.DotProduct(q) / det;
            }
        }
    }
    
    return M_INFINITY;
}
Beispiel #7
0
Vector3 Mesh::faceNormal(const Point3 &p0, const Point3 &p1, const Point3 &p2)
{
    //
    // ASSIGNMENT (PA04)
    //
    // The points p0, p1, and p2 bound a triangular face in clockwise
    // order. Compute two edges, take their cross product, and
    // normalize the result to get the face normal, which you return.
    //
    // 8 lines in instructor solution (YMMV)
    //

    // Get two edges (DOUBLE CHECK THIS)
    double e0x = p2.u.g.x - p1.u.g.x;
    double e0y = p2.u.g.y - p1.u.g.y;
    double e0z = p2.u.g.z - p1.u.g.z;

    double e1x = p1.u.g.x - p0.u.g.x;
    double e1y = p1.u.g.y - p0.u.g.y;
    double e1z = p1.u.g.z - p0.u.g.z;

    Vector3 edge0(e0x, e0y, e0z);
    Vector3 edge1(e1x, e1y, e1z);

    // Compute their cross product
    Vector3 cross = edge1.cross(edge0);

    // Find the normal
    //double magnitude = cross.mag();
    //Vector3 normal = cross / magnitude;

    return cross.normalized(); // permits template to compile cleanly
}
Beispiel #8
0
void HFaceFormula::calcFaceNormal(HVertex v1, HVertex v2, HVertex v3, HNormal &n) {

	HNormal edge1(v1 - v2), 
		edge2(v2 - v3);

	n = edge1 ^ edge2; // cross product
}
Beispiel #9
0
	plane::plane(const vec3& v1, const vec3& v2, const vec3& v3)
	{
		vec3 edge1(v2 - v1);

		normal = edge1.cross(v3 - v1);
		normal.normalize();
		d = -normal.dot(v1);
	}
Graph::Graph(ifstream& file,float prime_weight)
{
	vector<pair<float, float>> vertexs;
	int i = 0;						//id
	string name;					//city name
	float lat, lon;					//latitude & longitude
	float weight;					//weight = GDP * population
	bool prime;						//whether it is a prime city
	int flag = file.is_open();
	string line;
	int hz, nj;
	while (getline(file,line))
	{
		stringstream ss;
		ss << line;
		ss >> name >> lat >> lon >> weight;
		pair<float, float> v(lat, lon);
		vertexs.push_back(v);
		if (weight > prime_weight)
			prime = true;
		else
			prime = false;
		City c(i,name, v, weight,prime);
		city.push_back(c);

		//find hangzhou and nanjing
		if (name == "杭州市")
			hz = i;
		if (name == "南京市")
			nj = i;

		i++;
	}
	//construct distances set
	//dists[{i,j}] means distance between city with id i and city with id j
	for (unsigned i = 0; i < vertexs.size(); ++i)
	{
		for (unsigned j = 0; j < vertexs.size(); ++j)
		{
			pair<int, int> edge(i, j);
			dists[edge] = dist(vertexs[i], vertexs[j]);
		}
	}
	
	express[{hz, nj}] = 1; //the amount of express from hz to nj is one car
	for (unsigned i = 0; i < vertexs.size(); ++i)
	{
		for (unsigned j = 0; j < vertexs.size(); ++j)
		{
			if (i == j) continue;
			pair<int, int> edge1(i, j);
			pair<int, int> edge2(j, i);
			express[edge1] = city[i].weight * city[j].weight / (city[hz].weight * city[nj].weight);
			express[edge2] = city[i].weight * city[j].weight / (city[hz].weight * city[nj].weight);
		}
	}
}
Beispiel #11
0
bool PolygonLine :: intersects(Element *element)
{
    printf("Warning: entering PolygonLine :: intersects(Element *element).\n");

#ifdef __BOOST_MODULE
    if ( !boundingBoxIntersects(element) ) {
        return false;
    }

    double distTol = 1.0e-9;

    int numSeg = this->giveNrVertices() - 1;


    // Loop over the crack segments and test each segment for
    // overlap with the element
    for ( int segId = 1; segId <= numSeg; segId++ ) {
        if ( element->giveGeometryType() == EGT_triangle_1 ) {
            // Crack segment
            bPoint2 crackP1( this->giveVertex ( segId )->at(1), this->giveVertex ( segId )->at(2) );
            bPoint2 crackP2( this->giveVertex ( segId + 1 )->at(1), this->giveVertex ( segId + 1 )->at(2) );
            bSeg2 crackSeg(crackP1, crackP2);


            // Triangle vertices
            bPoint2 x1( element->giveNode ( 1 )->giveCoordinate(1), element->giveNode ( 1 )->giveCoordinate(2) );
            bPoint2 x2( element->giveNode ( 2 )->giveCoordinate(1), element->giveNode ( 2 )->giveCoordinate(2) );
            bPoint2 x3( element->giveNode ( 3 )->giveCoordinate(1), element->giveNode ( 3 )->giveCoordinate(2) );

            bSeg2 edge1(x1, x2);
            bSeg2 edge2(x2, x3);
            bSeg2 edge3(x3, x1);

            double d1 = bDist(crackSeg, edge1);
            if ( d1 < distTol ) {
                return true;
            }

            double d2 = bDist(crackSeg, edge2);
            if ( d2 < distTol ) {
                return true;
            }

            double d3 = bDist(crackSeg, edge3);
            if ( d3 < distTol ) {
                return true;
            }
        }
    }



#endif

    return false;
}
Beispiel #12
0
void outer( Point3d pentagon[5], Point3d * output) {
  for(int i=0; i<5; i++) {
    Line3d edge1(pentagon[i], pentagon[(i+1)%5]);
    Line3d edge4(pentagon[(i+3)%5], pentagon[(i+4)%5]);
    Point3d* ppt = (Point3d*)edge1.intersection(edge4);
    if (!ppt) {
      std::cout << "INCORRECT!!! diagonal lines are disjoint or identical" << std::endl;
      exit(0);
    }
    output[i] = *ppt;
  }
}
Beispiel #13
0
float HFaceFormula::calcTriangleFaceArea(HVertex &_v1, HVertex &_v2, HVertex &_v3)
{
	ChapillVec3<float> v1(_v1.x, _v1.y, _v1.z), 
		v2(_v2.x, _v2.y, _v2.z), 
		v3(_v3.x, _v3.y, _v3.z);

	ChapillVec3<float> edge1(v1 - v2), 
		edge2(v2 - v3);

	ChapillVec3<float> normal = edge1 ^ edge2; // cross product

	return normal.Length() / 2;
}
Beispiel #14
0
Foam::label Foam::removePoints::countPointUsage
(
    const scalar minCos,
    boolList& pointCanBeDeleted
) const
{
    // Containers to store two edges per point:
    // -1   : not filled
    // >= 0 : edge label
    // -2   : more than two edges for point
    labelList edge0(mesh_.nPoints(), -1);
    labelList edge1(mesh_.nPoints(), -1);

    const edgeList& edges = mesh_.edges();

    forAll(edges, edgeI)
    {
        const edge& e = edges[edgeI];

        forAll(e, eI)
        {
            label pointI = e[eI];

            if (edge0[pointI] == -2)
            {
                // Already too many edges
            }
            else if (edge0[pointI] == -1)
            {
                // Store first edge using point
                edge0[pointI] = edgeI;
            }
            else
            {
                // Already one edge using point. Check second container.

                if (edge1[pointI] == -1)
                {
                    // Store second edge using point
                    edge1[pointI] = edgeI;
                }
                else
                {
                    // Third edge using point. Mark.
                    edge0[pointI] = -2;
                    edge1[pointI] = -2;
                }
            }
        }
    }
Beispiel #15
0
Cloth::Cloth(vec3Array& vertices, std::vector<unsigned int> &indices, const scalarType edgeKs, const scalarType edgeKd, const scalarType bendKs, const scalarType bendKd)
	: mVertices(vertices), mIndices(indices)
{
	std::map<clothEdge, clothPair> mBendPairs;
	for (int i = 0; i < indices.size(); i += 3){
		clothSpring s;
		s.kd = edgeKd; s.ks = edgeKs;
		s.type = EDGE;
		// Edge 1
		s.p1 = indices[i]; s.p2 = indices[i + 1];
		if (mBendPairs.find(clothEdge(s.p1, s.p2)) == mBendPairs.end()){
			s.restLen = glm::length(vertices[s.p1] - vertices[s.p2]);
			mSprings.push_back(s);
		}
		// Edge 2
		s.p1 = indices[i + 1]; s.p2 = indices[i + 2];
		if (mBendPairs.find(clothEdge(s.p1, s.p2)) == mBendPairs.end()){
			s.restLen = glm::length(vertices[s.p1] - vertices[s.p2]);
			mSprings.push_back(s);
		}
		// Edge 3
		s.p1 = indices[i + 2]; s.p2 = indices[i];
		if (mBendPairs.find(clothEdge(s.p1, s.p2)) == mBendPairs.end()){
			s.restLen = glm::length(vertices[s.p1] - vertices[s.p2]);
			mSprings.push_back(s);
		}
		
		clothEdge edge1(indices[i], indices[i + 1]);
		mBendPairs[edge1].add(indices[i + 2]);

		clothEdge edge2(indices[i + 1], indices[i + 2]);
		mBendPairs[edge2].add(indices[i]);

		clothEdge edge3(indices[i + 2], indices[i]);
		mBendPairs[edge1].add(indices[i + 1]);
	}

	std::map<clothEdge, clothPair>::iterator iter;
	for (iter = mBendPairs.begin(); iter != mBendPairs.end(); iter++){
		if (iter->second.isValid()){
			clothSpring s;
			s.kd = bendKd; s.ks = bendKs;
			s.type = BEND;
			s.p1 = iter->second.p1; s.p2 = iter->second.p2;
			s.restLen = glm::length(vertices[s.p1] - vertices[s.p2]);
			mSprings.push_back(s);
		}
	}
}
Beispiel #16
0
void HFaceFormula::calcTriangleFaceFormula(HVertex _v1, HVertex _v2, HVertex _v3)
{
	HNormal edge1(_v1 - _v2), 
		edge2(_v2 - _v3);

	HNormal normal = edge1 ^ edge2; // cross product

	normal.Normalize();

	a = normal.x;
	b = normal.y;
	c = normal.z;

	d = - (a * _v1.x + b * _v1.y + c * _v1.z);
}
Beispiel #17
0
  bool BSPTree::intersect(Ray &ray, const ISectTri &isecttri, double t_max) const 
  {
    tri_calls++;

    // This is the Möller-Trumbore method
    Vec3d direction(ray.direction);
    Vec3d edge0(isecttri.edge0);
    Vec3d edge1(isecttri.edge1);

    // Ray-triangle intersection
    Vec3d p = cross(direction, edge1);
    double a = dot(edge0, p);
    if(a > -d_eps && a < d_eps)
      return false;

    // Just delay these 
    Vec3d origin(ray.origin);
    Vec3d point0(isecttri.point0);    
    double f = 1.0/a;
    Vec3d s = origin - point0;
    double u = f*dot(s, p);
    if(u < 0.0 || u > 1.0)
      return false;

    Vec3d q = cross(s, edge0);
    double v = f*dot(direction, q);  
    if(v < 0.0 || u + v > 1.0)
      return false;

    double t = f*dot(edge1, q);
    if(t < f_eps || t*t < 1.0e-9)
      return false;
    if(t > t_max)
      return false;
    if(t > ray.dist)
      return false;
  
    ray.dist = t;
    ray.u = u;
    ray.v = v;
    ray.hit_object = (TriMesh*)isecttri.mesh_id;
    ray.hit_face_id = isecttri.tri_id;
    ray.has_hit=true;
    return true; 
  }
/**
 * Break edge into several straight line
 *
 */
void Edge::breakEdge() {
	cv::Point p0; // = contours[0];
	cv::Point pend; // = contours[contours.size() - 1];
	if (listOfPoints.size() > 0) {
		p0 = listOfPoints.at(0);
		pend = listOfPoints.at(listOfPoints.size() - 1);

		if (listOfPoints.size() > 2) {
			Line line(p0, pend);
			double distance = 0;
			double maxDistance = 0; // ??????????????????
			double imax = 0;
			for (size_t i = 1; i < listOfPoints.size()-1; i++) {
				cv::Point pointi = listOfPoints.at(i);
				distance = abs(line.perpendicularDistance(pointi));
				if (distance > maxDistance) {
					maxDistance = distance;
					imax = i;
				}
			}

			if (maxDistance > 3) {
				vector<cv::Point> part1(this->listOfPoints.begin(),
						this->listOfPoints.begin() + imax + 1);
				vector<cv::Point> part2(this->listOfPoints.begin() + imax,
						this->listOfPoints.end());
				Edge edge1(part1);
				Edge edge2(part2);
				edge1.breakEdge();
				edge2.breakEdge();
			}
		}

		if (!checkPointInList(p0))
			breakPoints.push_back(p0);
		if (!checkPointInList(pend))
			breakPoints.push_back(pend);

	} else {
		return;
	}
}
void Graph::AddEdge(int origin, int direction)
{
    bool edge_exist = false;

    for(auto edge_b = m_graph[origin].begin(), edge_e = m_graph[origin].end(); edge_b != edge_e ; ++edge_b )
    {
        if(edge_b->m_direction == direction)
        {
            edge_exist = true;
        }
    }

    if(edge_exist == false)
    {
        Edge edge1(origin, direction);
        m_graph[origin].push_back(edge1);
        edge1.Reverse();
        m_graph[direction].push_back(edge1);
    }
}
dgFloat32 dgFastRayTest::PolygonIntersect (const dgVector& faceNormal, dgFloat32 maxT, const dgFloat32* const polygon, dgInt32 strideInBytes, const dgInt32* const indexArray, dgInt32 indexCount) const
{
	dgAssert (m_p0.m_w == dgFloat32 (0.0f));
	dgAssert (m_p1.m_w == dgFloat32 (0.0f));

	if (faceNormal.DotProduct(m_unitDir).GetScalar() < dgFloat32 (0.0f)) {
		dgInt32 stride = dgInt32(strideInBytes / sizeof (dgFloat32));
		dgBigVector v0(dgVector(&polygon[indexArray[indexCount - 1] * stride]) & dgVector::m_triplexMask);
		dgBigVector p0(m_p0);
		dgBigVector p0v0(v0 - p0);

		dgBigVector diff(m_diff);
		dgBigVector normal(faceNormal);
		dgFloat64 tOut = normal.DotProduct(p0v0).GetScalar() / normal.DotProduct(diff).GetScalar();
		if ((tOut >= dgFloat64(0.0f)) && (tOut <= maxT)) {
			dgBigVector p (p0 + diff.Scale (tOut));
			dgBigVector unitDir(m_unitDir);
			for (dgInt32 i = 0; i < indexCount; i++) {
				dgInt32 i2 = indexArray[i] * stride;
				dgBigVector v1(dgVector(&polygon[i2]) & dgVector::m_triplexMask);

				dgBigVector edge0(p - v0);
				dgBigVector edge1(v1 - v0);
				dgFloat64 area = unitDir.DotProduct (edge0.CrossProduct(edge1)).GetScalar();
				if (area < dgFloat32 (0.0f)) {
					return 1.2f;
				}
				v0 = v1;
			}

			return dgFloat32(tOut);
		}
	}

	return dgFloat32 (1.2f);
}
Beispiel #21
0
void main()
{
	glfwInit();

	// Creates a window
	window = glfwCreateWindow(800, 800, "OBB - Plane Collision Detection", nullptr, nullptr);
	glfwMakeContextCurrent(window);
	glfwSwapInterval(0);

	// Initializes most things needed before the main loop
	init();

	//Generate box mesh
	struct Vertex boxVerts[24];
	boxVerts[0] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner
	boxVerts[1] = { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner

	boxVerts[2] = { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner
	boxVerts[3] = { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner

	boxVerts[4] = { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner
	boxVerts[5] = { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner

	boxVerts[6] = { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner
	boxVerts[7] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner


	boxVerts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner
	boxVerts[9] = { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Top Back Left Corner

	boxVerts[10] = { -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner
	boxVerts[11] = { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Top Front Left Corner

	boxVerts[12] = { 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner
	boxVerts[13] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Top Front Right Corner

	boxVerts[14] = { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner
	boxVerts[15] = { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Top Back Right Corner


	boxVerts[16] = { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner
	boxVerts[17] = { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner

	boxVerts[18] = { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Left Corner
	boxVerts[19] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner

	boxVerts[20] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Front Right Corner
	boxVerts[21] = { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner

	boxVerts[22] = { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Right Corner
	boxVerts[23] = { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f };	//Bottom Back Left Corner

	box = new struct Mesh(24, boxVerts, GL_LINES);

	//Scale the box
	box->scale = box->scale * glm::scale(glm::mat4(1.0f), glm::vec3(0.1f, 0.1f, 0.1f));

	//Translate the box
	box->translation = glm::translate(box->translation, glm::vec3(-0.1f, 0.0f, 0.0f));


	//Generate the Plane mesh
	struct Vertex planeVerts[6];
	planeVerts[0] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[1] = { 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[2] = { 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[3] = { 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[4] = { 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[5] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };

	plane = new struct Mesh(6, planeVerts, GL_TRIANGLES);

	//Scale the plane
	plane->scale = plane->scale * glm::scale(glm::mat4(1.0f), glm::vec3(5.0f, 5.0f, 5.0f));

	//Translate the plane
	plane->translation = glm::translate(plane->translation, glm::vec3(0.1f, 0.0f, 0.0f));

	//Set the selected shape
	selectedShape = plane;

	//Generate the colliders
	boxCollider = new struct OBB(boxVerts[3].x - boxVerts[2].x, boxVerts[9].y - boxVerts[8].y, boxVerts[1].z - boxVerts[0].z);

	//Get two edges of the plane and take the cross product for the normal (Or just hardcode it, for example we know the normal to this plane
	//Will be the Z axis, because the plane mesh lies in the XY Plane to start.
	glm::vec3 edge1(planeVerts[0].x - planeVerts[1].x, planeVerts[0].y - planeVerts[1].y, planeVerts[0].z - planeVerts[1].z);
	glm::vec3 edge2(planeVerts[1].x - planeVerts[2].x, planeVerts[1].y - planeVerts[2].y, planeVerts[1].z - planeVerts[2].z);

	glm::vec3 normal = glm::normalize(glm::cross(edge1, edge2));
	
	planeCollider = new struct Plane(normal);

	//Print controls
	std::cout << "Use WASD to move the selected shape in the XY plane.\nUse left CTRL & left shift to move the selected shape along Z axis.\n";
	std::cout << "Left click and drag the mouse to rotate the selected shape.\nUse spacebar to swap the selected shape.\n";

	// Enter the main loop.
	while (!glfwWindowShouldClose(window))
	{
		// Call to update() which will update the gameobjects.
		update();

		// Call the render function.
		renderScene();

		// Swaps the back buffer to the front buffer
		glfwSwapBuffers(window);

		// Checks to see if any events are pending and then processes them.
		glfwPollEvents();
	}

	// After the program is over, cleanup your data!
	glDeleteShader(vertex_shader);
	glDeleteShader(fragment_shader);
	glDeleteProgram(program);
	// Note: If at any point you stop using a "program" or shaders, you should free the data up then and there.

	delete box;
	delete plane;

	delete boxCollider;
	delete planeCollider;

	// Frees up GLFW memory
	glfwTerminate();
}
Beispiel #22
0
    bool CTriangulation::Triangulate(vector<CEdgeLoop> &tri_faces, CRegion& region)
    {
		
		vector<CEdge> regionEdges;
		for(EdgeArray::iterator ol_it = region.OuterLoops.Edges.begin();ol_it != region.OuterLoops.Edges.end();ol_it++)
		{
			regionEdges.push_back(*ol_it);
		}

		for(vector<CEdgeLoop>::iterator il_it1 = region.InnerLoops.begin();il_it1 != region.InnerLoops.end();il_it1++)
		{
			CEdgeLoop currentInnerLoop = *il_it1;
			for(EdgeArray::iterator il_it2 = currentInnerLoop.Edges.begin();il_it2 != currentInnerLoop.Edges.end();il_it2++)
			{
				regionEdges.push_back(*il_it2);
			}
		}

		


		while(regionEdges.size() > 3)
		{
			vector<vec2> candidatePoints;
			for(int i = 1;i<regionEdges.size();i++)
			{
				if (CMathUtility::ToLeftExcludeOnLine(regionEdges[i].End,regionEdges[0]))
				{
					int k = 0;
					for(k = 1;k<regionEdges.size();k++)
					{
						CEdge edge1(regionEdges[0].Start,regionEdges[i].End);
						edge1.Commit();

						CEdge edge2(regionEdges[0].End,regionEdges[i].End);
						edge2.Commit();

                        //???????
						if(edge1.IsIntersectWith2(regionEdges[k]) || edge2.IsIntersectWith2(regionEdges[k]))
						{
							break;
						}
					}
					if(k == regionEdges.size())
					{
						candidatePoints.push_back(regionEdges[i].End);
					}


				}
			}

			double minR = MAXDWORD;
			vec2 LO2;

			
			for(int j = 0;j<candidatePoints.size();j++)
			{
				double r =CMathUtility::MinR(regionEdges[0].Start,regionEdges[0].End,candidatePoints[j]);
				if(r < minR)
				{
					minR = r;
					LO2 = candidatePoints[j];
				}

			}

			CEdgeLoop tmpTriangel;
			tmpTriangel.Edges.push_back(regionEdges[0]);
			CEdge tmpEdge1(regionEdges[0].End,LO2);
			tmpEdge1.Commit();
			tmpTriangel.Edges.push_back(tmpEdge1);
			CEdge tmpEdge2(LO2,regionEdges[0].Start);
			tmpEdge2.Commit();
			tmpTriangel.Edges.push_back(tmpEdge2);
			tmpTriangel.Commit();

			vector<vec2> newCandidatePoints;
            for(int m = 0;m<candidatePoints.size();m++)
			{
				if(CMathUtility::IsCanExistInCircle(candidatePoints[m],tmpTriangel))
				{
					newCandidatePoints.push_back(candidatePoints[m]);
				}

			}

			while (!newCandidatePoints.size() ==0)
			{
				minR=MAXDWORD;
				for(int m = 0;m < newCandidatePoints.size();m++)
				{
					double r=CMathUtility::MinR(regionEdges[0].Start,regionEdges[0].End,newCandidatePoints[m]);
					if(r < minR)
					{
						minR = r;
						LO2 = newCandidatePoints[m];
					}

				}
				
				tmpTriangel.Edges.clear();
				tmpTriangel.Edges.push_back(regionEdges[0]);
				tmpEdge1.Start = regionEdges[0].End;
				tmpEdge1.End = LO2;
				tmpTriangel.Edges.push_back(tmpEdge1);
				tmpEdge2.Start = LO2;
				tmpEdge2.End = regionEdges[0].Start;
				tmpTriangel.Edges.push_back(tmpEdge2);
				tmpTriangel.Commit();

				newCandidatePoints.clear();
				for (int j = 0;j<candidatePoints.size();j++)
				{
					if (CMathUtility::IsCanExistInCircle(candidatePoints[j],tmpTriangel))
					{
						newCandidatePoints.push_back(candidatePoints[j]);
					}
				}

			}

			tri_faces.push_back(tmpTriangel);

			CEdge L11_LO2(regionEdges[0].Start,LO2);
			L11_LO2.isBoundEdge = false;
			L11_LO2.Commit();
			CEdge L12_LO2(LO2,regionEdges[0].End);
			L12_LO2.isBoundEdge =false;
			L12_LO2.Commit();

			int pos_m = 0;
			int pos_n = 0;

			if(CMathUtility::IsBoundEdge(regionEdges,L11_LO2,pos_m))
			{
				L11_LO2.isBoundEdge = true;
			}
			if(CMathUtility::IsBoundEdge(regionEdges,L12_LO2,pos_n))
			{
				L12_LO2.isBoundEdge = true;
			}

			if(!L11_LO2.isBoundEdge && !L12_LO2.isBoundEdge)
			{
				CEdge tmpEdge(L12_LO2.Start,L12_LO2.End);
				tmpEdge.Commit();
				regionEdges.push_back(tmpEdge);
				regionEdges[0].End = LO2;
				regionEdges[0].Commit();
			}
			if(L11_LO2.isBoundEdge && !L12_LO2.isBoundEdge)
			{
				regionEdges[0].Start = LO2;
				regionEdges[0].Commit();
				regionEdges[pos_m] = regionEdges[regionEdges.size()-1];
				regionEdges.pop_back();
			}
			if(!L11_LO2.isBoundEdge && L12_LO2.isBoundEdge)
			{
				regionEdges[0].End = LO2;
				regionEdges[0].Commit();
				regionEdges[pos_n] = regionEdges[regionEdges.size()-1];
				regionEdges.pop_back();
			}
			if(L11_LO2.isBoundEdge && L12_LO2.isBoundEdge)
			{
				if (pos_n>pos_m)
				{
					regionEdges[pos_n] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();

					regionEdges[pos_m] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();
					
					regionEdges[0] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();
				}
				else
				{
					regionEdges[pos_m] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();

					regionEdges[pos_n] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();

					regionEdges[0] = regionEdges[regionEdges.size()-1];
					regionEdges.pop_back();

				}

			}

		}

        // TODO
		if(regionEdges.size()==3)
		{
			CEdgeLoop tmpTriangle;
			tmpTriangle.Edges.push_back(regionEdges[0]);
			tmpTriangle.Edges.push_back(regionEdges[1]);
			tmpTriangle.Edges.push_back(regionEdges[2]);
			tmpTriangle.Commit();
			tri_faces.push_back(tmpTriangle);
		}
        return true;
    }
void ellipseTransform(QPointF p1, QPointF p2, qreal rx, qreal ry, int largeFlag, int sweepFlag, int angel,
						qreal* startAngle, qreal *sweepLength, QRectF *rect){
	qreal r1 = (p1.x() - p2.x()) / (2.f * rx);
	qreal r2 = (p2.y() - p1.y()) / (2.f * ry);

	qreal tmp = atan(r1 / r2);
	qreal a1s[2] = { tmp, -tmp };
	
	tmp = asin(sqrt(r1*r1 + r2*r2));
	qreal a2s[2] = { tmp, -tmp };
	qreal x, y, t1, t2;

	qreal rrmin = rx*rx;
	qreal rrmax = ry*ry;
	if (rrmin > rrmax){
		tmp = rrmin;
		rrmin = rrmax;
		rrmax = tmp;
	}
	for (int i = 0; i < 2;i++)
	{
		qreal a1 = a1s[i];
		bool isBreak = false;
		for (int j = 0; j < 2; j++)
		{
			qreal a2 = a2s[j];
			t1 = a1 + a2;
			t2 = a1 - a2;
			x = p1.x() - rx*cos(t1);
			y = p1.y() - ry*sin(t1);

			qreal check1 = (p1.x() - x)*(p1.x() - x) / (rx*rx) + (p1.y() - y)*(p1.y() - y) / (ry*ry);
			qreal check2 = (p2.x() - x)*(p2.x() - x) / (rx*rx) + (p2.y() - y)*(p2.y() - y) / (ry*ry);
			
			if ( fabs(check1-1) < 1.e-6 && fabs(check2-1) < 1.e-6)
			{
				isBreak = true;
				break;
			}
		
		}
		if (isBreak)	break;
	}

	QVector3D edge1(x - p1.x(), y - p1.y(),0);
	QVector3D edge2(p2.x() - x, p2.y() - y,0);

	QVector3D cross = QVector3D::crossProduct(edge1,edge2);
	

	bool isCw = cross.z() > 0;
	if (isCw != (largeFlag == sweepFlag))
	{
		QPointF centerOfp1p2 = (p1 + p2) / 2.f;
		x = centerOfp1p2.x() * 2 - x;
		y = centerOfp1p2.y() * 2 - y;

		/*x = x0 + a * cos(t)
		y = y0 + b * sin(t)*/

		
	}


	*rect = QRect(x - rx, y - ry, rx * 2, ry * 2);

	t1 = atan2((p1.y() - y) / ry, (p1.x() - x) / rx);
	t2 = atan2((p2.y() - y) / ry, (p2.x() - x) / rx);

	*startAngle = t1 * 180 / PI;
	*startAngle = -*startAngle;
	*sweepLength = t2 * 180 / PI;
	*sweepLength = -*sweepLength;
	*sweepLength -= *startAngle;

	if ((largeFlag && fabs(*sweepLength) < 180) || (!largeFlag && fabs(*sweepLength) > 180))
	{
		if (*sweepLength < 0)
			*sweepLength = -360 - *sweepLength;
		else
			*sweepLength = 360 - *sweepLength;
	}

	if ((!sweepFlag && *sweepLength <0) || (sweepFlag && *sweepLength >0))
	{
		*sweepLength = -*sweepLength;
	}

	/*if (!isCw)
	{
		*sweepLength = fabs(*sweepLength);
	}*/
	
}
hacd::HaI32 dgPolygonSoupDatabaseBuilder::FilterFace (hacd::HaI32 count, hacd::HaI32* const pool)
{
	if (count == 3) {
		dgBigVector p0 (m_vertexPoints[pool[2]]);
		for (hacd::HaI32 i = 0; i < 3; i ++) {
			dgBigVector p1 (m_vertexPoints[pool[i]]);
			dgBigVector edge (p1 - p0);
			hacd::HaF64 mag2 = edge % edge;
			if (mag2 < hacd::HaF32 (1.0e-6f)) {
				count = 0;
			}
			p0 = p1;
		}

		if (count == 3) {
			dgBigVector edge0 (m_vertexPoints[pool[2]] - m_vertexPoints[pool[0]]);
			dgBigVector edge1 (m_vertexPoints[pool[1]] - m_vertexPoints[pool[0]]);
			dgBigVector normal (edge0 * edge1);
			hacd::HaF64 mag2 = normal % normal;
			if (mag2 < hacd::HaF32 (1.0e-8f)) {
				count = 0;
			}
		}
	} else {
	dgPolySoupFilterAllocator polyhedra;

	count = polyhedra.AddFilterFace (hacd::HaU32 (count), pool);

	if (!count) {
		return 0;
	}

	dgEdge* edge = &polyhedra.GetRoot()->GetInfo();
	if (edge->m_incidentFace < 0) {
		edge = edge->m_twin;
	}

	bool flag = true;
	while (flag) {
		flag = false;
		if (count >= 3) {
			dgEdge* ptr = edge;

			dgBigVector p0 (&m_vertexPoints[ptr->m_incidentVertex].m_x);
			do {
				dgBigVector p1 (&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x);
				dgBigVector e0 (p1 - p0);
				hacd::HaF64 mag2 = e0 % e0;
				if (mag2 < hacd::HaF32 (1.0e-6f)) {
					count --;
					flag = true;
					edge = ptr->m_next;
					ptr->m_prev->m_next = ptr->m_next;
					ptr->m_next->m_prev = ptr->m_prev;
					ptr->m_twin->m_next->m_prev = ptr->m_twin->m_prev;
					ptr->m_twin->m_prev->m_next = ptr->m_twin->m_next;
					break;
				}
				p0 = p1;
				ptr = ptr->m_next;
			} while (ptr != edge);
		}
	}
	if (count >= 3) {
		flag = true;
		dgBigVector normal (polyhedra.FaceNormal (edge, &m_vertexPoints[0].m_x, sizeof (dgBigVector)));

		HACD_ASSERT ((normal % normal) > hacd::HaF32 (1.0e-10f)); 
		normal = normal.Scale (dgRsqrt (normal % normal + hacd::HaF32 (1.0e-20f)));

		while (flag) {
			flag = false;
			if (count >= 3) {
				dgEdge* ptr = edge;

				dgBigVector p0 (&m_vertexPoints[ptr->m_prev->m_incidentVertex].m_x);
				dgBigVector p1 (&m_vertexPoints[ptr->m_incidentVertex].m_x);
				dgBigVector e0 (p1 - p0);
				e0 = e0.Scale (dgRsqrt (e0 % e0 + hacd::HaF32(1.0e-10f)));
				do {
					dgBigVector p2 (&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x);
					dgBigVector e1 (p2 - p1);

					e1 = e1.Scale (dgRsqrt (e1 % e1 + hacd::HaF32(1.0e-10f)));
					hacd::HaF64 mag2 = e1 % e0;
					if (mag2 > hacd::HaF32 (0.9999f)) {
						count --;
						flag = true;
						edge = ptr->m_next;
						ptr->m_prev->m_next = ptr->m_next;
						ptr->m_next->m_prev = ptr->m_prev;
						ptr->m_twin->m_next->m_prev = ptr->m_twin->m_prev;
						ptr->m_twin->m_prev->m_next = ptr->m_twin->m_next;
						break;
					}

					dgBigVector n (e0 * e1);
					mag2 = n % normal;
					if (mag2 < hacd::HaF32 (1.0e-5f)) {
						count --;
						flag = true;
						edge = ptr->m_next;
						ptr->m_prev->m_next = ptr->m_next;
						ptr->m_next->m_prev = ptr->m_prev;
						ptr->m_twin->m_next->m_prev = ptr->m_twin->m_prev;
						ptr->m_twin->m_prev->m_next = ptr->m_twin->m_next;
						break;
					}

					e0 = e1;
					p1 = p2;
					ptr = ptr->m_next;
				} while (ptr != edge);
			}
		}
	}

	dgEdge* first = edge;
	if (count >= 3) {
		hacd::HaF64 best = hacd::HaF32 (2.0f);
		dgEdge* ptr = edge;

		dgBigVector p0 (&m_vertexPoints[ptr->m_incidentVertex].m_x);
		dgBigVector p1 (&m_vertexPoints[ptr->m_next->m_incidentVertex].m_x);
		dgBigVector e0 (p1 - p0);
		e0 = e0.Scale (dgRsqrt (e0 % e0 + hacd::HaF32(1.0e-10f)));
		do {
			dgBigVector p2 (&m_vertexPoints[ptr->m_next->m_next->m_incidentVertex].m_x);
			dgBigVector e1 (p2 - p1);

			e1 = e1.Scale (dgRsqrt (e1 % e1 + hacd::HaF32(1.0e-10f)));
			hacd::HaF64 mag2 = fabs (e1 % e0);
			if (mag2 < best) {
				best = mag2;
				first = ptr;
			}

			e0 = e1;
			p1 = p2;
			ptr = ptr->m_next;
		} while (ptr != edge);

		count = 0;
		ptr = first;
		do {
			pool[count] = ptr->m_incidentVertex;
			count ++;
			ptr = ptr->m_next;
		} while (ptr != first);
	}

#ifdef _DEBUG
	if (count >= 3) {
		hacd::HaI32 j0 = count - 2;  
		hacd::HaI32 j1 = count - 1;  
		dgBigVector normal (polyhedra.FaceNormal (edge, &m_vertexPoints[0].m_x, sizeof (dgBigVector)));
		for (hacd::HaI32 j2 = 0; j2 < count; j2 ++) { 
			dgBigVector p0 (&m_vertexPoints[pool[j0]].m_x);
			dgBigVector p1 (&m_vertexPoints[pool[j1]].m_x);
			dgBigVector p2 (&m_vertexPoints[pool[j2]].m_x);
			dgBigVector e0 ((p0 - p1));
			dgBigVector e1 ((p2 - p1));

			dgBigVector n (e1 * e0);
			HACD_ASSERT ((n % normal) > hacd::HaF32 (0.0f));
			j0 = j1;
			j1 = j2;
		}
	}
#endif
	}

	return (count >= 3) ? count : 0;
}
void dgPolygonSoupDatabaseBuilder::AddMesh (const hacd::HaF32* const vertex, hacd::HaI32 vertexCount, hacd::HaI32 strideInBytes, hacd::HaI32 faceCount,	
	const hacd::HaI32* const faceArray, const hacd::HaI32* const indexArray, const hacd::HaI32* const faceTagsData, const dgMatrix& worldMatrix) 
{
	hacd::HaI32 faces[256];
	hacd::HaI32 pool[2048];


	m_vertexPoints[m_vertexCount + vertexCount].m_x = hacd::HaF64 (0.0f);
	dgBigVector* const vertexPool = &m_vertexPoints[m_vertexCount];

	worldMatrix.TransformTriplex (&vertexPool[0].m_x, sizeof (dgBigVector), vertex, strideInBytes, vertexCount);
	for (hacd::HaI32 i = 0; i < vertexCount; i ++) {
		vertexPool[i].m_w = hacd::HaF64 (0.0f);
	}

	hacd::HaI32 totalIndexCount = faceCount;
	for (hacd::HaI32 i = 0; i < faceCount; i ++) {
		totalIndexCount += faceArray[i];
	}

	m_vertexIndex[m_indexCount + totalIndexCount] = 0;
	m_faceVertexCount[m_faceCount + faceCount] = 0;

	hacd::HaI32 k = 0;
	for (hacd::HaI32 i = 0; i < faceCount; i ++) {
		hacd::HaI32 count = faceArray[i];
		for (hacd::HaI32 j = 0; j < count; j ++) {
			hacd::HaI32 index = indexArray[k];
			pool[j] = index + m_vertexCount;
			k ++;
		}

		hacd::HaI32 convexFaces = 0;
		if (count == 3) {
			convexFaces = 1;
			dgBigVector p0 (m_vertexPoints[pool[2]]);
			for (hacd::HaI32 i = 0; i < 3; i ++) {
				dgBigVector p1 (m_vertexPoints[pool[i]]);
				dgBigVector edge (p1 - p0);
				hacd::HaF64 mag2 = edge % edge;
				if (mag2 < hacd::HaF32 (1.0e-6f)) {
					convexFaces = 0;
				}
				p0 = p1;
			}

			if (convexFaces) {
				dgBigVector edge0 (m_vertexPoints[pool[2]] - m_vertexPoints[pool[0]]);
				dgBigVector edge1 (m_vertexPoints[pool[1]] - m_vertexPoints[pool[0]]);
				dgBigVector normal (edge0 * edge1);
				hacd::HaF64 mag2 = normal % normal;
				if (mag2 < hacd::HaF32 (1.0e-8f)) {
					convexFaces = 0;
				}
			}

			if (convexFaces) {
				faces[0] = 3;
			}

		} else {
			convexFaces = AddConvexFace (count, pool, faces);
		}

		hacd::HaI32 index = 0;
		for (hacd::HaI32 k = 0; k < convexFaces; k ++) {
			hacd::HaI32 count = faces[k];
			m_vertexIndex[m_indexCount] = faceTagsData[i];
			m_indexCount ++;
			for (hacd::HaI32 j = 0; j < count; j ++) {
				m_vertexIndex[m_indexCount] = pool[index];
				index ++;
				m_indexCount ++;
			}
			m_faceVertexCount[m_faceCount] = count + 1;
			m_faceCount ++;
		}
	}
	m_vertexCount += vertexCount;
	m_run -= vertexCount;
	if (m_run <= 0) {
		PackArray();
	}
}
Beispiel #26
0
	Subdivide (int _vertexCount, glm::vec3* _vertices, int _triangleCount, glm::ivec3* _triangles, int _subCount)
		:vertexCount(_vertexCount), triangleCount(_triangleCount * _subCount * _subCount), subCount(_subCount)
	{
		vertices.resize(vertexCount);
		triangles.resize(triangleCount);
		for (int i = 0; i < vertexCount; ++i){
			vertices[i] = _vertices[i];
		}
		std::map<SubdivideEdge, std::vector<int> > edgeMap;
		int triIndex = 0;
		for (int i = 0; i < _triangleCount; ++i){
			std::vector<int> triIndices;
			// Edge 1
			SubdivideEdge edge1(_triangles[i].x, _triangles[i].y);
			if (edgeMap.find(edge1) == edgeMap.end()){
				glm::vec3 vertexGap = (vertices[edge1.e2] - vertices[edge1.e1]) / (float)subCount;
				for (int i = 1; i < subCount; ++i){
					vertices.push_back(vertices[edge1.e1] + vertexGap * (float)i);
					edgeMap[edge1].push_back(vertexCount++);
				}
			}
			if (edge1.isExchanged){
				triIndices.push_back(edge1.e2);
				const std::vector<int>& tmpI = edgeMap[edge1];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[tmpI.size() - i - 1]);
				}
			}else{
				triIndices.push_back(edge1.e1);
				const std::vector<int>& tmpI = edgeMap[edge1];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[i]);
				}
			}
			// Edge 2
			SubdivideEdge edge2(_triangles[i].y, _triangles[i].z);
			if (edgeMap.find(edge2) == edgeMap.end()){
				glm::vec3 vertexGap = (vertices[edge2.e2] - vertices[edge2.e1]) / (float)subCount;
				for (int i = 1; i < subCount; ++i){
					vertices.push_back(vertices[edge2.e1] + vertexGap * (float)i);
					edgeMap[edge2].push_back(vertexCount++);
				}
			}
			if (edge2.isExchanged){	
				triIndices.push_back(edge2.e2);
				const std::vector<int>& tmpI = edgeMap[edge2];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[tmpI.size() - i - 1]);
				}			
			}else{			
				triIndices.push_back(edge2.e1);
				const std::vector<int>& tmpI = edgeMap[edge2];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[i]);
				}
			}
			// Edge 3
			SubdivideEdge edge3(_triangles[i].z, _triangles[i].x);
			if (edgeMap.find(edge3) == edgeMap.end()){
				glm::vec3 vertexGap = (vertices[edge3.e2] - vertices[edge3.e1]) / (float)subCount;
				for (int i = 1; i < subCount; ++i){
					vertices.push_back(vertices[edge3.e1] + vertexGap * (float)i);
					edgeMap[edge3].push_back(vertexCount++);
				}
			}
			if (edge3.isExchanged){
				triIndices.push_back(edge3.e2);
				const std::vector<int>& tmpI = edgeMap[edge3];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[tmpI.size() - i - 1]);
				}
			}else{
				triIndices.push_back(edge3.e1);
				const std::vector<int>& tmpI = edgeMap[edge3];
				for (int i = 0; i < tmpI.size(); ++i){
					triIndices.push_back(tmpI[i]);
				}
			}

			// Limit the subCount to [2, 5]
			subCount = subCount < 2 ? 2 : subCount;
			subCount = subCount > 5 ? 5 : subCount;

			// Create vertices inner triangle
			int currTriIndicesCnt = triIndices.size();
			for (int step = 2; step < subCount; ++step){
				glm::vec3 vertexGap = (vertices[triIndices[currTriIndicesCnt - step]] - vertices[triIndices[step]]) / (float)step;
				for (int i = 1; i < step; ++i){
					vertices.push_back(vertices[triIndices[step]] + vertexGap * (float)i);
					triIndices.push_back(vertexCount++);
				}
			}

			// Create triangle index
			int size = subCount * subCount;
			for (int i = 0; i < size; i++){
				triangles[triIndex++] = glm::ivec3(triIndices[subDivideMap[subCount][i * 3]],
												   triIndices[subDivideMap[subCount][i * 3 + 1]],
												   triIndices[subDivideMap[subCount][i * 3 + 2]]);
			}
		}
	}
Beispiel #27
0
void main()
{
	glfwInit();

	// Creates a window
	window = glfwCreateWindow(800, 800, "Point - Plane Collision Detection", nullptr, nullptr);
	glfwMakeContextCurrent(window);
	glfwSwapInterval(0);

	// Initializes most things needed before the main loop
	init();



	//Generate the Plane1 mesh
	struct Vertex planeVerts[6];
	planeVerts[0] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[1] = { 0.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[2] = { 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[3] = { 0.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[4] = { 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
	planeVerts[5] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };

	plane = new struct Mesh(6, planeVerts, GL_TRIANGLES);

	//Translate the plane
	plane->translation = glm::translate(plane->translation, glm::vec3(0.15f, 0.0f, 0.0f));

	//Generate point mesh
	struct Vertex pointVert = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };

	point = new struct Mesh(1, &pointVert, GL_POINTS);

	//Translate the plane
	point->translation = glm::translate(point->translation, glm::vec3(-0.15f, 0.0f, 0.0f));

	//Set the selected shape
	selectedShape = plane;

	//Generate plane collider

	//Get two edges of the plane and take the cross product for the normal (Or just hardcode it, for example we know the normal to this plane
	//Will be the Z axis, because the plane mesh lies in the XY Plane to start.
	glm::vec3 edge1(planeVerts[0].x - planeVerts[1].x, planeVerts[0].y - planeVerts[1].y, planeVerts[0].z - planeVerts[1].z);
	glm::vec3 edge2(planeVerts[1].x - planeVerts[2].x, planeVerts[1].y - planeVerts[2].y, planeVerts[1].z - planeVerts[2].z);

	glm::vec3 normal = glm::normalize(glm::cross(edge1, edge2));

	planeCollider = new struct Plane(normal);

	//Print controls
	std::cout << "Use WASD to move the selected shape in the XY plane.\nUse left CTRL & left shift to move the selected shape along Z axis.\n";
	std::cout << "Left click and drag the mouse to rotate the selected shape.\nUse spacebar to swap the selected shape.\n";

	// Enter the main loop.
	while (!glfwWindowShouldClose(window))
	{
		// Call to update() which will update the gameobjects.
		update();

		// Call the render function.
		renderScene();

		// Swaps the back buffer to the front buffer
		glfwSwapBuffers(window);

		// Checks to see if any events are pending and then processes them.
		glfwPollEvents();
	}

	// After the program is over, cleanup your data!
	glDeleteShader(vertex_shader);
	glDeleteShader(fragment_shader);
	glDeleteProgram(program);

	delete plane;
	delete point;

	delete planeCollider;

	// Frees up GLFW memory
	glfwTerminate();
}
Beispiel #28
0
  /*
    Convert tets and pyramids next to close (identified) points into prisms
  */
  void MakePrismsClosePoints (Mesh & mesh)
  {
    int i, j, k;
    for (i = 1; i <= mesh.GetNE(); i++)
      {
	Element & el = mesh.VolumeElement(i);
	if (el.GetType() == TET)
	  {
	    for (j = 1; j <= 3; j++)
	      for (k = j+1; k <= 4; k++)
		{
		  INDEX_2 edge(el.PNum(j), el.PNum(k));
		  edge.Sort();
		  if (mesh.GetIdentifications().GetSymmetric (el.PNum(j), el.PNum(k)))
		    {
		      int pi3 = 1, pi4 = 1;
		      while (pi3 == j || pi3 == k) pi3++;
		      pi4 = 10 - j - k - pi3;
		    
		      int p3 = el.PNum(pi3);
		      int p4 = el.PNum(pi4);
		    
		      el.SetType(PRISM);
		      el.PNum(1) = edge.I1();
		      el.PNum(2) = p3;
		      el.PNum(3) = p4;
		      el.PNum(4) = edge.I2();
		      el.PNum(5) = p3;
		      el.PNum(6) = p4;
		    }
		}
	  }

	if (el.GetType() == PYRAMID)
	  {
	    // pyramid, base face = 1,2,3,4
	  
	    for (j = 0; j <= 1; j++)
	      {
		int pi1 = el.PNum( (j+0) % 4 + 1);
		int pi2 = el.PNum( (j+1) % 4 + 1);
		int pi3 = el.PNum( (j+2) % 4 + 1);
		int pi4 = el.PNum( (j+3) % 4 + 1);
		int pi5 = el.PNum(5);

		INDEX_2 edge1(pi1, pi4);
		INDEX_2 edge2(pi2, pi3);
		edge1.Sort();
		edge2.Sort();
		if (mesh.GetIdentifications().GetSymmetric (pi1, pi4) &&
		    mesh.GetIdentifications().GetSymmetric (pi2, pi3))
		  {
		    //int p3 = el.PNum(pi3);
		    //int p4 = el.PNum(pi4);
		  
		    el.SetType(PRISM);
		    el.PNum(1) = pi1;
		    el.PNum(2) = pi2;
		    el.PNum(3) = pi5;
		    el.PNum(4) = pi4;
		    el.PNum(5) = pi3;
		    el.PNum(6) = pi5;
		  }
	      }
	  }
      }
  
    for (i = 1; i <= mesh.GetNSE(); i++)
      {
	Element2d & el = mesh.SurfaceElement(i);
	if (el.GetType() != TRIG) continue;

	for (j = 1; j <= 3; j++)
	  {
	    k = (j % 3) + 1;
	    INDEX_2 edge(el.PNum(j), el.PNum(k));
	    edge.Sort();

	    if (mesh.GetIdentifications().GetSymmetric (el.PNum(j), el.PNum(k)))
	      {
		int pi3 = 6-j-k;
		int p3 = el.PNum(pi3);
		int p1 = el.PNum(j);
		int p2 = el.PNum(k);

		el.SetType(QUAD);
		el.PNum(1) = p2;
		el.PNum(2) = p3;
		el.PNum(3) = p3;
		el.PNum(4) = p1;
	      }
	  }
      }
  }
bool DivideAndConquerFor3DCH::RayTriangleIntersection( Ray r, TRIANGLE triangle, const vector<VERTEX*>* pVertex )
{
    VERTEX* pointOne = (*pVertex)[ triangle.p1.pointOneIndex ];
    VERTEX* pointTwo = (*pVertex)[ triangle.p2.pointTwoIndex ];
    VERTEX* pointThree = (*pVertex)[ triangle.p3.pointThreeIndex ];

    D3DXVECTOR3 edge1( pointTwo->x - pointOne->x, pointTwo->y - pointOne->y, pointTwo->z - pointOne->z );
    D3DXVECTOR3 edge2( pointThree->x - pointOne->x, pointThree->y - pointOne->y, pointThree->z - pointOne->z );

    D3DXVECTOR3 triNormal;
    D3DXVec3Cross( &triNormal, &edge1, &edge2 );
    D3DXVec3Normalize( &triNormal, &triNormal );
    double denominator = D3DXVec3Dot( &triNormal, &r.direction );

    // Ray parallels to the plane
    if( fabs( denominator ) < 0.000001 )
    {
        return false;
    }

    double d = triNormal.x * pointOne->x + triNormal.y * pointOne->y + triNormal.z * pointOne->z;
    double t = ( d - D3DXVec3Dot( &triNormal, &r.position ) ) / denominator;

    // Trianle behine the ray
    if( t <= 0 )
    {
        return false;
    }

    D3DXVECTOR3 intersectPoint = r.position + t * r.direction;

    //D3DXVECTOR3 tmp;
    //D3DXVec3Cross( &tmp, &edge1, &edge2 );
    //double totalAmount = D3DXVec3Dot( &tmp, &triNormal );
    //double totalArea = D3DXVec3Length( &tmp ) * 0.5;

    //VERTEX tmpV = pointThree - pointTwo;
    //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointTwo.x, intersectPoint.y - pointTwo.y, intersectPoint.z - pointTwo.z ) );
    //double alpha = D3DXVec3Length( &tmp ) * 0.5 / totalArea;
    //
    //tmpV = pointOne - pointThree;
    //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointThree.x, intersectPoint.y - pointThree.y, intersectPoint.z - pointThree.z ) );
    //double beta = D3DXVec3Length( &tmp ) * 0.5 / totalArea;

    //tmpV = pointTwo - pointOne;
    //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointOne.x, intersectPoint.y - pointOne.y, intersectPoint.z - pointOne.z ) );
    //double gamma = D3DXVec3Length( &tmp ) * 0.5 / totalArea;

//	if( alpha + beta + gamma > 1.00001 )
//	{
//		return false;
//	}

    D3DXVECTOR3 tmpEdge( intersectPoint.x - pointOne->x, intersectPoint.y - pointOne->y, intersectPoint.z - pointOne->z );
    D3DXVECTOR3 tmpCrossRes;
    D3DXVec3Cross( &tmpCrossRes, &edge1, &tmpEdge );
    double alpha = D3DXVec3Dot( &triNormal, &tmpCrossRes );
    if( alpha < 0.0f )
    {
        return false;
    }

    tmpEdge = D3DXVECTOR3( intersectPoint.x - pointTwo->x, intersectPoint.y - pointTwo->y, intersectPoint.z - pointTwo->z);
    D3DXVECTOR3 tmpEdge2( pointThree->x - pointTwo->x, pointThree->y - pointTwo->y, pointThree->z - pointTwo->z );
    D3DXVec3Cross( &tmpCrossRes, &tmpEdge2, &tmpEdge );
    double beta = D3DXVec3Dot( &triNormal, &tmpCrossRes );
    if( beta < 0.0f )
    {
        return false;
    }

    tmpEdge = D3DXVECTOR3( intersectPoint.x - pointThree->x, intersectPoint.y - pointThree->y, intersectPoint.z - pointThree->z );
    tmpEdge2 = D3DXVECTOR3( pointOne->x - pointThree->x, pointOne->y - pointThree->y, pointOne->z - pointThree->z );
    D3DXVec3Cross( &tmpCrossRes, &tmpEdge2, &tmpEdge );
    double gamma = D3DXVec3Dot( &triNormal, &tmpCrossRes );
    if( gamma < 0.0f )
    {
        return false;
    }

    return true;
}
DCEL DivideAndConquerFor3DCH::BruceForceCH( vector<VERTEX*>* pVertex, const unsigned int offset )
{
    vector<TRIANGLE> triangleSet, finalTriangleSet;

    // Generate all possible triangles
    int pointSetSize = pVertex->size();
    for( int i = 0; i < pointSetSize; i++ )
    {
        for( int j = i + 1; j < pointSetSize; j++ )
        {
            for( int k = j + 1; k < pointSetSize; k++ )
            {
                // Forming face
                TRIANGLE face;
                face.p1.pointOneIndex = i;
                face.p2.pointTwoIndex = j;
                face.p3.pointThreeIndex = k;
                triangleSet.push_back( face );
            }
        }
    }

    // Find the CH for this point set by using RayAndTriangleIntersection method
    for( int i = 0; i < triangleSet.size(); i++ )
    {
        // Create a ray from this surface
        TRIANGLE triangle = triangleSet[ i ];
        // Point2 - point1
        //D3DXVECTOR3 edge1( triangle.pointTwo.x - triangle.pointOne.x, triangle.pointTwo.y - triangle.pointOne.y, triangle.pointTwo.z - triangle.pointOne.z );
        VERTEX* pointOne = (*pVertex)[ triangle.p1.pointOneIndex ];
        VERTEX* pointTwo = (*pVertex)[ triangle.p2.pointTwoIndex ];
        VERTEX* pointThree = (*pVertex)[ triangle.p3.pointThreeIndex ];

        D3DXVECTOR3 edge1( pointTwo->x - pointOne->x, pointTwo->y - pointOne->y, pointTwo->z - pointOne->z );
        D3DXVECTOR3 edge2( pointThree->x - pointOne->x, pointThree->y - pointOne->y, pointThree->z - pointOne->z );
        // point3 - point1
        //D3DXVECTOR3 edge2( triangle.pointThree.x - triangle.pointOne.x, triangle.pointThree.y - triangle.pointOne.y, triangle.pointThree.z - triangle.pointOne.z );

        D3DXVECTOR3 triangleNormal;
        D3DXVec3Cross( &triangleNormal, &edge1, &edge2 );
        D3DXVECTOR3 rayStartPoint( ( pointOne->x + pointTwo->x + pointThree->x ) / 3.0f,
                                   ( pointOne->y + pointTwo->y + pointThree->y ) / 3.0f,
                                   ( pointOne->z + pointTwo->z + pointThree->z ) / 3.0f );

        Ray ray, invRay;
        D3DXVec3Normalize( &ray.direction, &triangleNormal );
        ray.position = rayStartPoint;
        invRay = ray;
        invRay.direction *= -1.0;


        bool rayIntersect = !isNormal(ray, triangleSet[i], pVertex);
        bool invRayIntersect = !isNormal(invRay, triangleSet[i], pVertex);

        // This is the face that contribute to the convex hull and find its vertices order
        if( rayIntersect == false && invRayIntersect == true )
        {
            finalTriangleSet.push_back( triangleSet[ i ] );
        }
        else if( rayIntersect == true && invRayIntersect == false )
        {
            TRIANGLE tmpTri = triangleSet[ i ];
            int tmpVerIndex = tmpTri.p2.pointTwoIndex;
            tmpTri.p2.pointTwoIndex = tmpTri.p3.pointThreeIndex;
            tmpTri.p3.pointThreeIndex = tmpVerIndex;

            finalTriangleSet.push_back( tmpTri );
        }
    }

    DCEL dcel;
    dcel.createDCEL( &finalTriangleSet, pVertex, offset );

    return dcel;
}