예제 #1
0
void ReleaseNx()
{
    if (gScene)
	{
		for (MyCloth** cloth = gCloths.begin(); cloth != gCloths.end(); cloth++)
			delete *cloth;
		gCloths.clear();
		gPhysicsSDK->releaseScene(*gScene);
	}
	if (gPhysicsSDK)  NxReleasePhysicsSDK(gPhysicsSDK);
    NX_DELETE_SINGLE(gAllocator);
}
예제 #2
0
void TickCar()
{
	NxReal steeringAngle = gSteeringValue * gMaxSteeringAngle;

	NxArray<CarWheelContact>::iterator i = wheelContactPoints.begin();
	while(i != wheelContactPoints.end())
	{
		CarWheelContact& cwc = *i;

		WheelShapeUserData* wheelData = (WheelShapeUserData *)(cwc.wheel->userData);

		//apply to powered wheels only.
		if (wheelData->frontWheel)
	    {
			//steering:
			NxMat33 wheelOrientation = cwc.wheel->getLocalOrientation();
			wheelOrientation.setColumn(0,  NxVec3(NxMath::cos(steeringAngle), 0,  NxMath::sin(steeringAngle) ));
			wheelOrientation.setColumn(2,  NxVec3(NxMath::sin(steeringAngle), 0, -NxMath::cos(steeringAngle) ));
			cwc.wheel->setLocalOrientation(wheelOrientation);

			if (frontWheelIsPowered)
			{
				//get the world space orientation:
				wheelOrientation = cwc.wheel->getGlobalOrientation();
				NxVec3 steeringDirection;
				wheelOrientation.getColumn(0, steeringDirection);

				//the power direction of the front wheel is the wheel's axis as it is steered.
				if (gMotorForce)
				{
					cwc.car->addForceAtPos(steeringDirection * gMotorForce,cwc.contactPoint);
				}
			}
		}
		if (!wheelData->frontWheel && rearWheelIsPowered)
		{
			//get the orientation of this car:
			NxMat33 m = cwc.car->getGlobalOrientation();
			NxVec3 carForwardAxis;
			m.getColumn(0, carForwardAxis);
			//the power direction of the rear wheel is always the car's length axis.
			cwc.car->addForceAtPos(carForwardAxis * gMotorForce,cwc.contactPoint);
		}
		i++;
	}

	wheelContactPoints.clear();
}
예제 #3
0
void RenderCallback()
{
    if (gScene && !bPause)
	{
		StartPhysics();	
		GetPhysicsResults();
	}

    // Clear buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	ProcessInputs();
	ProcessCameraKeys();
	SetupCamera();

 	RenderActors(bShadows);

    // Render all the cloths in the scene
	for (MyCloth **cloth = gCloths.begin(); cloth != gCloths.end(); cloth++)
	{
		glColor4f(1.0f, 0.0f, 0.0f,1.0f);
		(*cloth)->draw(bShadows);
	}

	if (bForceMode)
		DrawForce(gSelectedActor, gForceVec, NxVec3(1,1,0));
	else
		DrawForce(gSelectedActor, gForceVec, NxVec3(0,1,1));
	gForceVec = NxVec3(0,0,0);

	// Render HUD
	hud.Render();

    glFlush();
    glutSwapBuffers();
}
예제 #4
0
void VertexWelder::update(NxMeshData meshData)
{
	assert(mWriteVerticesPtr != NULL);

	bool updateVertices = (*(meshData.dirtyBufferFlagsPtr) & (NX_MDF_VERTICES_POS_DIRTY | NX_MDF_VERTICES_NORMAL_DIRTY)) > 0;
	bool updateIndices = (*(meshData.dirtyBufferFlagsPtr) & (NX_MDF_INDICES_DIRTY | NX_MDF_PARENT_INDICES_DIRTY)) > 0;

	NxU32 numNewVertices = *meshData.numVerticesPtr;
	NxU32 numTriangles = *meshData.numIndicesPtr / 3;
	NxU32 oldMappingDomain = mMappingDomain;
	
	NxArray<NewVertex> newVertices;
	NxArray<DifficultVertex> difficultVertices;

	mMappingDomainAddition = 0;

	if (updateVertices)
	{
		
		if (mMappingDomain < numNewVertices)
		{
#ifdef DEBUG_WELDER
			printf("------------------------------------\n");
#endif
			for (NxU32 i = mMappingDomain; i < numNewVertices; i++)
			{
				NewVertex v;
				v.index = i;
				v.parent = *(NxU32*)(((char*)meshData.parentIndicesBegin) + meshData.parentIndicesByteStride * i);
				while (v.parent >= (NxI32)mMappingDomain) {
					v.parent = *(NxU32*)(((char*)meshData.parentIndicesBegin) + meshData.parentIndicesByteStride * v.parent);
				}
#ifdef DEBUG_WELDER
				printf("New Vertex: %d %d\n", v.index, v.parent);
#endif
				newVertices.push_back(v);
			}
			std::sort(newVertices.begin(), newVertices.end(), sortParent);
		}
		
		for (NxU32 i = 0; i < mMappingSize; i++)
		{
			NxU32 mappedIndex = getMapping(i);

			NewVertex newV;
			newV.parent = mappedIndex;
			// Find all vertices that are a parent for a newly created vertex
			NxArray<NewVertex>::iterator found = std::lower_bound(newVertices.begin(), newVertices.end(), newV, sortParent);
			while (found != NULL && found->parent == mappedIndex)
			{
				found->mappedVertices ++;
				if (found->mappedVertices == 1)
				{
					found->unMapParent = i;
#ifdef DEBUG_WELDER
					printf("New Vertex Update, %d %d %d\n", found->index, found->parent, found->unMapParent);
#endif
				}
				else
				{
					// several unmapped parents
					DifficultVertex v;
					v.mappedIndex = found->index;
					v.unMappedIndex = i;
					difficultVertices.push_back(v);
#ifdef DEBUG_WELDER
					printf("Difficult Vertex %d %d\n", v.unMappedIndex, v.mappedIndex);
#endif

					if (found->mappedVertices == 2)
					{
						v.unMappedIndex = found->unMapParent;
						difficultVertices.push_back(v);
#ifdef DEBUG_WELDER
						printf("Difficult Vertex %d %d\n", v.unMappedIndex, v.mappedIndex);
#endif
					}

					found->unMapParent = -2;
				}
				found++;
			}
			

			NxVec3& vertex = *(NxVec3*)(((char*)mWriteVerticesPtr) + mWriteVerticesStride * i);
			NxVec3& normal = *(NxVec3*)(((char*)mWriteNormalsPtr) + mWriteNormalsStride* i);
			//float* texCoord = (float*)(((char*)texCoords) + texStride * i);

			const NxVec3& oldVertex = *(NxVec3*)(((char*)meshData.verticesPosBegin) + meshData.verticesPosByteStride * mappedIndex);
			const NxVec3& oldNormal = *(NxVec3*)(((char*)meshData.verticesNormalBegin) + meshData.verticesNormalByteStride * mappedIndex);

			vertex = oldVertex;
			normal = oldNormal;
		}
		// Adapt the mapping table
		std::sort(newVertices.begin(), newVertices.end(), sortIndex);
		std::sort(difficultVertices.begin(), difficultVertices.end(), sortDifficultExt);	
	}

	if (updateIndices)
	{
		std::vector<bool> bitVector(mMappingSpace, false);
#ifdef DEBUG_WELDER
		printf("updateIndices: Vertices: %d, Indices %d, gfx Vertices: %d\n", *meshData.numVerticesPtr, *meshData.numIndicesPtr, mMappingSize);
#endif
		if (difficultVertices.size() > 0)
		{
#ifdef DEBUG_WELDER
			printf("    Difficult Vertices:\n");
#endif
			for (NxU32 i = 0; i < difficultVertices.size(); i++)
			{
				DifficultVertex& v = difficultVertices[i];
#ifdef DEBUG_WELDER
				printf("      V %d %d\n", v.unMappedIndex, v.mappedIndex);
#endif
			}
		}
		assert((meshData.flags & NX_MF_16_BIT_INDICES) == 0);
		assert(meshData.indicesByteStride == 4);
		for (NxU32 i = 0; i < numTriangles; i++)
		{
			const NxU32* simTriangle = (NxU32*)(((char*)meshData.indicesBegin) + meshData.indicesByteStride * (i*3));
			NxU32* gfxTriangle = (NxU32*)(((char*)mWriteIndicesPtr) + mWriteIndicesStride* i);
			
			if (simTriangle[0] == simTriangle[1] && simTriangle[1] == simTriangle[2])
			{
				// Face was deleted (outside valid bounds probably)
				gfxTriangle[0] = gfxTriangle[1] = gfxTriangle[2] = 0;
				continue;
			}
			for (NxU32 j = 0; j < 3; j++)
			{

				DifficultVertex v;
				v.mappedIndex = simTriangle[j];
				v.unMappedIndex = gfxTriangle[j];
				if (std::binary_search(difficultVertices.begin(), difficultVertices.end(), v, sortDifficult))
				{
					NxArray<DifficultVertex>::iterator it = std::lower_bound(difficultVertices.begin(), difficultVertices.end(), v, sortDifficultExt);
#ifdef DEBUG_WELDER
					printf("-- Triangle %d (%d) (%d %d %d) (%d %d %d)", i, j, simTriangle[0], simTriangle[1], simTriangle[2], gfxTriangle[0], gfxTriangle[1], gfxTriangle[2]);
					printf(" %d %d\n", v.unMappedIndex, v.mappedIndex);
#endif

					if (it == NULL || it->mappedIndex != simTriangle[j])
					{
						// element hasn't been found

						//insert element
#ifdef DEBUG_WELDER
						printf("Adding Diff %d %d\n", v.unMappedIndex, v.mappedIndex);
#endif
						difficultVertices.push_back(v);

						// sort now, don't know whether this could be done less often, so far the list is extremely small
						std::sort(difficultVertices.begin(), difficultVertices.end(), sortDifficultExt);

						// get the freshly created item
						it = std::lower_bound(difficultVertices.begin(), difficultVertices.end(), v, sortDifficultExt);

						// element has to exist
						assert(it != NULL);
					}

					if (it->newUnMappedIndex >= 0)
					{
						gfxTriangle[j] = it->newUnMappedIndex;
					}
					else if (bitVector[it->unMappedIndex])
					{
#ifdef DEBUG_WELDER
						printf("Bit %d is true\n", it->unMappedIndex);
#endif
						// create a new gfx vertex
						it->newUnMappedIndex = mMappingSize;
						addNewVertex(gfxTriangle[j]);
						setMapping(it->newUnMappedIndex, simTriangle[j]);
						gfxTriangle[j] = it->newUnMappedIndex;
						bitVector[it->newUnMappedIndex] = true;
					}
					else
					{
#ifdef DEBUG_WELDER
						printf("Set Bit %d to true\n", it->unMappedIndex);
#endif
						bitVector[it->unMappedIndex] = true;
						it->newUnMappedIndex = it->unMappedIndex;
						setMapping(it->newUnMappedIndex, simTriangle[j]);
					}
				}
				else if (simTriangle[j] >= oldMappingDomain) // only used when not a difficult vertex
				{
					// unamp index and update
					for (NxU32 k = 0; k < newVertices.size(); k++)
					{
						NewVertex& v = newVertices[k];
						if (v.index == simTriangle[j] && v.mappedVertices == 1)
						{
#ifdef DEBUG_WELDER
							printf("- Triangle %d (%d %d %d) (%d %d %d)", i, simTriangle[0], simTriangle[1], simTriangle[2], gfxTriangle[0], gfxTriangle[1], gfxTriangle[2]);
							printf(" %d %d\n", v.unMapIndex, v.index);
#endif
							if (v.unMapIndex == -1)
							{
#ifdef DEBUG_WELDER
								printf("Add Simple\n");
#endif
								v.unMapIndex = mMappingSize;
								//addNewVertex(vertices, vertexStride, normals, normalStride, texCoords, texStride, v.unMapParent);
								addNewVertex(gfxTriangle[j]);
								gfxTriangle[j] = v.unMapIndex;
								setMapping(v.unMapIndex, v.index);
							}
							else
							{
#ifdef DEBUG_WELDER
								printf("Use Simple\n");
#endif
								gfxTriangle[j] = v.unMapIndex;
							}
							break; // for (k)
						}
					}
				}
			}
		}
	}

	if (updateVertices)
	{
		mMappingDomain = *meshData.numVerticesPtr;

#ifdef DEBUG_WELDER
		static bool sanityCheck = true;
		if (sanityCheck)
		{
			// sanity check
			NxU32 temp = 0;
			for (NxU32 i = 0; i < mMappingSize; i++)
			{
				temp = NxMath::max(getMapping(i), temp);
			}
			if (temp != mMappingDomain - 1)
			{
				printf("Mapping Domain not right, is %d, should be %d\n", temp, mMappingDomain-1);
				assert(0);
			}
			for (NxU32 i = 0; i < numTriangles; i++)
			{
				const NxU32* simTriangle = (NxU32*)(((char*)meshData.indicesBegin) + meshData.indicesByteStride * (i*3));
				NxU32* gfxTriangle = (NxU32*)(((char*)mWriteIndicesPtr) + mWriteIndicesStride * i);
				for (NxU32 j = 0; j < 3; j++)
				{
					if (simTriangle[j] != getMapping(gfxTriangle[j]))
					{
						printf("Triangle %d (%d) not correct (%d %d %d) -> (%d %d %d) != (%d %d %d)\n",
							i, 3*i+j,
							gfxTriangle[0], gfxTriangle[1], gfxTriangle[2],
							getMapping(gfxTriangle[0]), getMapping(gfxTriangle[1]), getMapping(gfxTriangle[2]),
							simTriangle[0], simTriangle[1], simTriangle[2]);
						assert(0);
					}
				}
			}
		}
#endif
	}

	return;
}
예제 #5
0
void TickCar ( void )
{
	g_iValue = 10;

	NxReal steeringAngle = gSteeringValue * gMaxSteeringAngle;

	NxArray<CarWheelContact>::iterator i = wheelContactPoints.begin();
	while(i != wheelContactPoints.end())
	{
		CarWheelContact& cwc = *i;

		WheelShapeUserData* wheelData = (WheelShapeUserData *)(cwc.wheel->userData);

		/*
		struct CarWheelContact
		{
			NxActor* car;
			NxShape* wheel;
			NxVec3 contactPoint;
			NxVec3 contactNormalForce;
			NxVec3 contactFrictionForce;
		};
		*/

		{
			NxMat34 pose   = cwc.wheel->getGlobalPose ( );
			NxMat33 orient = pose.M;
			NxVec3  pos    = pose.t;

			float glmat[16];
			orient.getColumnMajorStride4(&(glmat[0]));
			pos.get(&(glmat[12]));
			glmat[3] = glmat[7] = glmat[11] = 0.0f;
			glmat[15] = 1.0f;

			SetWorldMatrix ( g_iValue, ( D3DXMATRIX* ) &glmat );
			sObject* pObject = dbGetObject ( g_iValue );
			pObject->position.vecPosition = D3DXVECTOR3 ( glmat [ 12 ], glmat [ 13 ], glmat [ 14 ] );

			//dbPositionObject ( g_iValue, glmat [ 12 ], glmat [ 13 ], glmat [ 14 ] );

			g_iValue++;
		}

		//apply to powered wheels only.
		if (wheelData->frontWheel)
	    {
			//steering:
			NxMat33 wheelOrientation = cwc.wheel->getLocalOrientation();
			wheelOrientation.setColumn(0,  NxVec3(NxMath::cos(steeringAngle), 0,  NxMath::sin(steeringAngle) ));
			wheelOrientation.setColumn(2,  NxVec3(NxMath::sin(steeringAngle), 0, -NxMath::cos(steeringAngle) ));
			cwc.wheel->setLocalOrientation(wheelOrientation);

			if (frontWheelIsPowered)
			{
				//get the world space orientation:
				wheelOrientation = cwc.wheel->getGlobalOrientation();
				NxVec3 steeringDirection;
				wheelOrientation.getColumn(0, steeringDirection);

				//the power direction of the front wheel is the wheel's axis as it is steered.
				if (gMotorForce)
				{
					cwc.car->addForceAtPos(steeringDirection * gMotorForce,cwc.contactPoint);
				}
			}
		}
		if (!wheelData->frontWheel && rearWheelIsPowered)
		{
			//get the orientation of this car:
			NxMat33 m = cwc.car->getGlobalOrientation();
			NxVec3 carForwardAxis;
			m.getColumn(0, carForwardAxis);
			//the power direction of the rear wheel is always the car's length axis.
			cwc.car->addForceAtPos(carForwardAxis * gMotorForce,cwc.contactPoint);
		}
		i++;
	}

	wheelContactPoints.clear();
}