コード例 #1
0
ファイル: physics.cpp プロジェクト: yhuili/ComputerAnimation
// calculate the damping force for collision springs
void dampingForceCollision(const point& a, const point& b, const point& va, const point& vb, double kDamp, point& n, point& f)
{
	// initialize temp force f
	f.x = 0;
	f.y = 0;
	f.z = 0;
	point diff;
	point diffVelocity;
	point normalizedDiff;
	double diffLength;
	double elasticForceScalar;
	double cosF;
	// let diff be the vector pointing from b to a
	pDIFFERENCE(a, b, diff);
	diffLength = sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
	// here va and vb are velocities of points a and b
	pDIFFERENCE(va, vb, diffVelocity);
	elasticForceScalar = (-kDamp) * ((diffVelocity.x * diff.x + diffVelocity.y * diff.y + diffVelocity.z * diff.z) / diffLength);
	// normalized vector diff
	normalizedDiff.x = diff.x / diffLength;
	normalizedDiff.y = diff.y / diffLength;
	normalizedDiff.z = diff.z / diffLength;
	pMULTIPLY(normalizedDiff, elasticForceScalar, f);
	DOTPRODUCTp(f, n, cosF);
	pMULTIPLY(n, cosF, f);
}
コード例 #2
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]);
	}
}
コード例 #3
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;
}
コード例 #4
0
/* Function: AreaOfTri
 * Description: Computes the area of a triangle
 * Input: inputModel - three vertices of the triangle
 * Output: Area
 */
double AreaOfTri(point A, point B, point C)
{
	double mside1, mside2; 
	point side1, side2;
	double dot = 0.0;
	
	pDIFFERENCE(A, B, side1);
	pDIFFERENCE(C, B, side2);
	mside1 = vecLeng(A, B);
	mside2 = vecLeng(C, B);
	dot = dotProd(side1, side2);

	if(mside1 > mside2)
		return (sqrt(mside2 * mside2 -  dot * dot) * mside1) / 2.0;
	else
		return (sqrt(mside1 * mside1 -  dot * dot) * mside2) / 2.0;
}
コード例 #5
0
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);
    
}
コード例 #6
0
ファイル: physics.cpp プロジェクト: yhuili/ComputerAnimation
// calculate the hook force for collision springs
void hookForceCollision(const point& a, const point& b, double kHook, point& n, point& f)
{
	// initialize temp force f
	f.x = 0;
	f.y = 0;
	f.z = 0;
	point diff;
	double elasticForceScalar;
	// let diff be the vector pointing from b to a
	pDIFFERENCE(a, b, diff);
	pMULTIPLY(diff, -kHook, diff);
	DOTPRODUCTp(diff, n, elasticForceScalar);
	pMULTIPLY(n, elasticForceScalar, f);
}
コード例 #7
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
コード例 #8
0
ファイル: physics.cpp プロジェクト: yhuili/ComputerAnimation
// calculate the hook force between point a and its the next neighbour point b
void hookForceBend(const point& a, const point& b, double kHook, point& f)
{
	// initialize temp force f
	f.x = 0;
	f.y = 0;
	f.z = 0;
	point diff;
	point normalizedDiff;
	double diffLength;
	double elasticForceScalar;
	// let diff be the vector pointing from b to a
	pDIFFERENCE(a, b, diff);
	diffLength = sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
	// normalized vector diff
	normalizedDiff.x = diff.x / diffLength;
	normalizedDiff.y = diff.y / diffLength;
	normalizedDiff.z = diff.z / diffLength;
	// the elastic force exerted on a is
	elasticForceScalar = (-kHook) * (diffLength - restLengthBend);
	pMULTIPLY(normalizedDiff, elasticForceScalar, f);
}
コード例 #9
0
ファイル: physics.cpp プロジェクト: yhuili/ComputerAnimation
void planeCollisionForce(world * jello, int i, int j, int k, const bool& s, const point& pn, point &a)
{
	if (s == false) // the point collided with the plane
	{
		double distance; 
		point normal;
		double normalLength;
		point normalizedN;
		point pointOnPlane;
		point f;
		point vPlane;
		vPlane.x = 0;
		vPlane.y = 0;
		vPlane.z = 0;
		// D = (ax + by + cz + d) / sqrt(a*a + b*b + c*c)
		distance = (jello->a * jello->p[i][j][k].x + jello->b * jello->p[i][j][k].y + jello->c * jello->p[i][j][k].z + jello->d);
		distance = distance / sqrt(jello->a * jello->a + jello->b * jello->b + jello->c * jello->c);
		
		normalLength = sqrt(pn.x * pn.x + pn.y * pn.y + pn.z * pn.z);
		// normalized normal, get the orientation of the normal
		normalizedN.x = (pn.x / normalLength);
		normalizedN.y = (pn.y / normalLength);
		normalizedN.z = (pn.z / normalLength);
		pMULTIPLY(normalizedN, distance, normalizedN);
		// calculate the point on plane
		pDIFFERENCE(jello->p[i][j][k], normalizedN, pointOnPlane);
		// calculate the direction
		normal.x = (pn.x / normalLength);
		normal.y = (pn.y / normalLength);
		normal.z = (pn.z / normalLength);
		hookForceCollision(jello->p[i][j][k], pointOnPlane, jello->kCollision, normal, f);
		pSUM(f, a, a);
		dampingForceCollision(jello->p[i][j][k], pointOnPlane, jello->v[i][j][k], vPlane, jello->dCollision, normal, f);
		pSUM(f, a, a);
	}
}
コード例 #10
0
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
コード例 #11
0
/* Function: modEuler
 * Description: Modified Euler Integrator using Implicit and Explicit
 *				vi(t + h) = vi(t) + (ALPHA / h) * (gi(t) - xi(t)) + (h / mi) * Fext(t) 
 *				xi(t + h) = xi(t) + h * vi(t + h)
 * Input: None
 * Output: None
 */
void ModEuler(phyzx *phyzxObj, int mIndex, int deformMode)
{
	point vertex, velocity, extVel, position, velDamp;
	point vDiff, velTotal, newPos, temp;
	matrix R, matTemp;

	memset( (void*)&temp, 0, sizeof(temp));
	memset((void*)&extVel, 0, sizeof(point));
	memset((void*)&velocity, 0, sizeof(point));
	memset((void*)&position, 0, sizeof(point));
	memset((void*)&vDiff, 0, sizeof(point));
	memset((void*)&velTotal, 0, sizeof(point));
	memset((void*)&newPos, 0, sizeof(point));
	memset((void*)&phyzxObj->avgVel, 0, sizeof(point));

	matInit(&R, 0, 0);
	matInit(&matTemp, 0, 0);

	if (deformMode == 3)
		quadDeformRot(&R, phyzxObj);

	for (unsigned int index = STARTFROM; index <= phyzxObj->model->numvertices; index++)
	{
		if (deformMode == 3)
		{
			// Compute Quadratic Deformation Goal Positions
			matMult(R, phyzxObj->q[index], &matTemp);						// R(q)
			temp = matToPoint(matTemp);										// Data type conversion
			pSUM(temp, phyzxObj->cmDeformed, phyzxObj->goal[index]);		// g = R(q) + xcm
		} //end if
		else
		{
			// Compute Goal Positions
			matMult3331(phyzxObj->R, phyzxObj->relStableLoc[index], &temp);				// R(xi0 - xcm0)
			pSUM(temp, phyzxObj->cmDeformed, phyzxObj->goal[index]);					// g = R(xi0 - xcm0) + xcm
		} //end if

		vertex.x = phyzxObj->model->vertices[3*index];
		vertex.y = phyzxObj->model->vertices[3*index + 1];
		vertex.z = phyzxObj->model->vertices[3*index + 2];\

		if (stickyFloor == 1)
			if (vertex.y <= -WALLDIST)
				continue;

		// Add user force
		if (mIndex == iMouseModel && lMouseVal == 2 && objectName != -1)// && index == objectName)
		{
			//point uForce;
			/*GLMnode *node;
			node = NBVStruct[objectName];

			while (node->next != NULL)
			{
				pSUM(phyzxObj->extForce[node->index], userForce, phyzxObj->extForce[node->index]);
				node = node->next;
			} //end while*/
			/*if (index != objectName)
			{
				point extPos = vMake(phyzxObj->model->vertices[3*objectName], phyzxObj->model->vertices[3*objectName+1], phyzxObj->model->vertices[3*objectName+2]);
				double dist = vecLeng(extPos, vertex);
				//if (dist > 0.04)
				//{
					pMULTIPLY(userForce, (1.0/dist), uForce);
					pSUM(phyzxObj->extForce[index], uForce, phyzxObj->extForce[index]);
					//pDisp("user", userForce);
				//} //end if
				//else
				//{
					//pSUM(phyzxObj->extForce[index], userForce, phyzxObj->extForce[index]);
				//} //end else
			} //end if
			else
			{*/
				pSUM(phyzxObj->extForce[index], userForce, phyzxObj->extForce[index]);
			//} //end else
		} //end if

		// Explicit Euler Integrator for veloctiy -> vi(t + h)
		pDIFFERENCE(phyzxObj->goal[index], vertex, vDiff);												// gi(t) - xi(t)
		pMULTIPLY(vDiff, (phyzxObj->alpha / phyzxObj->h), velocity);									// vi(h) = (ALPHA / h) * (gi(t) - xi(t))
		pMULTIPLY(phyzxObj->extForce[index], (phyzxObj->h / phyzxObj->mass[index]), extVel);			// (h / mi) * Fext(t)
//		pMULTIPLY(phyzxObj->extForce[index], phyzxObj->h, extVel);			// (h / mi) * Fext(t)
		pSUM(velocity, extVel, velTotal);																// vi(h) = (ALPHA / h) * (gi(t) - xi(t)) + (h / mi) * Fext(t) 

		pSUM(phyzxObj->velocity[index], velTotal, phyzxObj->velocity[index]);							// vi(t + h) = vi(t) + vi(h)
		
		// Velocity Damping
		pMULTIPLY(phyzxObj->velocity[index], -phyzxObj->delta, velDamp);
		pSUM(phyzxObj->velocity[index], velDamp, phyzxObj->velocity[index]);

		// Implicity Euler Integrator for position
		pMULTIPLY(phyzxObj->velocity[index], phyzxObj->h, position);									// xi(h) = h * vi(t + h)
		pSUM(vertex, position, newPos);																// xi(t + h) = xi(t) + xi(h)

		// Store new position into data structure
		phyzxObj->model->vertices[3*index] = newPos.x;
		phyzxObj->model->vertices[3*index + 1] = newPos.y;
		phyzxObj->model->vertices[3*index + 2] = newPos.z;

		pSUM(phyzxObj->avgVel, phyzxObj->velocity[index], phyzxObj->avgVel);

		//if (objCollide)
			CheckForCollision(index, phyzxObj, mIndex);
	} //end for

	pMULTIPLY(phyzxObj->avgVel, 1.0 / phyzxObj->model->numvertices, phyzxObj->avgVel);

	delete[] R.data;
	delete[] matTemp.data;
} //end ModEuler()
コード例 #12
0
/* 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