static void CreatePhysicsTerrain() { if(gTerrainData!=NULL) { delete gTerrainData; gTerrainData=NULL; } gTerrainData = new TerrainData; gTerrainData->init(TERRAIN_SIZE, TERRAIN_OFFSET, TERRAIN_WIDTH, TERRAIN_CHAOS); // Build physical model NxTriangleMeshDesc terrainDesc; terrainDesc.numVertices = gTerrainData->nbVerts; terrainDesc.numTriangles = gTerrainData->nbFaces; terrainDesc.pointStrideBytes = sizeof(NxVec3); terrainDesc.triangleStrideBytes = 3*sizeof(NxU32); terrainDesc.points = gTerrainData->verts; terrainDesc.triangles = gTerrainData->faces; terrainDesc.flags = 0; terrainDesc.heightFieldVerticalAxis = NX_Y; terrainDesc.heightFieldVerticalExtent = -1000.0f; bool status = InitCooking(); if (!status) { printf("Unable to initialize the cooking library. Please make sure that you have correctly installed the latest version of the NVIDIA PhysX SDK."); exit(1); } MemoryWriteBuffer buf; status = CookTriangleMesh(terrainDesc, buf); if (!status) { printf("Unable to cook a triangle mesh."); exit(1); } MemoryReadBuffer readBuffer(buf.data); terrainMesh = gPhysicsSDK->createTriangleMesh(readBuffer); // // Please note about the created Triangle Mesh, user needs to release it when no one uses it to save memory. It can be detected // by API "meshData->getReferenceCount() == 0". And, the release API is "gPhysicsSDK->releaseTriangleMesh(*meshData);" // NxTriangleMeshShapeDesc terrainShapeDesc; terrainShapeDesc.meshData = terrainMesh; terrainShapeDesc.shapeFlags = NX_SF_FEATURE_INDICES; NxActorDesc ActorDesc; ActorDesc.shapes.pushBack(&terrainShapeDesc); gTerrain = gScene->createActor(ActorDesc); gTerrain->userData = (void*)0; CloseCooking(); }
//------------------------------------------------------------------------------------ // Constructor //------------------------------------------------------------------------------------ TileTerrainShapeX::TileTerrainShapeX( PhysXManager *pMan , sn::TileTerrain* terrain ) { gPhAllocator = new UserAllocator(); NxU32* ii = terrain->GetIndices(); NxTriangleMeshDesc terrainDesc; terrainDesc.numVertices = terrain->GetVertexCount(); terrainDesc.numTriangles = terrain->GetIndexesCount() / 3; terrainDesc.pointStrideBytes = sizeof(gfx::Vertex3); terrainDesc.triangleStrideBytes = 3*sizeof(NxU32); terrainDesc.points = terrain->GetPositions(); terrainDesc.triangles = ii; terrainDesc.flags = 0; terrainDesc.heightFieldVerticalAxis = NX_Y; terrainDesc.heightFieldVerticalExtent = -1000.0f; bool status = InitCooking(/*gPhAllocator, &gPhErrorStream*/); if (!status) kge::io::Logger::Log("Unable to initialize the cooking library. Please make sure that you have correctly installed the latest version of the AGEIA PhysX SDK."); MemoryWriteBuffer buf; status = CookTriangleMesh(terrainDesc, buf); if (!status) printf("Unable to cook a triangle mesh."); MemoryReadBuffer readBuffer(buf.data); terrainMesh = pMan->getPhysxSDK()->createTriangleMesh(readBuffer); NxTriangleMeshShapeDesc terrainShapeDesc; terrainShapeDesc.meshData = terrainMesh; terrainShapeDesc.shapeFlags = NX_SF_FEATURE_INDICES; NxActorDesc ActorDesc; ActorDesc.shapes.pushBack(&terrainShapeDesc); gLocalActor = pMan->getPhysxScene()->createActor(ActorDesc); gLocalActor->userData = (void*)0; CloseCooking(); } // Constructor
mEResult mCCooking::InitGothic3Cooking( void ) { if ( !InitCooking( 2 << 24 | 5 << 16 | 0 << 0 ) ) // Actually Gothic 3 uses PhysX 2.4.1 but 2.5.0 is easier to load return MI_ERROR( mCPhysXError, EMissingSystemSoftware, "Please download and install 'Nvidia PhysX Legacy System Software' (NOT 'Nvidia PhysX System Software'!) from the official Nvidia homepage and restart the program." ), mEResult_False; return mEResult_Ok; }
mEResult mCCooking::InitRisenCooking( void ) { if ( !InitCooking( 2 << 24 | 8 << 16 | 1 << 8 ) ) return MI_ERROR( mCPhysXError, EMissingLegacySystemSoftware, "Please download and install 'Nvidia PhysX System Software' from the official Nvidia homepage and restart the program." ), mEResult_False; return mEResult_Ok; }
void SampleCollision::setup() { SetTitleString(getName()); #ifdef __PPCGEKKO__ SetHelpString(" a: create rigid bodies"); #else SetHelpString(" b: create rigid bodies"); #endif gShadows = false; // Create objects in the scene if (!InitCooking(gAllocator, &gErrorStream)) { printf("\nError: Unable to initialize the cooking library, exiting the sample.\n\n"); return; } // Load ASE file CookASE("fluidSample.ase", gScene, NxVec3(1,10,0)); CookASE("coolFlow.ase", gScene, NxVec3(1,6,-0), NxVec3(1,0.2,1)); CloseCooking(); // Add a box shaped drain. NxActorDesc boxDrainActor; NxBoxShapeDesc boxDrainShape; boxDrainActor.shapes.pushBack(&boxDrainShape); boxDrainShape.dimensions.set(40,1,40); boxDrainShape.shapeFlags |= NX_SF_FLUID_DRAIN; boxDrainActor.globalPose.t.set(0, 0, 0); gScene->createActor(boxDrainActor); //Pre cook hotspots NxBounds3 precookAABB; precookAABB.set(NxVec3(-20,-20,-20), NxVec3(20,20,20)); // gScene->cookFluidMeshHotspot(precookAABB, PACKET_SIZE_MULTIPLIER, REST_PARTICLES_PER_METER, KERNEL_RADIUS_MULTIPLIER, MOTION_LIMIT_MULTIPLIER, COLLISION_DISTANCE_MULTIPLIER ); //Create a set of initial particles ParticleSDK* initParticles = new ParticleSDK[MAX_PARTICLES]; unsigned initParticlesNum = 0; NxVec3 fluidPos(0, 11.6, 0); float distance = 0.1f; unsigned sideNum = 16; float rad = sideNum*distance*0.5f; for (unsigned i=0; i<sideNum; i++) for (unsigned j=0; j<sideNum; j++) for (unsigned k=0; k<sideNum; k++) { NxVec3 p = NxVec3(i*distance,j*distance,k*distance); if (p.distance(NxVec3(rad,rad,rad)) < rad) { p += fluidPos; ParticleSDK& newParticle = initParticles[initParticlesNum++]; newParticle.position = p; newParticle.velocity = NxVec3(0,0,0); } } //Setup structure to pass initial particles. NxParticleData initParticleData; initParticleData.numParticlesPtr = &initParticlesNum; initParticleData.bufferPos = &initParticles[0].position.x; initParticleData.bufferPosByteStride = sizeof(ParticleSDK); initParticleData.bufferVel = &initParticles[0].velocity.x; initParticleData.bufferVelByteStride = sizeof(ParticleSDK); //Setup fluid descriptor NxFluidDesc fluidDesc; fluidDesc.maxParticles = initParticlesNum; fluidDesc.kernelRadiusMultiplier = KERNEL_RADIUS_MULTIPLIER; fluidDesc.restParticlesPerMeter = REST_PARTICLES_PER_METER; fluidDesc.collisionDistanceMultiplier = COLLISION_DISTANCE_MULTIPLIER; fluidDesc.stiffness = 50.0f; fluidDesc.viscosity = 22.0f; fluidDesc.damping = 0.0f; fluidDesc.restitutionForStaticShapes = 0.4f; fluidDesc.dynamicFrictionForStaticShapes = 0.03f; fluidDesc.simulationMethod = NX_F_SPH; //NX_F_NO_PARTICLE_INTERACTION; if (!gHardwareSimulation) fluidDesc.flags &= ~NX_FF_HARDWARE; fluidDesc.initialParticleData = initParticleData; //Create user fluid. //- create NxFluid in NxScene //- setup the buffers to read from data from the SDK //- set NxFluid::userData field to MyFluid instance bool trackUserData = false; bool provideCollisionNormals = false; MyFluid* fluid = new MyFluid(gScene, fluidDesc, trackUserData, provideCollisionNormals, NxVec3(0.2f,0.3f,0.7f), 0.03f); assert(fluid); gMyFluids.pushBack(fluid); delete[] initParticles; gCameraPos.set(23, 14, 23); gCameraForward = fluidPos - NxVec3(0, 3, 0) - gCameraPos; gCameraForward.normalize(); }