Example #1
0
/* Function: PenaltyPushBack
 * Description: Responds to the collision that is detected and performs penalty method for model spheres
 * Input: cur - current model structure
 *		  p2 - center of the other model
 *		  r1 - radius of the other model
 * Output: void
 */
void PenaltyPushBack(pModel *cur, pModel *next)
{
	point distCI, distIC, inter, velDir, cVel;
	double length;

	pDIFFERENCE(cur->cModel, next->cModel, inter);
	pNORMALIZE(inter);
	pCPY(next->pObj->avgVel, velDir);
	pNORMALIZE(velDir);
	pCPY(cur->pObj->avgVel, cVel);
	pNORMALIZE(cVel);

	pMULTIPLY(inter, next->radius, inter);
	
	for (unsigned int index = STARTFROM; index <= cur->pObj->model->numvertices; index++)
	{
		point cP = vMake(cur->pObj->model->vertices[3*index], cur->pObj->model->vertices[3*index + 1], cur->pObj->model->vertices[3*index + 2]);
		length = vecLeng(cP, inter);
		point pForce = penaltyForce(cP, cur->pObj->velocity[index], inter, velDir, cur->pObj->kSphere, cur->pObj->dSphere);

		// Add the forces to the collided vertex
		pMULTIPLY(pForce, (1.0 / (length * length)) * cur->pObj->mass[index], pForce);
		pSUM(cur->pObj->extForce[index] , pForce, cur->pObj->extForce[index]);

		point nP = vMake(next->pObj->model->vertices[3*index], next->pObj->model->vertices[3*index + 1], next->pObj->model->vertices[3*index + 2]);
		length = vecLeng(nP, inter);
		point nForce = penaltyForce(nP, next->pObj->velocity[index], inter, cVel, next->pObj->kSphere, next->pObj->dSphere);

		// Add the forces to the collided vertex
		pMULTIPLY(nForce, -(1.0 / (length * length)) * next->pObj->mass[index], nForce);
		pSUM(next->pObj->extForce[index], nForce, next->pObj->extForce[index]);
	}
}
Example #2
0
/* Function: computeHooksForce
 * Description: Compute Hook's Law in 3D
 * Input: index - index of the vertex which collided 
 *		  wallP - point on the wall where the vertex is colliding
 * Output: Computed hooks force 
 */
point computeHooksForce(int index, point B, phyzx *phyzxObj)
{
	
	point L, unitV;
	double mag = 0;
	double restLength = 0, length;
	point hooksForce, A;
	
	memset( (void*)&L, 0, sizeof(L));
	memset( (void*)&unitV, 0, sizeof(unitV));
	memset( (void*)&hooksForce, 0, sizeof(hooksForce));
	memset( (void*)&A, 0, sizeof(A));

	A = vMake(phyzxObj->model->vertices[3*index], phyzxObj->model->vertices[3*index + 1], phyzxObj->model->vertices[3*index + 2]);
	pDIFFERENCE(A, B, L);
	pCPY(L, unitV);
	pNORMALIZE(unitV);
	//xxx
	/*length = A.y - B.y;
	unitV.x = 0;
	unitV.y = 1;
	unitV.z = 0;*/
	pMULTIPLY(unitV, -(phyzxObj->kWall) * length * phyzxObj->mass[index], hooksForce);
	//pMULTIPLY(unitV, -(phyzxObj->kWall) * length, hooksForce);

	return hooksForce;
}
bool Pick(int x, int y)
{
    double length;
    point ray_orig, ray_dir;
    ViewUnProject(x, y, 0.0f, &ray_orig);
    ViewUnProject(x, y, 1.0f, &ray_dir);
    pDIFFERENCE(ray_dir, ray_orig, ray_dir);
    pNORMALIZE(ray_dir);
    
}
Example #4
0
/* Function: penaltyForce
 * Description: Computes the penalty force between two points.
 * Input: p - Coordinates of first point
 *        pV - Velocity of first point
 *        I - Intersection point
 *        V - Velocity of Intersection point
 *        kH - K value for Hook's Law
 *        kD - K value for damping force
 * Output: Penalty force vector
 */
point penaltyForce(point p, point pV, point I, point V, double kH, double kD)
{
	double mag, length, dot;
	point dist, hForce, dForce, pVel, vDiff, pForce;

	// Initialize force computation variables
	pDIFFERENCE(p, I, dist);
	pDIFFERENCE(pV, V, vDiff);
	dot = dotProd(vDiff, dist);

	// Compute Hooks Force
	pNORMALIZE(dist);
	pMULTIPLY(dist, -(kH * length), hForce);

	// Compute Damping Forces
	mag = length;
	pNORMALIZE(pV);
	pMULTIPLY(pV, (kD * (dot/length)), dForce);
	
	// Compute Penalty Force
	pSUM(hForce, dForce, pForce);

	return pForce;
} //end penaltyForce
void RenderClothSystem(cloth *clothItem, GLuint texId)
{
	double length = 0.0f;
	
	struct tex
	{
		float u;
		float v;
	};

	struct tex texture, increment;

	if(gRenderMode == THREAD)
	{
		glLineWidth(1);
		glPointSize(5);

		glDisable(GL_LIGHTING);

		// Render the cloth points
		glBegin(GL_POINTS);
			RenderPoints(clothItem);
		glEnd();
	
		// Render the cloth springs
		for(int row = 0; row < clothItem->height; row++)
		{
			for(int col = 0; col < clothItem->width; col++)
			{
				glBegin(GL_LINES);
					// Render the structural springs
					RenderSpring(clothItem, nMake(col, row, 0), nMake(1, 0, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(-1, 0, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(0, 1, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(0, -1, 0));

					// Render shear springs along the side
					RenderSpring(clothItem, nMake(col, row, 0), nMake(1, 1, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(1, -1, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(-1, 1, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(-1, -1, 0));

					// Render bend springs
					RenderSpring(clothItem, nMake(col, row, 0), nMake(2, 0, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(-2, 0, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(0, 2, 0));
					RenderSpring(clothItem, nMake(col, row, 0), nMake(0, -2, 0));
				glEnd();
			}
		}

		glEnable(GL_LIGHTING);
	}

	if(gRenderMode == TRIANGLE)
	{
		glDisable(GL_LIGHTING);
		glDisable(GL_CULL_FACE);

		glPolygonMode(GL_FRONT, GL_FILL);
		
		// Accumulate the normals for all the points in the cloth
		point len1, len2, len3;
		int index, index1, index2, index3;
		for(int row = 0; row < clothItem->height - 1; row++)
		{
			for(int col = 0; col < clothItem->width - 1; col ++)
			{
	/*
			index		index1
				-----------
				|		 /|
				|  T1   / |
				|	   /  |
				|     /   |
				|    /    |
				|   /     |
				|  /      |
				| /  T2   |
				|/        |
				-----------
			index2		index3
	*/

				index = FindIndexInArray(row, col, clothItem->width);
				index1 = FindIndexInArray(row, col + 1, clothItem->width);
				index2 = FindIndexInArray(row + 1, col, clothItem->width);
				index3 = FindIndexInArray(row + 1, col + 1, clothItem->width);

				// First triangle - left top
				pDIFFERENCE(clothItem->positions[index1], clothItem->positions[index], len1);	
				pDIFFERENCE(clothItem->positions[index2], clothItem->positions[index], len2);	
				
				CROSSPRODUCTp(len1, len2, len3);
				pNORMALIZE(len3);

				pSUM(clothItem->normals[index1], len3, clothItem->normals[index1]);
				clothItem->normalsCount[index1]++;

				pSUM(clothItem->normals[index2], len3, clothItem->normals[index2]);
				clothItem->normalsCount[index2]++;

				pSUM(clothItem->normals[index], len3, clothItem->normals[index]);
				clothItem->normalsCount[index]++;

				// Second triangle - right bottom
				pDIFFERENCE(clothItem->positions[index1], clothItem->positions[index3], len1);	
				pDIFFERENCE(clothItem->positions[index2], clothItem->positions[index3], len2);	
				
				CROSSPRODUCTp(len1, len2, len3);
				pNORMALIZE(len3);

				pSUM(clothItem->normals[index1], len3, clothItem->normals[index1]);
				clothItem->normalsCount[index1]++;

				pSUM(clothItem->normals[index2], len3, clothItem->normals[index2]);
				clothItem->normalsCount[index2]++;

				pSUM(clothItem->normals[index3], len3, clothItem->normals[index]);
				clothItem->normalsCount[index3]++;
			}
		}
		
		texture.u = 0.0;
		texture.v = 0.0;

		increment.u = 1.0 / clothItem->width;
		increment.v = 1.0 / clothItem->height;
		// Render the triangles
		for(int row = 0; row < clothItem->height - 1; row++)
		{
			glBindTexture(GL_TEXTURE_2D, texId);

			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

			glBegin(GL_TRIANGLE_STRIP);
			
			for(int col = 0; col < clothItem->width - 1; col ++)
			{
				//index index 2 index 1 index 3
				index = FindIndexInArray(row, col, clothItem->width); 
				index1 = FindIndexInArray(row, col + 1, clothItem->width);
				index2 = FindIndexInArray(row + 1, col, clothItem->width);
				index3 = FindIndexInArray(row + 1, col + 1, clothItem->width); 

				// CCW order for the triangle strip
				// left top (0,0)
				glNormal3f(clothItem->normals[index].x / clothItem->normalsCount[index], clothItem->normals[index].y / clothItem->normalsCount[index], clothItem->normals[index].z / clothItem->normalsCount[index]);
				glTexCoord2f(texture.u, texture.v);
				glVertex3f(clothItem->positions[index].x, clothItem->positions[index].y, clothItem->positions[index].z);

				// left bottom (0, 1)
				glNormal3f(clothItem->normals[index2].x / clothItem->normalsCount[index2], clothItem->normals[index2].y / clothItem->normalsCount[index2], clothItem->normals[index2].z / clothItem->normalsCount[index2]);
				glTexCoord2f(texture.u, texture.v + increment.v);
				glVertex3f(clothItem->positions[index2].x, clothItem->positions[index2].y, clothItem->positions[index2].z);

				// right top (1, 0)
				glNormal3f(clothItem->normals[index1].x / clothItem->normalsCount[index1], clothItem->normals[index1].y / clothItem->normalsCount[index1], clothItem->normals[index1].z / clothItem->normalsCount[index1]);
				glTexCoord2f(texture.u + increment.u, texture.v);
				glVertex3f(clothItem->positions[index1].x, clothItem->positions[index1].y, clothItem->positions[index1].z);

				// right bottom (1, 1)
				glNormal3f(clothItem->normals[index3].x / clothItem->normalsCount[index3], clothItem->normals[index3].y / clothItem->normalsCount[index3], clothItem->normals[index3].z / clothItem->normalsCount[index3]);
				glTexCoord2f(texture.u + increment.u, texture.v + increment.v);
				glVertex3f(clothItem->positions[index3].x, clothItem->positions[index3].y, clothItem->positions[index3].z);

				texture.u += increment.u;
			}
			
			texture.u = 0.0;
			texture.v += increment.v;
			glEnd();
		}

		glEnable(GL_LIGHTING);
	}// if gRenderMode
}// end RenderClothSystem
/* Function: cameraFreeMove
 * Description: Free movement camera computations.  Allow camera to move 
 *              forward, backword, up, down, strafe left, strafe right, 
 *              tilt up/down and turn right/left.
 * Input: dir - Direction of movement
 *              0. Move Camera Forward
 *              1. Move Camera Backward
 *              2. Move Camera Up
 *              3. Move Camera Down
 *              4. Move Camera Right
 *              5. Move Camera Left
 *              6. Tilt Camera Up		(Not Implemented)
 *              7. Tilt Camera Down		(Not Implemented)
 *              8. Turn Camera Right	(Not Implemented)
 *              9. Turn Camera Left		(Not Implemented)
 * Output: None
 */
void cameraFreeMove(int dir)
{
	point mouse, vec, pVec, cVec, cPos;
	double ang, length;

	pDIFFERENCE(lineOfSight, cameraPos, vec);
	pNORMALIZE(vec);

	if (dir == 0)			// Move Camera Forward
	{
		pMULTIPLY(vec, CAMSPEED, vec);
		pSUM(cameraPos, vec, cameraPos);
		pSUM(lineOfSight, vec, lineOfSight);

	} //end if 
	else if (dir == 1)		// Move Camera Backward
	{
		pMULTIPLY(vec, CAMSPEED, vec);
		pDIFFERENCE(cameraPos, vec, cameraPos);
		pDIFFERENCE(lineOfSight, vec, lineOfSight);
	} //end else
	else if (dir == 2)		// Move Camera Up
	{
		ang = Phi + CAMROT;
		cPos.x = lineOfSight.x + (R * cos(ang) * cos(Theta));
		cPos.y = lineOfSight.y + (R * sin(Theta));
		cPos.z = lineOfSight.z + (-R * sin(ang) * cos(Theta));

		pDIFFERENCE(cPos, cameraPos, pVec);
		pNORMALIZE(pVec);
		CROSSPRODUCTp(pVec, vec, cVec);
		pMULTIPLY(cVec, CAMSPEED, cVec);
		pSUM(cameraPos, cVec, cameraPos);
		pSUM(lineOfSight, cVec, lineOfSight);
	} //end else
	else if (dir == 3)		// Move Camera Down
	{
		ang = Phi + CAMROT;
		cPos.x = lineOfSight.x + (R * cos(ang) * cos(Theta));
		cPos.y = lineOfSight.y + (R * sin(Theta));
		cPos.z = lineOfSight.z + (-R * sin(ang) * cos(Theta));

		pDIFFERENCE(cPos, cameraPos, pVec);
		pNORMALIZE(pVec);
		CROSSPRODUCTp(pVec, vec, cVec);
		pMULTIPLY(cVec, CAMSPEED, cVec);
		pDIFFERENCE(cameraPos, cVec, cameraPos);
		pDIFFERENCE(lineOfSight, cVec, lineOfSight);
	} //end else
	else if (dir == 4)		// Move Camera Strafe Right
	{
		ang = Theta + CAMROT;
		cPos.x = lineOfSight.x + (R * cos(Phi) * cos(ang));
		cPos.y = lineOfSight.y + (R * sin(ang));
		cPos.z = lineOfSight.z + (-R * sin(Phi) * cos(ang));

		pDIFFERENCE(cPos, cameraPos, pVec);
		pNORMALIZE(pVec);
		CROSSPRODUCTp(vec, pVec, cVec);
		pMULTIPLY(cVec, CAMSPEED, cVec);
		pSUM(cameraPos, cVec, cameraPos);
		pSUM(lineOfSight, cVec, lineOfSight);
	} //end else
	else if (dir == 5)		// Move Camera Strafe Left
	{
		ang = Theta + CAMROT;
		cPos.x = lineOfSight.x + (R * cos(Phi) * cos(ang));
		cPos.y = lineOfSight.y + (R * sin(ang));
		cPos.z = lineOfSight.z + (-R * sin(Phi) * cos(ang));

		pDIFFERENCE(cPos, cameraPos, pVec);
		pNORMALIZE(pVec);
		CROSSPRODUCTp(vec, pVec, cVec);
		pMULTIPLY(cVec, CAMSPEED, cVec);
		pDIFFERENCE(cameraPos, cVec, cameraPos);
		pDIFFERENCE(lineOfSight, cVec, lineOfSight);
	} //end else
} //end cameraFreeMove
// Hook's Law in 3D
//				F = -k hook ( |L| - R) L / |L|	
// springType	1 = Structural
//				2 = Shear side
//				3 = Shear diagonal
//				4 = Bend
//				5 = Collision
point computeHooksForce(int indexA, int indexB, point collisionP, cloth *clothItem, int springType, int coEffType)
{
	point L, unitV;
	double mag = 0;
	double restLength = 0, length = 0.0;
	point hooksForce;
	
	memset( (void*)&L, 0, sizeof(L));
	memset( (void*)&unitV, 0, sizeof(unitV));
	memset( (void*)&hooksForce, 0, sizeof(hooksForce));

	if(coEffType == KELASTIC)
	{
		L.x = clothItem->positions[indexA].x - clothItem->positions[indexB].x;
		L.y = clothItem->positions[indexA].y - clothItem->positions[indexB].y;
		L.z = clothItem->positions[indexA].z - clothItem->positions[indexB].z;

		mag = sqrt((L.x * L.x) + (L.y * L.y) + (L.z * L.z));

		unitV.x = L.x / mag;
		unitV.y = L.y / mag;
		unitV.z = L.z / mag;
		
		// Find the rest length for the current type of spring
		switch(springType)
		{
			case 1:	//Structural spring
				restLength = clothItem->strSprLen;
				break;
			case 2: //Shear side spring
				restLength = clothItem->shrSprLen;
				break;
			case 3: //Bend spring
				restLength = clothItem->bendSprLen;
				break;
			case 4: //Collision spring
				restLength = 0;
				break;
		}

		hooksForce.x = -(clothItem->kThread) * (mag - restLength) * (unitV.x);
		hooksForce.y = -(clothItem->kThread) * (mag - restLength) * (unitV.y);
		hooksForce.z = -(clothItem->kThread) * (mag - restLength) * (unitV.z);
	}
	else if(coEffType == KCOLLISION)
	{
		L.x = clothItem->positions[indexA].x - collisionP.x;
		L.y = clothItem->positions[indexA].y - collisionP.y;
		L.z = clothItem->positions[indexA].z - collisionP.z;

		mag = sqrt((L.x * L.x) + (L.y * L.y) + (L.z * L.z));

//		unitV.x = clothItem->normals[indexA].x / clothItem->normalsCount[indexA];
//		unitV.y = clothItem->normals[indexA].y / clothItem->normalsCount[indexA];
//		unitV.z = clothItem->normals[indexA].z / clothItem->normalsCount[indexA];

		pNORMALIZE(unitV);
		unitV.x = L.x / mag;
		unitV.y = L.y / mag;
		unitV.z = L.z / mag;

		hooksForce.x = -(clothItem->kWall) * (mag) * (unitV.x);
		hooksForce.y = -(clothItem->kWall) * (mag) * (unitV.y);
		hooksForce.z = -(clothItem->kWall) * (mag) * (unitV.z);
	}
	return hooksForce;
}