Beispiel #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]);
	}
}
Beispiel #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;
}
void CopyToBuffer(cloth *buffer, cloth*clothItem)
{
	int index = 0;

	// Time step and nstep for the simulation
	buffer->nStep = clothItem->nStep;
	buffer->tStep = clothItem->tStep;

	// Set the lengths of all the springs in the cloth based of the input strSprLen
	buffer->strSprLen = clothItem->strSprLen;
	buffer->shrSprLen = clothItem->shrSprLen;
	buffer->bendSprLen = clothItem->bendSprLen;

	// count of the number of vertives in the cloth
	buffer->cArrayLength = clothItem->cArrayLength;

	// Hooks coefficients
	buffer->kThread = clothItem->kThread;
	buffer->kWall = clothItem->kWall;
	buffer->dThread = clothItem->dThread;
	buffer->dWall = clothItem->dWall;
	buffer->width = clothItem->width;
	buffer->height = clothItem->height;
	buffer->mass = clothItem->mass;

	buffer->positions = (point*)calloc(buffer->cArrayLength, sizeof(point));
	buffer->velocities = (point*)calloc(buffer->cArrayLength, sizeof(point));
	buffer->acceleration = (point*)calloc(buffer->cArrayLength, sizeof(point));
	buffer->force = (point*)calloc(buffer->cArrayLength, sizeof(point));
	buffer->normals = (point*)calloc(buffer->cArrayLength, sizeof(point));
	buffer->normalsCount = (int*)calloc(buffer->cArrayLength, sizeof(int));
	
	for(int row = 0; row < clothItem->height; row++)
	{
		for(int col = 0; col < clothItem->width; col++)
		{
			index = FindIndexInArray(row, col, clothItem->width);

			pCPY(clothItem->positions[index], buffer->positions[index]);
			pCPY(clothItem->velocities[index], buffer->velocities[index]);
			pCPY(clothItem->velocities[index], buffer->velocities[index]);
			pCPY(clothItem->force[index], buffer->force[index]);
			pCPY(clothItem->normals[index], buffer->normals[index]);
			buffer->normalsCount[index] = clothItem->normalsCount[index];
		}
	}
}
void ClothInit(cloth *clothItem, double strSprLen, point birthPosition, int clothWidth, int clothHeight)
{
	point cur;
	memset( (void*)&cur, 0, sizeof(point));
	int index = 0;

	// Time step and nstep for the simulation
	clothItem->nStep = gNstep;
	clothItem->tStep = gTstep;

	// Set the lengths of all the springs in the cloth based of the input strSprLen
	clothItem->strSprLen = strSprLen;
	clothItem->shrSprLen = sqrt(2.0) * strSprLen;
	clothItem->bendSprLen = 2.0 * strSprLen;

	// count of the number of vertives in the cloth
	clothItem->cArrayLength = clothWidth * clothHeight;

	// Hooks coefficients
	clothItem->kThread = gKThread;
	clothItem->kWall = gKWall;
	clothItem->dThread = gDThread;
	clothItem->dWall = gDWall;

	clothItem->width = clothWidth;
	clothItem->height = clothHeight;

	// Same mass for all the vertices of the cloth
	clothItem->mass = 0.02;

	// Set the initial positions based on the structural spring length
	clothItem->positions = (point*)calloc(clothItem->cArrayLength, sizeof(point));
	
	for(int row = 0; row < clothHeight; row++)
	{
		memset( (void*)&cur, 0, sizeof(point));
		
		// new row position
		cur.y = birthPosition.y - (row * strSprLen);

		for(int col = 0; col < clothWidth; col++)
		{
			// new col position
			cur.x = birthPosition.x + (col * strSprLen);

			index = FindIndexInArray(row, col, clothWidth);

			cur.z = birthPosition.z;

			pCPY(cur, clothItem->positions[index]);
		}
	}

	// set the initial velocities for all the vertices of the cloth
	clothItem->velocities = (point*)calloc(clothItem->cArrayLength, sizeof(point));

	// set the initial acceleration for all the vertices of the cloth
	clothItem->acceleration = (point*)calloc(clothItem->cArrayLength, sizeof(point));

	for(int row = 0; row < clothHeight; row++)
	{
		for(int col = 0; col < clothWidth; col++)
		{
			index = FindIndexInArray(row, col, clothWidth);

			// Change these for the initial velocities
			clothItem->acceleration[index].x = 0.0;
			clothItem->acceleration[index].y = 0.0;
			clothItem->acceleration[index].z = 0.0;
		}
	}

	clothItem->force = (point*)calloc(clothItem->cArrayLength, sizeof(point));

	for(int row = 0; row < clothHeight; row++)
	{
		for(int col = 0; col < clothWidth; col++)
		{
			index = FindIndexInArray(row, col, clothWidth);

			// Change these for the initial velocities
			clothItem->force[index].x = 0.0;
			clothItem->force[index].y = 0.0;
			clothItem->force[index].z = 0.0;
		}
	}

	clothItem->normals = (point*)calloc(clothItem->cArrayLength, sizeof(point));

	clothItem->normalsCount = (int*)calloc(clothItem->cArrayLength, sizeof(int));

}// End of cloth initialization
/* as a result, updates the jello structure */
void RK4(cloth *clothItem)
{
	int index;
	point *F1p, *F1v,
		*F2p, *F2v,
		*F3p, *F3v,
		*F4p, *F4v;

	F1p = (point*)calloc(clothItem->cArrayLength, sizeof(point));
	F1v = (point*)calloc(clothItem->cArrayLength, sizeof(point));
	F2p = (point*)calloc(clothItem->cArrayLength, sizeof(point));
	F2v = (point*)calloc(clothItem->cArrayLength, sizeof(point));
	F3p = (point*)calloc(clothItem->cArrayLength, sizeof(point));
	F3v = (point*)calloc(clothItem->cArrayLength, sizeof(point));
	F4p = (point*)calloc(clothItem->cArrayLength, sizeof(point));
	F4v = (point*)calloc(clothItem->cArrayLength, sizeof(point));

	cloth *buffer = (cloth*)malloc(1 * sizeof(cloth));

	CopyToBuffer(buffer, clothItem);

	computeAcceleration(clothItem);

	for(int row = 0; row < clothItem->height; row++)
	{
		for(int col = 0; col < clothItem->width; col++)
		{
			index = FindIndexInArray(row, col, clothItem->width);
			
			// Pin Check
			if(gPin == PINNED)
			{
				if(index == 0 || index == clothItem->width-1)
				continue;
			}
			else if(gPin == UNPINLEFT)
			{
				if(index == clothItem->width-1)
				continue;
			}
			else if(gPin == UNPINRIGHT)
			{
				if(index == 0)
				continue;
			}

			pMULTIPLY(clothItem->velocities[index], clothItem->tStep, F1p[index]);
			pMULTIPLY(clothItem->acceleration[index], clothItem->tStep, F1v[index]);
			pMULTIPLY(F1p[index], 0.5, buffer->positions[index]);
			pMULTIPLY(F1v[index], 0.5, buffer->velocities[index]);
			pSUM(clothItem->positions[index], buffer->positions[index], buffer->positions[index]);
			pSUM(clothItem->velocities[index], buffer->velocities[index], buffer->velocities[index]);
		}
	}

	for(int  i= 0; i < clothItem->cArrayLength; i++)
	{
		pCPY(clothItem->acceleration[i], buffer->acceleration[i]); 
	}

	computeAcceleration(buffer);

	for(int row = 0; row < clothItem->height; row++)
	{
		for(int col = 0; col < clothItem->width; col++)
		{
			index = FindIndexInArray(row, col, clothItem->width);

			// Pin Check
			if(gPin == PINNED)
			{
				if(index == 0 || index == clothItem->width-1)
				continue;
			}
			else if(gPin == UNPINLEFT)
			{
				if(index == clothItem->width-1)
				continue;
			}
			else if(gPin == UNPINRIGHT)
			{
				if(index == 0)
				continue;
			}

			pMULTIPLY(buffer->velocities[index], clothItem->tStep, F2p[index]);
			pMULTIPLY(buffer->acceleration[index], clothItem->tStep, F2v[index]);
			pMULTIPLY(F2p[index], 0.5, buffer->positions[index]);
			pMULTIPLY(F2v[index], 0.5, buffer->velocities[index]);
			pSUM(clothItem->positions[index], buffer->positions[index], buffer->positions[index]);
			pSUM(clothItem->velocities[index], buffer->velocities[index], buffer->velocities[index]);
		}
	}

	computeAcceleration(buffer);

	for(int row = 0; row < clothItem->height; row++)
	{
		for(int col = 0; col < clothItem->width; col++)
		{
			index = FindIndexInArray(row, col, clothItem->width);

			// Pin Check
			if(gPin == PINNED)
			{
				if(index == 0 || index == clothItem->width-1)
				continue;
			}
			else if(gPin == UNPINLEFT)
			{
				if(index == clothItem->width-1)
				continue;
			}
			else if(gPin == UNPINRIGHT)
			{
				if(index == 0)
				continue;
			}

			pMULTIPLY(buffer->velocities[index], clothItem->tStep, F3p[index]);
			pMULTIPLY(buffer->acceleration[index], clothItem->tStep, F3v[index]);
			pMULTIPLY(F3p[index], 0.5, buffer->positions[index]);
			pMULTIPLY(F3v[index], 0.5, buffer->velocities[index]);
			pSUM(clothItem->positions[index], buffer->positions[index], buffer->positions[index]);
			pSUM(clothItem->velocities[index], buffer->velocities[index], buffer->velocities[index]);
		}
	}
         
	computeAcceleration(buffer);

	for(int row = 0; row < clothItem->height; row++)
	{
		for(int col = 0; col < clothItem->width; col++)
		{
			index = FindIndexInArray(row, col, clothItem->width);

			// Pin Check
			if(gPin == PINNED)
			{
				if(index == 0 || index == clothItem->width-1)
				continue;
			}
			else if(gPin == UNPINLEFT)
			{
				if(index == clothItem->width-1)
				continue;
			}
			else if(gPin == UNPINRIGHT)
			{
				if(index == 0)
				continue;
			}

			pMULTIPLY(buffer->velocities[index], clothItem->tStep, F4p[index]);
			pMULTIPLY(buffer->acceleration[index], clothItem->tStep, F4v[index]);
			pMULTIPLY(F2p[index], 2, buffer->positions[index]);
			pMULTIPLY(F3p[index], 2, buffer->velocities[index]);
			pSUM(buffer->positions[index], buffer->velocities[index], buffer->positions[index]);
			pSUM(buffer->positions[index], F1p[index], buffer->positions[index]);
			pSUM(buffer->positions[index], F4p[index], buffer->positions[index]); 
			pMULTIPLY(buffer->positions[index], 1.0 / 6, buffer->positions[index]);
			pSUM(buffer->positions[index], clothItem->positions[index], clothItem->positions[index]);
			 
			pMULTIPLY(F2v[index], 2, buffer->positions[index]);
			pMULTIPLY(F3v[index], 2, buffer->velocities[index]);
			pSUM(buffer->positions[index], buffer->velocities[index], buffer->positions[index]);
			pSUM(buffer->positions[index], F1v[index], buffer->positions[index]);
			pSUM(buffer->positions[index], F4v[index], buffer->positions[index]);
			pMULTIPLY(buffer->positions[index], 1.0 / 6, buffer->positions[index]);
			pSUM(buffer->positions[index], clothItem->velocities[index], clothItem->velocities[index]);
		}
	}

	for(int  i= 0; i < clothItem->cArrayLength; i++)
	{
		pCPY(buffer->acceleration[i], clothItem->acceleration[i]); 
	}

	for(int  i= 0; i < clothItem->cArrayLength; i++)
	{
		// Pin Check
		if(gPin == PINNED)
		{
			if(index == 0 || index == clothItem->width-1)
			continue;
		}
		else if(gPin == UNPINLEFT)
		{
			if(index == clothItem->width-1)
			continue;
		}
		else if(gPin == UNPINRIGHT)
		{
			if(index == 0)
			continue;
		}

		pMULTIPLY(clothItem->velocities[i], gDelta, underWaterDamp);
		pSUM(clothItem->velocities[i], underWaterDamp, clothItem->velocities[i]);
		pSUM(clothItem->force[i], gravity, clothItem->force[i]);
	}

	free(buffer);
  return;  
}
// Computes acceleration to every point of the cloth		
void computeAcceleration(cloth *clothItem)
{  
	node typeP, curP;	// typeP = one of the 12 nodes to which the curP point is connected
	int collided = 0, index;

	memset( (void*)&typeP, 0, sizeof(typeP));
	memset( (void*)&curP, 0, sizeof(curP));
	

	/*
	// FORCE FIELD COMPUTATION
	if(ActivateFF)
	{
		// Check for force field
		if(jello->resolution)
		{
			// compute the force field cube size and store it in the global variable
			forceFieldCubeSize = ((double)4)/jello->resolution;
			noOfCubesInRow = (int)(((double)jello->resolution) / forceFieldCubeSize);

			// Compute the effect of force field and update the forces due to it on all the nodes
			computeForceField(jello);
		}
	}
	*/

	// COLLISION DETECTION AND RESPONSE
	for(int row = 0; row < clothItem->height; row++)
	{
		for(int col = 0; col < clothItem->width; col++)
		{
			memset( (void*)&curP, 0, sizeof(curP));

			index = FindIndexInArray(curP.y, curP.x, clothItem->width);
			pCPY(vMake(0.0), clothItem->force[index]);

			curP.x = col;
			curP.y = row;
			
			// Checks whether any of the nodes is colliding with the bounding box and Sphere
			checkForCollision(curP, clothItem);
		}
	}

	for(int row = 0; row < clothItem->height; row++)
	{
		for(int col = 0; col < clothItem->width; col++)
		{
			curP.x = col;
			curP.y = row;

			// Check for all the springs possible = 12
			
			// STRUCTURAL SPRINGS
			//-----------------------------------------------------------------
			// TYPE 1 -> (x+1, y, z) structural spring
			typeP.x = col + 1;
			typeP.y = row;
			
			updateForce(curP, typeP, clothItem, STRUCTURAL);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 2 -> (x-1, y, z)
			typeP.x = col - 1;
			typeP.y = row;
			
			updateForce(curP, typeP, clothItem, STRUCTURAL);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 3 -> (x, y+1, z)
			typeP.x = col;
			typeP.y = row + 1;
			
			updateForce(curP, typeP, clothItem, STRUCTURAL);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 4 -> (x, y-1, z)
			typeP.x = col;
			typeP.y = row - 1;
			
			updateForce(curP, typeP, clothItem, STRUCTURAL);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------

			// SHEAR SPRINGS
			//-----------------------------------------------------------------
			// TYPE 5 -> (x+1, y+1, z)
			typeP.x = col + 1;
			typeP.y = row + 1;
			
			updateForce(curP, typeP, clothItem, SHEARSIDE);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 6 -> (x-1, y+1, z)
			typeP.x = col - 1;
			typeP.y = row + 1;
			
			updateForce(curP, typeP, clothItem, SHEARSIDE);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 7 -> (x+1, y-1, z)
			typeP.x = col + 1;
			typeP.y = row - 1;
			
			updateForce(curP, typeP, clothItem, SHEARSIDE);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 8 -> (x-1, y-1, z)
			typeP.x = col - 1;
			typeP.y = row - 1;
			
			updateForce(curP, typeP, clothItem, SHEARSIDE);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			

			// BEND SPRINGS
			//-----------------------------------------------------------------
			// TYPE 9 -> (x+2, y, z)
			typeP.x = col + 2;
			typeP.y = row;
			
			updateForce(curP, typeP, clothItem, BEND);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 10 -> (x-2, y, z)
			typeP.x = col - 2;
			typeP.y = row;
			
			updateForce(curP, typeP, clothItem, BEND);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 11 -> (x, y+2, z)
			typeP.x = col;
			typeP.y = row + 2;
			
			updateForce(curP, typeP, clothItem, BEND);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
			// TYPE 12 -> (x, y-2, z)
			typeP.x = col;
			typeP.y = row - 2;
			
			updateForce(curP, typeP, clothItem, BEND);
			memset( (void*)&typeP, 0, sizeof(typeP));
			//-----------------------------------------------------------------
		}// for col
	}// for row
	
	for(int row = 0; row < clothItem->height; row++)
	{
		for(int col = 0; col < clothItem->width; col++)
		{
			index = FindIndexInArray(row, col, clothItem->width);

			clothItem->acceleration[index].x = clothItem->force[index].x / clothItem->mass;
			clothItem->acceleration[index].y = clothItem->force[index].y / clothItem->mass;
			clothItem->acceleration[index].z = clothItem->force[index].z / clothItem->mass;
		}
	}
}