Here is a code example for PhysX wrapper I wrote for Catapult.
//////////////////////////////////////////////////////////////////////////////// // PhysXActorGenesis.cpp - Handles all PhysX creation // // Author: Brian Mumm // // Modified: 8/9/2007 //////////////////////////////////////////////////////////////////////////////// #include ".\physxactorgenesis.h" #include "UserData.h" #include "Stream.h" #include "cooking.h" #include "Hud.h" #include "PhyMathLib.h" #include "NXU_helper.h" #include "Gameplaymanager.h" #include "ObjectManager.h" #include "Block.h" #include using std::string; using namespace pml; PhysXActorGenesis * PhysXActorGenesis::m_pInstance; NxActor * m_WindActor = NULL; PhysXActorGenesis::PhysXActorGenesis() { m_GroundPlane= NULL; for(int i =0;i < LARGE_BOULDER_COUNT;i++) m_LargeBoulder[i]= NULL; for(int i =0; i < NORMAL_BOULDER_COUNT;i++) m_NormalBoulder[i]= NULL; for(int i =0; i < MULTISHOT_COUNT;i++) m_MultiShotBoulder[i]= NULL; m_BoulderMass=60.0f; m_BoulderGroup=1; m_BlockGroup=2; m_GroundPlaneGroup=3; m_AnimalGroup = 4; m_FireGroup = 5; m_EnemyGroup = 6; m_ForceFieldWind = NULL; m_ForceFieldExplosion = NULL; m_inclusionShape =NULL; m_excludeShape = NULL; m_explosionFrame = NULL; m_kinematicActor = NULL; m_Cow = NULL; m_bWindToggle = false; m_WindVec.set((float)NxMath::rand(MIN_WIND,MAX_WIND), (float)NxMath::rand(MIN_WIND,MAX_WIND), (float)NxMath::rand(MIN_WIND,MAX_WIND)); m_VertsRightBanner = NULL; m_FacesRightBanner = NULL; m_NormRightBanner = NULL; m_NumFaceRightBanner = m_NumVertRightBanner = NULL; m_VertsLeftBanner = NULL; m_FacesLeftBanner = NULL; m_NormLeftBanner = NULL; m_NumFaceLeftBanner = m_NumVertLeftBanner = NULL; m_VertsMiddleBanner = NULL; m_FacesMiddleBanner = NULL; m_NormMiddleBanner = NULL; m_NumFaceMiddleBanner = m_NumVertMiddleBanner = NULL; m_VertsMetalDoor = NULL; m_FacesMetalDoor = NULL; m_NormMetalDoor = NULL; m_NumFaceMetalDoor = m_NumVertMetalDoor = NULL; } ////////////////////////////////////////////////////////////////////////// // Get the instance of the PhysXActorGenesis ////////////////////////////////////////////////////////////////////////// PhysXActorGenesis *PhysXActorGenesis::GetInstance(void) { if ( m_pInstance == NULL ) m_pInstance = new PhysXActorGenesis; return m_pInstance; } ////////////////////////////////////////////////////////////////////////// // Delete the instance of the PhysXActorGenesis ////////////////////////////////////////////////////////////////////////// void PhysXActorGenesis::DeleteInstance(void) { if(m_pInstance) { delete m_pInstance; m_pInstance = NULL; } } ////////////////////////////////////////////////////////////////////////// // Clean up PhysX ////////////////////////////////////////////////////////////////////////// void PhysXActorGenesis::CleanUp(void) { if(m_VertsRightBanner) delete [] m_VertsRightBanner; m_VertsRightBanner = NULL; if(m_FacesRightBanner) delete [] m_FacesRightBanner; m_FacesRightBanner = NULL; if(m_NormRightBanner) delete [] m_NormRightBanner; m_NormRightBanner = NULL; if(m_VertsLeftBanner) delete [] m_VertsLeftBanner; m_VertsLeftBanner = NULL; if(m_FacesLeftBanner) delete [] m_FacesLeftBanner; m_FacesLeftBanner = NULL; if(m_NormLeftBanner) delete [] m_NormLeftBanner; m_NormLeftBanner = NULL; if(m_VertsMiddleBanner) delete [] m_VertsMiddleBanner; m_VertsMiddleBanner = NULL; if(m_FacesMiddleBanner) delete [] m_FacesMiddleBanner; m_FacesMiddleBanner = NULL; if(m_NormMiddleBanner) delete [] m_NormMiddleBanner; m_NormMiddleBanner = NULL; if(m_VertsMetalDoor) delete [] m_VertsMetalDoor; m_VertsMetalDoor = NULL; if(m_FacesMetalDoor) delete [] m_FacesMetalDoor; m_FacesMetalDoor = NULL; if(m_NormMetalDoor) delete [] m_NormMetalDoor; m_NormMetalDoor = NULL; } //////////////////////////////////////////////////////// // Creates an Sphere. // // In : pos The position of the sphere // radius The radius of the sphere // density The density of sphere // mass The mass of the sphere // // Out: NxActor * The sphere actor. // /////////////////////////////////////////////////////// NxActor *PhysXActorGenesis::CreateSphere(const NxVec3& pos, NxReal radius, NxReal density, NxReal mass) { NxBodyDesc BodyDesc; BodyDesc.angularDamping = 0.5f; NxSphereShapeDesc SphereDesc; SphereDesc.radius = radius; SphereDesc.mass = mass; NxActorDesc ActorDesc; ActorDesc.shapes.pushBack(&SphereDesc); ActorDesc.body = &BodyDesc; ActorDesc.density = density; ActorDesc.globalPose.t = pos; return PhysXSceneManager::GetInstance()->GetScene()->createActor(ActorDesc); } //////////////////////////////////////////////////////// // Creates a Ball // // In : FireData * Information needed for firing // /////////////////////////////////////////////////////// bool PhysXActorGenesis::CreateBall(FireData * data) { NxScene *scene = PhysXSceneManager::GetInstance()->GetScene(); while( scene && !scene->isWritable() ); // Calculate the linear velocity vec3f vecRight = Cross(data->vecForward, gc_yAxis); vec3f vecVel = CreateRotation( -data->fAngle, vecRight ) * (data->vecForward * -1.0f); vecVel.Normalize(); vecVel *= data->fPower; // Normal boulder if(Hud::GetInstance()->GetCurrAmmoType() == AMMO_NORMAL) { for(int i =0; i< NORMAL_BOULDER_COUNT; i++) { if(m_NormalBoulder[i]->getName() == "Hidden") { ActorUserData * actordata = (ActorUserData *)m_NormalBoulder[i]->userData; actordata->contactEvents = 0; m_NormalBoulder[i]->setGlobalPosition(NxVec3(data->fX, data->fY + 5.0f, data->fZ)); m_NormalBoulder[i]->setName("NormalBoulder"); m_NormalBoulder[i]->setLinearVelocity( NxVec3(vecVel.e) ); CreateWindForceField(m_NormalBoulder[i]); m_bWindToggle = true; GamePlayManager::GetInstance()->SetLastBoulder( m_NormalBoulder[i] ); GamePlayManager::GetInstance()->SetNormalBoulderFired(true); break; } } } // Large boulder else if(Hud::GetInstance()->GetCurrAmmoType() == AMMO_LARGE) { for(int i =0;i < LARGE_BOULDER_COUNT; i++) { if(m_LargeBoulder[i]->getName() == "Hidden") { ActorUserData * actordata = (ActorUserData *)m_LargeBoulder[i]->userData; actordata->contactEvents = 0; m_LargeBoulder[i]->setGlobalPosition(NxVec3(data->fX, data->fY + 5.0f,data->fZ)); m_LargeBoulder[i]->setName("LargeBoulder"); m_LargeBoulder[i]->setLinearVelocity( NxVec3(vecVel.e) ); CreateWindForceField(m_LargeBoulder[i]); GamePlayManager::GetInstance()->SetLastBoulder( m_LargeBoulder[i] ); break; } } } // MultiShot else if(Hud::GetInstance()->GetCurrAmmoType() == AMMO_MULTI) { for(int i =0; i< MULTISHOT_COUNT; i++) { if(m_MultiShotBoulder[i]->getName() == "Hidden") { ActorUserData * actordata = (ActorUserData *)m_MultiShotBoulder[i]->userData; actordata->contactEvents = 0; m_MultiShotBoulder[i]->setGlobalPosition(NxVec3(data->fX, data->fY + 5.0f,data->fZ)); m_MultiShotBoulder[i+1]->setGlobalPosition(NxVec3(data->fX + 3.0f, data->fY + 5.0f,data->fZ)); m_MultiShotBoulder[i+2]->setGlobalPosition(NxVec3(data->fX - 3.0f,data->fY + 5.0f,data->fZ)); m_MultiShotBoulder[i]->setLinearVelocity( NxVec3(vecVel.e) ); m_MultiShotBoulder[i+1]->setLinearVelocity( NxVec3( (CreateRotation(-ANGLE_MULTI, gc_yAxis) * vecVel).e ) ); m_MultiShotBoulder[i+2]->setLinearVelocity( NxVec3( (CreateRotation(ANGLE_MULTI, gc_yAxis) * vecVel).e ) ); CreateWindForceField(m_MultiShotBoulder[i]); m_MultiShotBoulder[i+1]->setName("MultShotBoulder"); m_MultiShotBoulder[i]->setName("MultShotBoulder"); m_MultiShotBoulder[i+2]->setName("MultShotBoulder"); GamePlayManager::GetInstance()->SetLastBoulder( m_MultiShotBoulder[i] ); break; } } } // FIRE!!!!! else if(Hud::GetInstance()->GetCurrAmmoType() == AMMO_FIRE) { for(int i =0; i< FIRE_BOULDER_COUNT; i++) { if(m_FireBoulder[i]->getName() == "Hidden" && m_FireBoulder[i]->isSleeping()) { ActorUserData * actordata = (ActorUserData *)m_FireBoulder[i]->userData; actordata->id = FIRE_DATA_ID; actordata->contactEvents = 0; m_FireBoulder[i]->setGlobalPosition(NxVec3(data->fX, data->fY + 5.0f, data->fZ)); m_FireBoulder[i]->setName("FireBoulder"); m_FireBoulder[i]->setLinearVelocity( NxVec3(vecVel.e) ); CreateWindForceField(m_FireBoulder[i]); GamePlayManager::GetInstance()->SetLastBoulder( m_FireBoulder[i] ); AiManager::GetInstance()->m_FireBolderPosition = m_FireBoulder[i]; AiManager::GetInstance()->m_bFires = true; break; } } } Hud::GetInstance()->SetChangeAmmoState(true); return true; } //////////////////////////////////////////////////////// // Creates a Box // // In : pos The position of the box // boxDim The size of the box // density The density of the box // mass The mass of the box // // Out: NxActor * The box actor. /////////////////////////////////////////////////////// NxActor* PhysXActorGenesis::CreateBox(const NxVec3& pos, const NxVec3& boxDim, const NxReal density, NxReal mass) { // Add a single-shape actor to the scene NxActorDesc actorDesc; NxBodyDesc bodyDesc; // The actor has one shape, a box NxBoxShapeDesc boxDesc; boxDesc.dimensions.set(boxDim.x,boxDim.y,boxDim.z); boxDesc.mass = mass; if (density) { actorDesc.body = &bodyDesc; actorDesc.density = density; } else { actorDesc.body = NULL; } actorDesc.shapes.pushBack(&boxDesc); NxActor * temp = PhysXSceneManager::GetInstance()->GetScene()->createActor(actorDesc); temp->setGlobalPosition(pos); NxShape * const *shape = temp->getShapes(); NxMaterial* defaultMaterial = PhysXSceneManager::GetInstance()->GetScene()->getMaterialFromIndex(shape[0]->getMaterial()); defaultMaterial->setRestitution(0.0f); defaultMaterial->setDynamicFriction(.5f); defaultMaterial->setStaticFriction(.001f); defaultMaterial->setDirOfAnisotropy(NxVec3(1.0f,0.0f,0.0f)); temp->putToSleep(); return temp; } //////////////////////////////////////////////////////// // Creates a Explosion // // In : pos The position of the explosion // /////////////////////////////////////////////////////// void PhysXActorGenesis::CreateExplosionForceField(const NxVec3& pos) { m_kinematicActor = NULL; NxScene *scene = PhysXSceneManager::GetInstance()->GetScene(); while( scene && !scene->isWritable() ); NxForceFieldDesc desc; desc.coordinates = NX_FFC_SPHERICAL; desc.constant = NxVec3(150.0f, 150.0f, 150.0f); NxMat33 m; m.zero(); desc.positionMultiplier = m; desc.noise = NxVec3(500.0f,500.0f,500.0f); desc.velocityTarget = NxVec3(150.0f, 150.0f, 200.0f); m.diagonal(NxVec3(50.0f, 50.0f, 50.0f)); desc.velocityMultiplier = m; if(!m_kinematicActor) { NxActorDesc actorDesc; NxBodyDesc bodyDesc; bodyDesc.flags |= NX_BF_KINEMATIC; bodyDesc.massSpaceInertia = NxVec3(10.0f, 10.0f, 10.0f); bodyDesc.mass = 3.0f; actorDesc.body = &bodyDesc; m_kinematicActor = scene->createActor(actorDesc); m_kinematicActor->setGlobalPosition(pos); } else m_kinematicActor->setGlobalPosition(pos); desc.actor = m_kinematicActor; desc.pose.id(); if(!m_ForceFieldExplosion) { m_ForceFieldExplosion = scene->createForceField(desc); NxForceFieldShape* shape = NULL; NxSphereForceFieldShapeDesc s; s.flags |= NX_FFS_EXCLUDE; s.radius = 0.1f; s.pose.t = NxVec3(0.0f, 0.0f, 0.0f); m_inclusionShape = m_ForceFieldExplosion->createShape(s); NxSphereForceFieldShapeDesc exclude; exclude.flags |= NX_FFS_EXCLUDE; exclude.radius = 0.2f; exclude.pose.t = NxVec3(0.0f, 0.0f, 0.0f); m_excludeShape = m_ForceFieldExplosion->createShape(exclude); } else m_ForceFieldExplosion->setActor(m_kinematicActor); } ////////////////////////////////////////////////////////////////////////// // Updates the position and size of the explosion ////////////////////////////////////////////////////////////////////////// void PhysXActorGenesis::UpdateExplosion(void) { NxScene *scene = PhysXSceneManager::GetInstance()->GetScene(); while( scene && !scene->isWritable() ); if (m_explosionFrame > 0) { if (m_explosionFrame == 15 || m_explosionFrame == 20) { m_inclusionShape->setFlags(m_inclusionShape->getFlags() & ~NX_FFS_EXCLUDE); } m_inclusionShape->isSphere()->setRadius((float)m_explosionFrame * 0.5f); m_explosionFrame++; if (m_explosionFrame == 20 || m_explosionFrame >= 25) { m_explosionFrame = 0; m_inclusionShape->setFlags(m_inclusionShape->getFlags() | NX_FFS_EXCLUDE); m_inclusionShape->isSphere()->setRadius(0.1f); m_excludeShape->isSphere()->setRadius(0.2f); } } } //////////////////////////////////////////////////////// // Creates Wind // // In : actor The actor to attach to // /////////////////////////////////////////////////////// void PhysXActorGenesis::CreateWindForceField(NxActor* actor) { NxForceFieldDesc desc; desc.coordinates = NX_FFC_CARTESIAN; NxScene *scene = PhysXSceneManager::GetInstance()->GetScene(); while( scene && !scene->isWritable() ); desc.constant = m_WindVec; NxMat33 m; m.zero(); desc.positionMultiplier = m; desc.noise = m_WindVec; desc.velocityTarget = m_WindVec; desc.actor = NULL; desc.pose.id(); if(!m_ForceFieldWind) { m_ForceFieldWind = scene->createForceField(desc); m_WindActor = actor; NxBoxForceFieldShapeDesc exclude; exclude.flags |= NX_FFS_EXCLUDE; exclude.dimensions = NxVec3(9.0f, 5.0f, 5.0f); exclude.pose.t = actor->getGlobalPosition(); m_WindShape = m_ForceFieldWind->createShape(exclude); } else { m_WindActor = actor; m_WindShape->setFlags(NX_FFS_EXCLUDE); m_WindShape->setPose(actor->getGlobalPose()); } } ////////////////////////////////////////////////////////////////////////// // Updates the Wind ////////////////////////////////////////////////////////////////////////// void PhysXActorGenesis::UpdateWind(void) { if (m_bWindToggle) { m_bWindToggle = false; if (m_WindShape != NULL) m_WindShape->setFlags(m_WindShape->getFlags() ^ NX_FFS_EXCLUDE); } if(m_ForceFieldWind) { m_WindShape->setPose(m_WindActor->getGlobalPose()); } } ////////////////////////////////////////////////////////////////////////// // Make a Moo Moo Cow ////////////////////////////////////////////////////////////////////////// void PhysXActorGenesis::CreateCow(void) { NXU::NxuPhysicsCollection* c = NXU::loadCollection("../Asset/PhysX/Cow.dae", NXU::FT_COLLADA); if ( c ) { HardwareChangerNotify* notify = NULL; if (PhysXSceneManager::GetInstance()->GetIfHardware()) notify = new HardwareChangerNotify(); bool bSuccess =false; PhysXSceneManager * pScene = PhysXSceneManager::GetInstance(); bSuccess = NXU::instantiateCollection(c, *pScene->GetPhysXSDK(), pScene->GetScene(), NULL, notify); if (bSuccess) { for (NxU32 j = 0; j < pScene->GetScene()->getNbActors(); j++) { m_Cow = pScene->GetScene()->getActors()[j]; m_Cow->setGroup(m_AnimalGroup); ActorUserData * cowData = new ActorUserData; cowData->id = COW_DATA_ID; m_Cow->userData = cowData; PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_AnimalGroup,m_GroundPlaneGroup,NX_NOTIFY_ON_TOUCH); PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_AnimalGroup,m_BoulderGroup,NX_NOTIFY_ON_START_TOUCH); m_Cow->setName("Hidden"); for (NxU32 k = 0; k < m_Cow->getNbShapes(); k++) { NxShape* shape = m_Cow->getShapes()[k]; if (shape->isTriangleMesh()) { NxTriangleMeshShape* triShape = shape->isTriangleMesh(); NxTriangleMeshDesc* meshDesc = new NxTriangleMeshDesc(); triShape->getTriangleMesh().saveToDesc(*meshDesc); shape->userData = meshDesc; } } } m_Cow->setGlobalPosition(NxVec3(0.0f,1000.0f,100.0f)); } NXU::releaseCollection(c); NXU::releasePersistentMemory(); if (notify != NULL) delete notify; } } ////////////////////////////////////////////////////////////////////////// // Make a Metal Door ////////////////////////////////////////////////////////////////////////// void PhysXActorGenesis::CreateMetalDoor(void) { ModelLoader *ML = ModelLoader::GetInstance(); m_DoorData = NULL; m_DoorData = ML->LoadModel("../Asset/Model/Apex_Gate.bin"); for(unsigned int i =0; i < m_DoorData->Count_Verts *3;i+=3) { m_DoorData->verts[i] *= 1.37f; m_DoorData->verts[i+1] *= 0.9f; } NxClothDesc clothDesc; clothDesc.globalPose.t = NxVec3(-1.5f,9.0f,-110.0f); clothDesc.thickness = 0.001f; if(PhysXSceneManager::GetInstance()->GetIfHardware()) clothDesc.flags |= NX_CLF_HARDWARE; clothDesc.flags |= NX_CLF_BENDING; clothDesc.flags |= NX_CLF_BENDING_ORTHO; clothDesc.stretchingStiffness = 0.00001f; clothDesc.bendingStiffness = 0.00001f; clothDesc.friction = 0.5f; clothDesc.name = "Metal Door"; NxReal impulseThreshold = 100.0f; NxReal penetrationDepth = 2.0f; NxReal maxDeformationDistance = 10000.0f; NxActorDesc coreActorDesc; NxBodyDesc coreBodyDesc; coreActorDesc.density = 0.05f; coreBodyDesc.mass = 0.0f; coreActorDesc.body = &coreBodyDesc; coreActorDesc.shapes.pushBack(new NxBoxShapeDesc()); m_MetalDoorCore = PhysXSceneManager::GetInstance()->GetScene()->createActor(coreActorDesc); m_MetalDoorCore->raiseBodyFlag(NX_BF_FROZEN_POS); m_MetalDoorCore->raiseBodyFlag(NX_BF_FROZEN_ROT); m_Door = PhysXActorGenesis::GetInstance()->MakeClothMesh(m_DoorData->Count_Verts, m_DoorData->Count_Indices,m_DoorData->verts,m_DoorData->indices,m_DoorData->norms, 1,clothDesc,m_DoorRecv); m_Door->attachToCore(m_MetalDoorCore, impulseThreshold, penetrationDepth, maxDeformationDistance); m_MetalDoorCore->setName("Metal Door"); ActorUserData * normalBlockData = new ActorUserData; normalBlockData->id = METALDOOR_DATA_ID; m_MetalDoorCore->userData = normalBlockData; m_MetalDoorCore->setGroup(m_BlockGroup); PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_BlockGroup,m_BoulderGroup,NX_NOTIFY_ON_START_TOUCH); } //////////////////////////////////////////////////////// // Creates a ClothMesh from fVerts and nFaces passed in // // In : nVertCount The vert Count // nFaceCount The face Count // fVerts The pointer to the first vert // nFaces The pointer to the first face // nScale The scale value // desc The cloth desc // // Out: NxCloth * The cloth that was made // /////////////////////////////////////////////////////// NxCloth * PhysXActorGenesis::MakeClothMesh(const int nVertCount,const int nFaceCount, float * fVerts, int * nFaces, float * fNormal ,float nScale, NxClothDesc &desc, NxMeshData &receiveBuffers) { if(PhysXSceneManager::GetInstance()->GetIfHardware()) desc.flags |= NX_CLF_HARDWARE; NxVec3** Norm; NxVec3** Verts; NxU32** Faces; if(desc.name == "Metal Door") { m_NormMetalDoor = new NxVec3[nVertCount]; m_VertsMetalDoor = new NxVec3[nVertCount]; m_FacesMetalDoor = new NxU32[nFaceCount *3]; Norm = &m_NormMetalDoor; Faces = &m_FacesMetalDoor; Verts = &m_VertsMetalDoor; receiveBuffers.numVerticesPtr = &m_NumVertMetalDoor; receiveBuffers.numIndicesPtr = &m_NumFaceMetalDoor; } else if(desc.name == "Middle Banner") { m_NormMiddleBanner = new NxVec3[nVertCount]; m_FacesMiddleBanner = new NxU32[nFaceCount *3]; m_VertsMiddleBanner = new NxVec3[nVertCount]; Norm = &m_NormMiddleBanner; Faces = &m_FacesMiddleBanner; Verts = &m_VertsMiddleBanner; receiveBuffers.numVerticesPtr = &m_NumVertMiddleBanner; receiveBuffers.numIndicesPtr = &m_NumFaceMiddleBanner; } else if(desc.name == "Left Banner") { m_NormLeftBanner = new NxVec3[nVertCount]; m_FacesLeftBanner = new NxU32[nFaceCount *3]; m_VertsLeftBanner = new NxVec3[nVertCount]; Norm = &m_NormLeftBanner; Faces = &m_FacesLeftBanner; Verts = &m_VertsLeftBanner; receiveBuffers.numVerticesPtr = &m_NumVertLeftBanner; receiveBuffers.numIndicesPtr = &m_NumFaceLeftBanner; } else if(desc.name == "Right Banner") { m_NormRightBanner = new NxVec3[nVertCount]; m_FacesRightBanner = new NxU32[nFaceCount *3]; m_VertsRightBanner = new NxVec3[nVertCount]; Norm = &m_NormRightBanner; Faces = &m_FacesRightBanner; Verts = &m_VertsRightBanner; receiveBuffers.numVerticesPtr = &m_NumVertRightBanner; receiveBuffers.numIndicesPtr = &m_NumFaceRightBanner; } int vertPos =0; for(int i =0; i< nVertCount; i++) { (*Verts)[i].x = (fVerts[vertPos]); (*Verts)[i].y = (fVerts[vertPos+1]); (*Verts)[i].z = (fVerts[vertPos+2]); (*Norm)[i].x = (fNormal[vertPos]); (*Norm)[i].y = (fNormal[vertPos +1]); (*Norm)[i].z = (fNormal[vertPos+2]); vertPos +=3; } for(int i =0; i< nFaceCount; i++) { (*Faces)[i*3 ] = nFaces[i*3]; (*Faces)[i*3 +1] = nFaces[i*3 +1]; (*Faces)[i*3 +2] = nFaces[i*3 +2]; } bool status = false; NxClothMeshDesc clothDesc; clothDesc.numVertices = nVertCount; clothDesc.numTriangles = nFaceCount; clothDesc.pointStrideBytes = sizeof(NxVec3); clothDesc.triangleStrideBytes= 3*sizeof(NxU32); clothDesc.points = *Verts; clothDesc.triangles = *Faces; NxVec3 *vSrc = *Verts; NxVec3 *vDest = (NxVec3*)clothDesc.points; for (int i = 0; i < nVertCount; i++, vDest++, vSrc++) *vDest = (*vSrc)*nScale; memcpy((NxU32*)clothDesc.triangles, *Faces, sizeof(NxU32)*clothDesc.numTriangles); NxInitCooking(); MemoryWriteBuffer buf; status = NxCookClothMesh(clothDesc, buf); MemoryReadBuffer rb(buf.data); NxClothMesh * clothMeshTemp = PhysXSceneManager::GetInstance()->GetScene()->getPhysicsSDK().createClothMesh(rb); desc.clothMesh = clothMeshTemp; NxU32 maxVertices = nVertCount; receiveBuffers.verticesPosBegin = *Verts; receiveBuffers.verticesNormalBegin = *Norm; receiveBuffers.verticesPosByteStride = sizeof(NxVec3); receiveBuffers.verticesNormalByteStride = sizeof(NxVec3); receiveBuffers.maxVertices = maxVertices; NxU32 maxIndices = nFaceCount; receiveBuffers.indicesBegin = *Faces; receiveBuffers.indicesByteStride = sizeof(NxU32) *3; receiveBuffers.maxIndices = maxIndices; *receiveBuffers.numVerticesPtr = nVertCount; *receiveBuffers.numIndicesPtr = nFaceCount; desc.meshData = receiveBuffers; return PhysXSceneManager::GetInstance()->GetScene()->createCloth(desc); } //////////////////////////////////////////////////////// // Creates a Ground Plane // // Out : NxActor * The ground plane actor // /////////////////////////////////////////////////////// NxActor* PhysXActorGenesis::CreateGroundPlane(void) { NxPlaneShapeDesc planeDesc; NxActorDesc actorDesc; actorDesc.shapes.pushBack(&planeDesc); return PhysXSceneManager::GetInstance()->GetScene()->createActor(actorDesc); } ////////////////////////////////////////////////////////////////////////// // Creates all the catapult's boulders ////////////////////////////////////////////////////////////////////////// void PhysXActorGenesis::CreateCatapultBoulders(void) { ObjectManager *pOM = ObjectManager::GetInstance(); int nBoulderTexID; nBoulderTexID = TextureManager::GetInstance()->LoadTGA("../Asset/Texture/Apex_Stone.tga", false); ActorUserData * normalBoulder1data[NORMAL_BOULDER_COUNT]; float fSpacingNormal = -102.0f; for(int i =0;i < NORMAL_BOULDER_COUNT;i++) { m_NormalBoulder[i] = CreateSphere(NxVec3(fSpacingNormal, 13.0f,900.0f) , 1.5f, 1.0f, 15.0f); m_NormalBoulder[i]->putToSleep(); m_NormalBoulder[i]->setGroup(m_BoulderGroup); m_NormalBoulder[i]->setName("Hidden"); normalBoulder1data[i] = new ActorUserData; normalBoulder1data[i]->id = BOULDER_DATA_ID; m_NormalBoulder[i]->userData = normalBoulder1data[i]; PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_BoulderGroup,m_GroundPlaneGroup,NX_NOTIFY_ON_START_TOUCH); PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_BoulderGroup,m_BlockGroup,NX_NOTIFY_ON_START_TOUCH); fSpacingNormal += -6.0f; // Add this boulder to the ObjectManager Boulder newBoulder; newBoulder.SetActor(m_NormalBoulder[i]); newBoulder.AddTextureByIndex(nBoulderTexID, 0); pOM->AddBoulder(newBoulder); } ActorUserData * largeBoulder1data[LARGE_BOULDER_COUNT]; float fSpacingLarge = 3.0f; for(int i =0;i < LARGE_BOULDER_COUNT;i++) { m_LargeBoulder[i] = CreateSphere(NxVec3(fSpacingLarge,13.0f,900.0f) , 3.0f, 1.0f, 30.0f); m_LargeBoulder[i]->putToSleep(); m_LargeBoulder[i]->setGroup(m_BoulderGroup); m_LargeBoulder[i]->setName("Hidden"); largeBoulder1data[i] = new ActorUserData; largeBoulder1data[i]->id =BOULDER_DATA_ID; m_LargeBoulder[i]->userData = largeBoulder1data[i]; PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_BoulderGroup,m_GroundPlaneGroup,NX_NOTIFY_ON_START_TOUCH); PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_BoulderGroup,m_BlockGroup,NX_NOTIFY_ON_START_TOUCH); fSpacingLarge += 10.0f; // Add this boulder to the ObjectManager Boulder newBoulder; newBoulder.SetActor(m_LargeBoulder[i]); newBoulder.AddTextureByIndex(nBoulderTexID, 0); pOM->AddBoulder(newBoulder); } ActorUserData * multishotBoulderdata[MULTISHOT_COUNT]; float fSpacingMulti = 104.0f; for(int i =0; i< MULTISHOT_COUNT; i++) { m_MultiShotBoulder[i] = CreateSphere(NxVec3(fSpacingMulti, 13.0f,900.0f), 0.9f, 1.0f, 12.0f); m_MultiShotBoulder[i]->putToSleep(); m_MultiShotBoulder[i]->setGroup(m_BoulderGroup); m_MultiShotBoulder[i]->setName("Hidden"); multishotBoulderdata[i] = new ActorUserData; multishotBoulderdata[i]->id = BOULDER_DATA_ID; m_MultiShotBoulder[i]->userData =multishotBoulderdata[i]; PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_BoulderGroup,m_GroundPlaneGroup,NX_NOTIFY_ON_START_TOUCH); PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_BoulderGroup,m_BlockGroup,NX_NOTIFY_ON_START_TOUCH); fSpacingMulti += 6.0f; // Add this boulder to the ObjectManager Boulder newBoulder; newBoulder.SetActor(m_MultiShotBoulder[i]); newBoulder.AddTextureByIndex(nBoulderTexID, 0); pOM->AddBoulder(newBoulder); } ActorUserData * fireBoulderdata[FIRE_BOULDER_COUNT]; float fSpacingFire = 0.0f; for(int i =0; i< FIRE_BOULDER_COUNT; i++) { m_FireBoulder[i] = CreateSphere(NxVec3(fSpacingMulti, 60.0f,900.0f), 2.0f, 1.0f, 17.0f); m_FireBoulder[i]->putToSleep(); m_FireBoulder[i]->setGroup(m_FireGroup); m_FireBoulder[i]->setName("Hidden"); fireBoulderdata[i] = new ActorUserData; fireBoulderdata[i]->id = FIRE_DATA_ID; m_FireBoulder[i]->userData =fireBoulderdata[i]; PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_FireGroup,m_GroundPlaneGroup,NX_NOTIFY_ON_START_TOUCH); PhysXSceneManager::GetInstance()->GetScene()->setActorGroupPairFlags(m_FireGroup,m_BlockGroup,NX_NOTIFY_ON_START_TOUCH); fSpacingFire += 200.0f; // Add this boulder to the ObjectManager Boulder newBoulder; newBoulder.SetActor(m_FireBoulder[i]); newBoulder.AddTextureByIndex(nBoulderTexID, 0); pOM->AddBoulder(newBoulder); } }