bool CPhysicsManager::ReleasePhysicActor (CPhysicActor* actor) { assert(actor != NULL); assert(m_pScene != NULL); assert(m_pPhysicsSDK != NULL); bool isOk = false; NxActor* nxActor = actor->GetPhXActor(); if( nxActor != 0) { NxArray<NxCCDSkeleton*> skeletons; for (NxU32 i = 0; i < nxActor->getNbShapes(); i++) { NxShape* shape = nxActor->getShapes()[i]; if (shape->getCCDSkeleton() != NULL) { skeletons.pushBack(shape->getCCDSkeleton()); } } for (NxU32 i = 0; i < skeletons.size(); i++) { m_pPhysicsSDK->releaseCCDSkeleton(*skeletons[i]); } m_pScene->releaseActor(*nxActor); nxActor = 0; } return true; }
//---------------------------------------------------------------------------- // ReleaseAllActors : Alliberem tots els actors de l'escena de PhysX //---------------------------------------------------------------------------- bool CPhysicsManager::ReleaseAllActors ( void ) //EUserDataFlag _eFlags ) { assert ( m_pScene != NULL ); assert ( m_pPhysicsSDK != NULL ); bool isOk = true; NxActor** l_ppActorList = m_pScene->getActors(); NxU32 l_TotalActors = m_pScene->getNbActors(); while ( l_TotalActors -- ) { NxActor* nxActor = *l_ppActorList; if ( nxActor != 0) { NxArray<NxCCDSkeleton*> skeletons; for (NxU32 i = 0; i < nxActor->getNbShapes(); i++) { NxShape* shape = nxActor->getShapes()[i]; if (shape->getCCDSkeleton() != NULL) { skeletons.pushBack(shape->getCCDSkeleton()); } } for (NxU32 i = 0; i < skeletons.size(); i++) { m_pPhysicsSDK->releaseCCDSkeleton(*skeletons[i]); } m_pScene->releaseActor(*nxActor); nxActor = 0; } } return isOk; }
// ---------------------------------------------------------------------------------------------------------- void MeshHash::query(const NxBounds3 &bounds, NxArray<int> &itemIndices, int maxIndices) { int x1,y1,z1; int x2,y2,z2; int x,y,z; cellCoordOf(bounds.min, x1,y1,z1); cellCoordOf(bounds.max, x2,y2,z2); itemIndices.clear(); for (x = x1; x <= x2; x++) { for (y = y1; y <= y2; y++) { for (z = z1; z <= z2; z++) { int h = hashFunction(x,y,z); MeshHashRoot &r = mHashIndex[h]; if (r.timeStamp != mTime) continue; int i = r.first; while (i >= 0) { MeshHashEntry &entry = mEntries[i]; itemIndices.push_back(entry.itemIndex); if (maxIndices >= 0 && (int)itemIndices.size() >= maxIndices) return; i = entry.next; } } } } }
static void RenderTerrain() { if(gTerrainData) { renderTerrainTriangles(*gTerrainData, gTouchedTris.size(), &gTouchedTris[0]); renderTerrain(*gTerrainData); } }
// Create a static trigger static void CreateTrigger(const NxVec3& pos, NxF32 size = 2, const NxVec3* initial_velocity=NULL, bool kinematic = false) { // Our trigger is a cube NxBodyDesc triggerBody; NxBoxShapeDesc dummyShape; NxBoxShapeDesc BoxDesc; BoxDesc.dimensions = NxVec3(size, size, size); BoxDesc.shapeFlags |= NX_TRIGGER_ENABLE; NxActorDesc ActorDesc; if(initial_velocity || kinematic) { if (initial_velocity) { triggerBody.linearVelocity = *initial_velocity; } if (kinematic) { triggerBody.flags |= NX_BF_KINEMATIC; } triggerBody.mass = 1; ActorDesc.body = &triggerBody; NxF32 sizeinc = 1.01f; dummyShape.dimensions.set(size*sizeinc, size*sizeinc, size*sizeinc); dummyShape.group = 1; ActorDesc.shapes.pushBack(&dummyShape); } ActorDesc.shapes.pushBack(&BoxDesc); ActorDesc.globalPose.t = pos; int thisNb = ++gNbTriggers; gNbTouchedBodies.pushBack(0); NX_ASSERT(gNbTouchedBodies.size() == gNbTriggers); gMyPhysX.getScene()->setGroupCollisionFlag(1,0, false); gMyPhysX.getScene()->setGroupCollisionFlag(1,1, false); gMyPhysX.getScene()->setGroupCollisionFlag(1,2, true); ActorDesc.userData = (void*)(-thisNb); if (!ActorDesc.isValid()) { printf("Invalid ActorDesc\n"); return; } NxActor* actor = gMyPhysX.getScene()->createActor(ActorDesc); // This is just a quick-and-dirty way to identify the trigger for rendering NX_ASSERT(actor != NULL); if (kinematic) { KinematicActor k; k.actor = actor; if (initial_velocity) { k.vel = *initial_velocity; } else { k.vel.set(0,0,0); } gKinematicActors.pushBack(k); } gMyPhysX.getScene()->setUserTriggerReport(&myTriggerCallback); }
// ---------------------------------------------------------------------------------------------------------- void MeshHash::compressIndices(NxArray<int> &itemIndices) { if (itemIndices.size() == 0) return; // sort results quickSort(itemIndices, 0, itemIndices.size()-1); // mark duplicates int i = 0; while (i < (int)itemIndices.size()) { int j = i+1; while (j < (int)itemIndices.size() && itemIndices[i] == itemIndices[j]) { itemIndices[j] = -1; j++; } i = j; } // remove duplicates i = 0; while (i < (int)itemIndices.size()) { if (itemIndices[i] < 0) { itemIndices[i] = itemIndices[itemIndices.size()-1]; itemIndices.pop_back(); } else i++; } }
// ---------------------------------------------------------------------------------------------------------- void MeshHash::query(const NxVec3 &pos, NxArray<int> &itemIndices, int maxIndices) { int x,y,z; cellCoordOf(pos, x,y,z); itemIndices.clear(); int h = hashFunction(x,y,z); MeshHashRoot &r = mHashIndex[h]; if (r.timeStamp != mTime) return; int i = r.first; while (i >= 0) { MeshHashEntry &entry = mEntries[i]; itemIndices.push_back(entry.itemIndex); if (maxIndices >= 0 && (int)itemIndices.size() >= maxIndices) return; i = entry.next; } }
void SetHelpString(const char *demoKeyString) { char tempString[512]; sprintf(gHelpString, "\nGeneral:\n"); #ifdef __PPCGEKKO__ sprintf(gHelpString, " +,-: choose scene\n"); strcat(gHelpString, " arrows: move/strafe\n"); strcat(gHelpString, " b: shoot sphere\n"); strcat(gHelpString, " HOME: toggle help\n"); strcat(gHelpString, " 1: Reset scene\n"); if(gSampleIndex == 6) strcat(gHelpString, " 2: toggle debug rendering\n"); #else sprintf(tempString, " 1-%d: choose scene\n", gSamples.size()); strcat(gHelpString, tempString); strcat(gHelpString, " p: pause\n"); strcat(gHelpString, " o: single step\n"); #ifndef NX_DISABLE_HARDWARE strcat(gHelpString, " h: hardware on/off\n"); #endif strcat(gHelpString, " w,a,s,d: move/strafe\n"); strcat(gHelpString, " q,e: move up/down\n"); strcat(gHelpString, " mouse right: pick\n"); strcat(gHelpString, " space: shoot sphere\n"); strcat(gHelpString, " x: toggle shadows\n"); strcat(gHelpString, " n: toggle wireframe\n"); strcat(gHelpString, " F1: toggle help\n"); strcat(gHelpString, " F3,F4: pick push/pull\n"); strcat(gHelpString, " F5: toggle debug rendering\n"); strcat(gHelpString, " F9: toggle vsync\n"); strcat(gHelpString, " F10: Reset scene\n"); #endif if (demoKeyString) { strcat(gHelpString, "\nDemo specific:\n"); strcat(gHelpString, demoKeyString); } }
// 增加一辆车 NxVehicle* NxAllVehicle::addVehicle(const NxVec3& pos, VehicleInfo vinfo, std::string name, NxScene* nxScene, NxPhysicsSDK* nxPhysics) { NxVehicleDesc vehicleDesc; NxBoxShapeDesc boxShapes[2]; NxConvexShapeDesc carShape[2]; NxArray<NxVec3> points; NxArray<NxVec3> points2; NxReal halfWidth = vinfo.width / 2;//1.1529f; NxReal halfLength = vinfo.length / 2;//2.5278f; NxReal halfHeight = vinfo.height / 2; //0.6027; points.pushBack().set(halfLength,-halfHeight * 0.1f, 0); points.pushBack().set(halfLength * 0.7f, 0, 0); points.pushBack().set(0.2f * halfLength, halfHeight * 0.2f, 0); points.pushBack().set(-halfLength, halfHeight * 0.2f, 0); points.pushBack().set(0.1*halfLength, halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(0.1*halfLength, halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(-0.8*halfLength, halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(-0.8*halfLength, halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(halfLength * 0.9f,-halfHeight * 0.25f, halfWidth * 0.8f); points.pushBack().set(halfLength * 0.9f,-halfHeight * 0.25f,-halfWidth * 0.8f); points.pushBack().set(0,-halfHeight * 0.2f, halfWidth); points.pushBack().set(0,-halfHeight * 0.2f,-halfWidth); points.pushBack().set(-halfLength * 0.9f,-halfHeight * 0.2f, halfWidth * 0.9f); points.pushBack().set(-halfLength * 0.9f,-halfHeight * 0.2f,-halfWidth * 0.9f); points.pushBack().set(halfLength * 0.8f, -halfHeight, halfWidth * 0.79f); points.pushBack().set(halfLength * 0.8f, -halfHeight,-halfWidth * 0.79f); points.pushBack().set(-halfLength * 0.8f, -halfHeight, halfWidth * 0.79f); points.pushBack().set(-halfLength * 0.8f, -halfHeight,-halfWidth * 0.79f); for(NxU32 i = 2; i < 8; i++) { points2.pushBack(points[i]); } points2.pushBack().set(-0.5*halfLength, halfHeight*0.8f, halfWidth*0.7f); points2.pushBack().set(-0.5*halfLength, halfHeight*0.8f,-halfWidth*0.7f); points2.pushBack().set(-0.7*halfLength, halfHeight*0.7f, halfWidth*0.7f); points2.pushBack().set(-0.7*halfLength, halfHeight*0.7f,-halfWidth*0.7f); static NxConvexMeshDesc convexMesh; convexMesh.numVertices = points.size(); convexMesh.points = &(points[0].x); convexMesh.pointStrideBytes = sizeof(NxVec3); convexMesh.flags |= NX_CF_COMPUTE_CONVEX|NX_CF_USE_LEGACY_COOKER; MemoryWriteBuffer buf; bool status = NxCookConvexMesh(convexMesh, buf); if(status) { carShape[0].meshData = nxPhysics->createConvexMesh(MemoryReadBuffer(buf.data)); vehicleDesc.carShapes.pushBack(&carShape[0]); } static NxConvexMeshDesc convexMesh2; convexMesh2.numVertices = points2.size(); convexMesh2.points = (&points2[0].x); convexMesh2.pointStrideBytes = sizeof(NxVec3); convexMesh2.flags = NX_CF_COMPUTE_CONVEX|NX_CF_USE_LEGACY_COOKER; MemoryWriteBuffer buf2; status = NxCookConvexMesh(convexMesh2, buf2); if(status) { carShape[1].meshData = nxPhysics->createConvexMesh(MemoryReadBuffer(buf2.data)); vehicleDesc.carShapes.pushBack(&carShape[1]); } vehicleDesc.position = pos; vehicleDesc.mass = vinfo.mass;//1200;//monsterTruck ? 12000 : vehicleDesc.digitalSteeringDelta = vinfo.steerablity;//0.04f; vehicleDesc.steeringMaxAngle = vinfo.maxSteeringAngle; //30.f; vehicleDesc.motorForce = vinfo.maxAcceleraion * vinfo.mass;//3500.f;//monsterTruck?180.f: NxVehicleMotorDesc motorDesc; NxVehicleGearDesc gearDesc; NxReal wheelRadius = 0.4f; vehicleDesc.maxVelocity = vinfo.maxVelocity; //80.f;//(monsterTruck)?40.f:80.f; motorDesc.setToCorvette(); vehicleDesc.motorDesc = &motorDesc; gearDesc.setToCorvette(); vehicleDesc.gearDesc = &gearDesc; vehicleDesc.differentialRatio = 3.42f; wheelRadius = 0.3622f; vehicleDesc.centerOfMass.set(0,-0.7f,0); NxWheelDesc wheelDesc[4]; for(NxU32 i=0;i<4;i++) { wheelDesc[i].wheelApproximation = 10; //wheelDesc[i].wheelFlags |= NX_WF_BUILD_LOWER_HALF; wheelDesc[i].wheelRadius = wheelRadius;//(monsterTruck)?wheelRadius*3.f:wheelRadius; wheelDesc[i].wheelWidth = 0.1923f;//(monsterTruck)?0.3f:0.1923f; wheelDesc[i].wheelSuspension = 0.2f;//(monsterTruck)?0.6f:0.2f; wheelDesc[i].springRestitution = 7000;//monsterTruck?(crovette?5000:4000):7000; wheelDesc[i].springDamping = 800; wheelDesc[i].springBias = 0.0f; // 设为1.0后居然会出错!!!!!!!! //wheelDesc[i].maxHandBraking = 1.f; //monsterTruck?0.5f:1.f; wheelDesc[i].inverseWheelMass = 4.0f / vinfo.maxAcceleraion; // 换算成动力 wheelDesc[i].frictionToFront = 1.f; wheelDesc[i].frictionToSide = 2.f; vehicleDesc.carWheels.pushBack(&wheelDesc[i]); } NxReal heightPos = -0.3622f; //(monsterTruck)?1.f: wheelDesc[0].position.set( 1.02f, heightPos, 1.26); wheelDesc[1].position.set( 1.12f, heightPos,-1.54); wheelDesc[2].position.set(-1.02f, heightPos, 1.26); wheelDesc[3].position.set(-1.12f, heightPos,-1.54); NxU32 flags = NX_WF_BUILD_LOWER_HALF; wheelDesc[0].wheelFlags |= ((vinfo.driven==FrontDriven)?NX_WF_ACCELERATED:0) | NX_WF_STEERABLE_INPUT | flags; wheelDesc[1].wheelFlags |= ((vinfo.driven==FrontDriven)?NX_WF_ACCELERATED:0) | NX_WF_STEERABLE_INPUT | flags; wheelDesc[2].wheelFlags |= ((vinfo.driven==BackDriven)?NX_WF_ACCELERATED:0) | NX_WF_AFFECTED_BY_HANDBRAKE | flags; wheelDesc[3].wheelFlags |= ((vinfo.driven==BackDriven)?NX_WF_ACCELERATED:0) | NX_WF_AFFECTED_BY_HANDBRAKE | flags; vehicleDesc.steeringSteerPoint.set(1.8, 0, 0); vehicleDesc.steeringTurnPoint.set(-1.5, 0, 0); NxVehicle* vehicle = NxVehicle::createVehicle(nxScene, &vehicleDesc, name); NxQuat q; // 少转过90度,可能会有问题 q.fromAngleAxis(90.0f, NxVec3(0.0f, 1.0f, 0.0f)); vehicle->getActor()->setGlobalOrientationQuat(q); vehicle->mVInfo = vinfo; vehicle->setOilAmount(vinfo.oilAmount); // 加到队列中 mAllVehicle.pushBack(vehicle); mIsLive.pushBack(0); // miUserVehicle = mAllVehicle.size() - 1; return vehicle; }
// ----------------------------------------------------------------------- void VertexWelder::initialize(const NxClothMeshDesc& unweldedMesh) { NxArray<NxU32> mapping; NxReal squaredEpsilon = mEpsilon * mEpsilon; for (NxU32 i = 0; i < unweldedMesh.numVertices; i++) { const NxVec3& curVec = *(const NxVec3*)(((const char*)unweldedMesh.points) + (i * unweldedMesh.pointStrideBytes)); // Find Vertex in newVertices NxU32 newIndex = 0; for (newIndex = 0; newIndex < mNewVertices.size(); newIndex++) { NxVec3& newVec = mNewVertices[newIndex]; if ((mEpsilon == 0 && newVec == curVec) || (newVec.distanceSquared(curVec) < squaredEpsilon)) //if (newVec == curVec) { break; } } if (newIndex == mNewVertices.size()) { // Not found in previous list mNewVertices.push_back(curVec); } mapping.push_back(newIndex); } // Store mapping mMappingSize = mapping.size(); mMappingSpace = unweldedMesh.numTriangles * 3; mMappingDomain = mNewVertices.size(); mMapping = (NxU32*)malloc(sizeof(NxU32) * mMappingSpace); memcpy(mMapping, &mapping[0], sizeof(NxU32) * mMappingSize); memset(((NxU32*)mMapping) + mMappingSize, 0, sizeof(NxU32) * (mMappingSpace - mMappingSize)); mapping.clear(); if (mNewVertices.size() < unweldedMesh.numVertices) { mUsed = true; } else { return; } if (unweldedMesh.flags & NX_MF_16_BIT_INDICES) { mNewFaces16 = (NxU16*)malloc(sizeof(NxU16) * unweldedMesh.numTriangles * 3); } else { mNewFaces32 = (NxU32*)malloc(sizeof(NxU32) * unweldedMesh.numTriangles * 3); } for (NxU32 i = 0; i < unweldedMesh.numTriangles; i++) { NxU32 triangles[3]; const char* triangleChar = ((const char*)unweldedMesh.triangles) + (unweldedMesh.triangleStrideBytes * i); if (mNewFaces16) { const NxU16* tris = (const NxU16*)triangleChar; triangles[0] = tris[0]; triangles[1] = tris[1]; triangles[2] = tris[2]; } else { assert(mNewFaces32 != NULL); const NxU32* tris = (const NxU32*)triangleChar; triangles[0] = tris[0]; triangles[1] = tris[1]; triangles[2] = tris[2]; } for (NxU32 j = 0; j < 3; j++) { triangles[j] = getMapping(triangles[j]); } if (mNewFaces16) { for (NxU32 j = 0; j < 3; j++) { mNewFaces16[3*i+j] = (NxU16)(triangles[j] & 0xffff); } } else { for (NxU32 j = 0; j < 3; j++) { mNewFaces32[3*i+j] = triangles[j]; } } } }
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; }
bool NxuPhysicsExport::Write(NxJoint *j,const char *userProperties,const char *id) { bool ret = false; NxSceneDesc *current = getCurrentScene(); CustomCopy cc(mCollection,current); NxJointDesc *joint = 0; switch ( j->getType() ) { case NX_JOINT_PRISMATIC: if ( 1 ) { ::NxPrismaticJointDesc d1; NxPrismaticJoint *sj = j->isPrismaticJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxPrismaticJointDesc *desc = new NxPrismaticJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_REVOLUTE: if ( 1 ) { ::NxRevoluteJointDesc d1; NxRevoluteJoint *sj = j->isRevoluteJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxRevoluteJointDesc *desc = new NxRevoluteJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_CYLINDRICAL: if ( 1 ) { ::NxCylindricalJointDesc d1; NxCylindricalJoint *sj = j->isCylindricalJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxCylindricalJointDesc *desc = new NxCylindricalJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_SPHERICAL: if ( 1 ) { ::NxSphericalJointDesc d1; NxSphericalJoint *sj = j->isSphericalJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxSphericalJointDesc *desc = new NxSphericalJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_POINT_ON_LINE: if ( 1 ) { ::NxPointOnLineJointDesc d1; NxPointOnLineJoint *sj = j->isPointOnLineJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxPointOnLineJointDesc *desc = new NxPointOnLineJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_POINT_IN_PLANE: if ( 1 ) { ::NxPointInPlaneJointDesc d1; NxPointInPlaneJoint *sj = j->isPointInPlaneJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxPointInPlaneJointDesc *desc = new NxPointInPlaneJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_DISTANCE: if ( 1 ) { ::NxDistanceJointDesc d1; NxDistanceJoint *sj = j->isDistanceJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxDistanceJointDesc *desc = new NxDistanceJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_PULLEY: if ( 1 ) { ::NxPulleyJointDesc d1; NxPulleyJoint *sj = j->isPulleyJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxPulleyJointDesc *desc = new NxPulleyJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_FIXED: if ( 1 ) { ::NxFixedJointDesc d1; NxFixedJoint *sj = j->isFixedJoint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxFixedJointDesc *desc = new NxFixedJointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; case NX_JOINT_D6: if ( 1 ) { ::NxD6JointDesc d1; NxD6Joint *sj = j->isD6Joint(); sj->saveToDesc(d1); addActor( d1.actor[0] ); addActor( d1.actor[1] ); NxD6JointDesc *desc = new NxD6JointDesc; desc->copyFrom(d1,cc); joint = static_cast<NxJointDesc *>(desc); } break; default: break; } //Add Limits // in addition, we also have to write out its limit planes! j->resetLimitPlaneIterator(); if (j->hasMoreLimitPlanes()) { // write limit point joint->mOnActor2 = j->getLimitPoint(joint->mPlaneLimitPoint); NxArray< NxPlaneInfoDesc *> plist; // write the plane normals while (j->hasMoreLimitPlanes()) { NxPlaneInfoDesc *pInfo = new NxPlaneInfoDesc(); #if NX_SDK_VERSION_NUMBER >= 272 j->getNextLimitPlane(pInfo->mPlaneNormal, pInfo->mPlaneD, &pInfo->restitution); #else j->getNextLimitPlane(pInfo->mPlaneNormal, pInfo->mPlaneD); #endif plist.push_back(pInfo); } if ( plist.size() ) { for (int i=plist.size()-1; i>=0; i--) { NxPlaneInfoDesc *p = plist[i]; joint->mPlaneInfo.pushBack(p); } } } if ( joint ) { if ( id ) { joint->mId = id; } else { char scratch[512]; sprintf(scratch,"Joint_%d", current->mJoints.size()); joint->mId = getGlobalString(scratch); joint->mUserProperties = getGlobalString(userProperties); } current->mJoints.push_back(joint); ret = true; } return ret; }
void render() { static Timer t; if(!gMyPhysX.isPaused()) { for (NxU32 i = 0; i < gKinematicActors.size(); i++) { NxActor* actor = gKinematicActors[i].actor; NxVec3 pos = actor->getGlobalPosition(); pos += gKinematicActors[i].vel * 1.f/60.f; actor->moveGlobalPosition(pos); } } gMyPhysX.simulate(t.elapsed_time()); t.reset(); // Clear buffers glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glColor4f(0.5,0.9,0.5,1.0); DrawSkyBox(SKYEXTENTS); drawPlane(SKYEXTENTS); // Keep physics & graphics in sync for (NxU32 pass = 0; pass < 2; pass++) { int nbActors = gMyPhysX.getScene()->getNbActors(); NxActor** actors = gMyPhysX.getScene()->getActors(); actors += nbActors; while(nbActors--) { NxActor* actor = *--actors; float size; bool isTrigger = false; bool isKinematic = actor->isDynamic() && actor->readBodyFlag(NX_BF_KINEMATIC); NxVec3 color; NxF32 alpha = 1; if (actor->isDynamic()) { if (actor->readBodyFlag(NX_BF_KINEMATIC)) { color.set(1,0,0); } else { color.set(0,1,0); } } else { color.set(0.2f,0.2f,0.2f); } if (*(int *)(&actor->userData) < 0) { NxI32 triggerNumber = -(*(NxI32 *)(&actor->userData)); NxI32 triggerIndex = triggerNumber - 1; // This is our trigger isTrigger = true; size = 10.0f; color.z = gNbTouchedBodies[triggerIndex] > 0.5f ? 1.0f:0.0f; alpha = 0.5f; if (pass == 0) continue; } else { // This is a normal object size = float(*(int *)(&actor->userData)); if (pass == 1) continue; } float glmat[16]; glPushMatrix(); actor->getGlobalPose().getColumnMajor44(glmat); glMultMatrixf(glmat); glColor4f(color.x, color.y, color.z, 1.0f); glutSolidCube(size*2.0f); glPopMatrix(); // Handle shadows if( !isTrigger) { glPushMatrix(); const static float ShadowMat[]={ 1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1 }; glMultMatrixf(ShadowMat); glMultMatrixf(glmat); glDisable(GL_LIGHTING); glColor4f(0.1f, 0.2f, 0.3f, 1.0f); glutSolidCube(size*2.0f); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glEnable(GL_LIGHTING); glPopMatrix(); } } } }