Esempio n. 1
0
void cloth::addWindForcesForTriangle(Particle *p1,Particle *p2,Particle *p3, const vec3 direction)
{
	vec3 normal = calcTriangleNormal(p1,p2,p3);
	vec3 d = normalize(normal);
	vec3 force = normal*(dot(d,direction));
	p1->addForce(force);
	p2->addForce(force);
	p3->addForce(force);
}
Esempio n. 2
0
void cloth::updateFaceNormal()
{
	for(int x = 0; x<num_particles_width-1; x++)
	{
		for(int y=0; y<num_particles_height-1; y++)
		{
			vec3 normal = calcTriangleNormal(getParticle(x+1,y),getParticle(x,y),getParticle(x,y+1));
			getParticle(x+1,y)->addToNormal(normal);
			getParticle(x,y)->addToNormal(normal);
			getParticle(x,y+1)->addToNormal(normal);

			normal = calcTriangleNormal(getParticle(x+1,y+1),getParticle(x+1,y),getParticle(x,y+1));
			getParticle(x+1,y+1)->addToNormal(normal);
			getParticle(x+1,y)->addToNormal(normal);
			getParticle(x,y+1)->addToNormal(normal);
		}
	}
}
	/* A private method used by windForce() to calcualte the wind force for a single triangle 
	defined by p1,p2,p3*/
	void addWindForcesForTriangle(Particle *p1,Particle *p2,Particle *p3, const Vec3 direction)
	{
		Vec3 normal = calcTriangleNormal(p1,p2,p3);
		Vec3 d = normal.normalized();
		Vec3 force = normal*(d.dot(direction));
		p1->addForce(force);
		p2->addForce(force);
		p3->addForce(force);
	}
	/* drawing the cloth as a smooth shaded (and colored according to column) OpenGL triangular mesh
	Called from the display() method
	The cloth is seen as consisting of triangles for four particles in the grid as follows:

	(x,y)   *--* (x+1,y)
	        | /|
	        |/ |
	(x,y+1) *--* (x+1,y+1)

	*/
	void drawShaded()
	{
		// reset normals (which where written to last frame)
		std::vector<Particle>::iterator particle;
		for(particle = particles.begin(); particle != particles.end(); particle++)
		{
			(*particle).resetNormal();
		}

		//create smooth per particle normals by adding up all the (hard) triangle normals that each particle is part of
		for(int x = 0; x<num_particles_width-1; x++)
		{
			for(int y=0; y<num_particles_height-1; y++)
			{
				Vec3 normal = calcTriangleNormal(getParticle(x+1,y),getParticle(x,y),getParticle(x,y+1));
				getParticle(x+1,y)->addToNormal(normal);
				getParticle(x,y)->addToNormal(normal);
				getParticle(x,y+1)->addToNormal(normal);

				normal = calcTriangleNormal(getParticle(x+1,y+1),getParticle(x+1,y),getParticle(x,y+1));
				getParticle(x+1,y+1)->addToNormal(normal);
				getParticle(x+1,y)->addToNormal(normal);
				getParticle(x,y+1)->addToNormal(normal);
			}
		}

		glBegin(GL_TRIANGLES);
		for(int x = 0; x<num_particles_width-1; x++)
		{
			for(int y=0; y<num_particles_height-1; y++)
			{
				Vec3 color(0,0,0);
				if (x%2) // red and white color is interleaved according to which column number
					color = Vec3(0.6f,0.2f,0.2f);
				else
					color = Vec3(1.0f,1.0f,1.0f);

				drawTriangle(getParticle(x+1,y),getParticle(x,y),getParticle(x,y+1),color);
				drawTriangle(getParticle(x+1,y+1),getParticle(x+1,y),getParticle(x,y+1),color);
			}
		}
		glEnd();
	}
Esempio n. 5
0
void cloth::generateFace(Particle *p1,Particle *p2,Particle *p3)
{
	Face face;
	face.particleA = p1;
	face.particleB = p2;
	face.particleC = p3;
	face.normal = normalize(calcTriangleNormal(p1,p2,p3));
	face.centerPos.x =(p1->getPos().x+p2->getPos().x+p3->getPos().x)/3;
	face.centerPos.y =(p1->getPos().y+p2->getPos().y+p3->getPos().y)/3;
	face.centerPos.z =(p1->getPos().z+p2->getPos().z+p3->getPos().z)/3;
	faces.push_back(face);
}
Esempio n. 6
0
char* parseTriangle(char *start, std::vector<rpm_triangle_t> &tris, int texId, std::vector<int> &parentBones)
{
	rpm_triangle_t tri;
	tri.iTexID = texId;

	for( int i = 0; i < 3; i++ ) // 3 vertexes
	{
		int mainParent = 0;
		float pos[3] = {0.0f};
		float norm[3] = {0.0f};
		float uv[2] = {0.0f};
		int numRead = 0;
		//sscanf_s(start, "%i%[ \t]%f%[ \t]%f%[ \t]%f%[ \t]%f%[ \t]%f%[ \t]%f%[ \t]%f%[ \t]%f%n",
		sscanf_s(start, "%i %f %f %f %f %f %f %f %f%n",
			&mainParent, &pos[0], &pos[1], &pos[2], &norm[0], &norm[1], &norm[2], &uv[0], &uv[1], &numRead);

		if( numRead > 0 )
		{
			rpm_vertex_t &v = tri.vertex3[i];
			for( int k = 0; k < 3; k++ )
				v.pos3[k] = pos[k];
			for( int k = 0; k < 3; k++ )
				v.norm3[k] = norm[k];
			for( int k = 0; k < 2; k++ )
				v.uv2[k] = uv[k];

			//Try to read additional bone weights
			char *boneWeightStart = start + numRead;
			int links;
			int boneId;
			float weight;
			int numRead = 0;
			int ret = sscanf_s(boneWeightStart, " %i %i %f", &links, &boneId, &weight);
			if( ret == 3 )
				parentBones.push_back(boneId);
			else
				parentBones.push_back(mainParent);
		}

		char *endLn = strchr(start, '\n');
		start = endLn + 1;
	}

	calcTriangleNormal(tri);

	tris.push_back(tri);

	return start;
}
Esempio n. 7
0
bool cloth::testTriangleIntersect(Particle* currentParticle)
{
	bool testResult = false;
	//test each particles, see if it's collide with the plane(face)
	//plane equation: ax+by+cz=d, n=(a,b,c)
	//ray equation: r = p+t*dirc;
	for (int i = 0; i<faces.size(); i++)
	{
		if (faces[i].particleA->particleIndex != currentParticle->particleIndex && faces[i].particleB->particleIndex != currentParticle->particleIndex && faces[i].particleC->particleIndex != currentParticle->particleIndex)
		{
			Face currentface = faces[i];
			glm::vec3 n = normalize(calcTriangleNormal(faces[i].particleA,faces[i].particleB,faces[i].particleC));

			//glm::vec3 p = currentParticle->pos;
			glm::vec3 rayDirection = currentParticle->pos - currentParticle->old_pos;
			float nDotD = glm::dot(rayDirection, n);
			if (abs(nDotD) <= 0.00001 || nDotD ==0)
			{
				return false;
			}
			else
			{
				float d = glm::dot(n, faces[i].particleA->getPos());
				//float d = n.x * faces[i].particleA->getPos().x+n.y * faces[i].particleA->getPos().y+n.z * faces[i].particleA->getPos().z;
				//find out the intersect point
				float t = (d-glm::dot(n,currentParticle->old_pos))/nDotD;
				//float t = dot(n,(faces[i].particleA->getPos()-currentParticle->old_pos))/(nDotD);
				intersectQ = currentParticle->old_pos + t*rayDirection;
				
				if (((intersectQ.x)>=max(currentParticle->pos.x,currentParticle->old_pos.x)) || ((intersectQ.y)>=max(currentParticle->pos.y,currentParticle->old_pos.y)) || ((intersectQ.z)>=max(currentParticle->pos.z,currentParticle->old_pos.z)) ||
					((intersectQ.x)<=min(currentParticle->pos.x,currentParticle->old_pos.x)) || ((intersectQ.y)<=min(currentParticle->pos.y,currentParticle->old_pos.y)) || ((intersectQ.z)<=min(currentParticle->pos.z,currentParticle->old_pos.z))
				   )
				{
					return false;
				}
				////test if Q inside line AB
				//glm::vec3 AB = faces[i].particleB->getPos() - faces[i].particleA->getPos();
				//glm::vec3 AQ = intersectQ - faces[i].particleA->getPos();
				//glm::vec3 testAB = glm::cross(AB,AQ);
				////test if Q inside line BC
				//glm::vec3 BC = faces[i].particleC->getPos() - faces[i].particleB->getPos();
				//glm::vec3 BQ = intersectQ - faces[i].particleB->getPos();
				//glm::vec3 testBC = glm::cross(BC,BQ);
				////test if Q inside line AC
				//glm::vec3 CA = faces[i].particleA->getPos() - faces[i].particleC->getPos();
				//glm::vec3 CQ = intersectQ - faces[i].particleC->getPos();
				//glm::vec3 testAC = glm::cross(CA,CQ);
				/*if (glm::dot(testAB,n)>=0 && glm::dot(testBC,n)>=0 && glm::dot(testAC,n)>=0)
				{
					
					return true;
				}*/
				if(PointinTriangle(faces[i].particleA->getPos(),faces[i].particleB->getPos(),faces[i].particleC->getPos(),intersectQ))
				{
					currentParticle->pos = currentParticle->old_pos; 
					printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
					return true;
					
				}
			}	
		}
	}
	return false;
}
void
ParticleSystem::calculateNormals()
{
    assert(mFaceNormals != NULL && mVertexNormals != NULL);

#define IDX(u,v) ( (u)+((v)*mWidth) )

    // normals calculation
    // calculate normals to faces
    for (int y=0; y<mHeight-1; y++) {
        for (int x=0; x<mWidth-1; x++) {
            Vector3d &p1 = getParticlePos(x, y);
            Vector3d &p2 = getParticlePos(x, y+1);
            Vector3d &p4 = getParticlePos(x+1, y);
            Vector3d v1 = p2-p1;
            Vector3d v2 = p4-p1;
            mFaceNormals[IDX(x,y)] = v1.cross(v2);
            mFaceNormals[IDX(x,y)].normalize();
        }
    }
    // calculate normals to vertices
    Vector3d normal1, normal2, normal3, normal4;
    Vector3d normal;
    for (int y=0; y<mHeight; y++) {
        for (int x=0; x<mWidth; x++) {
            // corners
            if (x==0 && y==0) {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x+1, y);
                Vector3d &p3 = getParticlePos(x, y+1);
                normal = calcTriangleNormal( p1, p2, p3);
            }
            else if (x==0 && y==mHeight-1) {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x, y-1);
                Vector3d &p3 = getParticlePos(x+1, y);
                normal = calcTriangleNormal( p1, p2, p3);
            }
            else if (x==mWidth-1 && y==0) {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x, y+1);
                Vector3d &p3 = getParticlePos(x-1, y);
                normal = calcTriangleNormal( p1, p2, p3);
            }
            else if (x==mWidth-1 && y==mHeight-1) {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x-1, y);
                Vector3d &p3 = getParticlePos(x, y-1);
                normal = calcTriangleNormal( p1, p2, p3);
            }
            // edges
            else if (x==0) {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x, y-1);
                Vector3d &p3 = getParticlePos(x+1, y);
                Vector3d &p4 = getParticlePos(x, y+1);
                normal1 = calcTriangleNormal( p1, p2, p3);
                normal2 = calcTriangleNormal( p1, p3, p4);
                normal = normal1 + normal2;
            }
            else if (x==mWidth-1) {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x, y+1);
                Vector3d &p3 = getParticlePos(x-1, y);
                Vector3d &p4 = getParticlePos(x, y-1);
                normal1 = calcTriangleNormal( p1, p2, p3);
                normal2 = calcTriangleNormal( p1, p3, p4);
                normal = normal1 + normal2;
            }
            else if (y==0) {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x+1, y);
                Vector3d &p3 = getParticlePos(x, y+1);
                Vector3d &p4 = getParticlePos(x-1, y);
                normal1 = calcTriangleNormal( p1, p2, p3);
                normal2 = calcTriangleNormal( p1, p3, p4);
                normal = normal1 + normal2;
            }
            else if (y==mHeight-1) {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x-1, y);
                Vector3d &p3 = getParticlePos(x, y-1);
                Vector3d &p4 = getParticlePos(x+1, y);
                normal1 = calcTriangleNormal( p1, p2, p3);
                normal2 = calcTriangleNormal( p1, p3, p4);
                normal = normal1 + normal2;
            }
            // inner vertices
            else {
                Vector3d &p1 = getParticlePos(x, y);
                Vector3d &p2 = getParticlePos(x-1, y);
                Vector3d &p3 = getParticlePos(x, y-1);
                Vector3d &p4 = getParticlePos(x+1, y);
                Vector3d &p5 = getParticlePos(x, y+1);
                normal1 = calcTriangleNormal( p1, p2, p3);
                normal2 = calcTriangleNormal( p1, p3, p4);
                normal3 = calcTriangleNormal( p1, p4, p5);
                normal4 = calcTriangleNormal( p1, p5, p2);
                normal = normal1 + normal2 + normal3 + normal4;
            }
            normal.normalize();
            mVertexNormals[IDX(x,y)] = normal;
        }
    }

#undef IDX
}