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); }
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(); }
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(); }
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; }
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(); }