void plSimulationMgr::UpdateDetectorsInScene(plKey world, plKey avatar, hsPoint3& pos, bool entering) { // search thru the actors in a scene looking for convex hull detectors and see if the avatar is inside it // ... and then send appropiate collision message if needed NxScene* scene = GetScene(world); plSceneObject* avObj = plSceneObject::ConvertNoRef(avatar->ObjectIsLoaded()); const plCoordinateInterface* ci = avObj->GetCoordinateInterface(); hsPoint3 soPos = ci->GetWorldPos(); if (scene) { uint32_t numActors = scene->getNbActors(); NxActor** actors = scene->getActors(); for (int i = 0; i < numActors; i++) { plPXPhysical* physical = (plPXPhysical*)actors[i]->userData; if (physical && physical->DoDetectorHullWorkaround()) { if ( physical->IsObjectInsideHull(pos) ) { physical->SetInsideConvexHull(entering); // we are entering this world... say we entered this detector ISendCollisionMsg(physical->GetObjectKey(), avatar, entering); } } } } }
void plPXPhysicalControllerCore::IHandleResize() { uint32_t collideFlags = 1<<plSimDefs::kGroupStatic | 1<<plSimDefs::kGroupAvatarBlocker | 1<<plSimDefs::kGroupDynamic; if(!IsSeeking()) { collideFlags|=(1<<plSimDefs::kGroupExcludeRegion); } NxScene* myscene = plSimulationMgr::GetInstance()->GetScene(this->fWorldKey); // NxShape** response=new NxShape*[2]; NxVec3 center(fLocalPosition.fX,fLocalPosition.fY,fLocalPosition.fZ+fPreferedRadius); NxSegment Seg(center,center); const NxCapsule newCap(Seg,fPreferedRadius); int numintersect =myscene->checkOverlapCapsule(newCap,NX_ALL_SHAPES,collideFlags); //with new capsule dimensions check for overlap //with objects we would collide with if(numintersect==0) { fHeight=fPreferedHeight; fRadius=fPreferedRadius; fController->setRadius(fRadius); fController->setHeight(fHeight); fNeedsResize=false; } // delete[] response; }
void create(NxScene& scene, const NxVec3& pos, float rad, NxActor* holder) { NxActorDesc actorDesc; NxBodyDesc bodyDesc; bodyDesc.solverIterationCount = 20; // steer axis bodyDesc.mass = 50; bodyDesc.massSpaceInertia = NxVec3(1,1,1); actorDesc.body = &bodyDesc; actorDesc.shapes.clear(); actorDesc.globalPose.t = pos; steerAxis = scene.createActor(actorDesc); wheel.create(scene, pos, rad, steerAxis); // revolute joint connecting steerAxis with the holder NxRevoluteJointDesc revJointDesc; revJointDesc.projectionMode = NX_JPM_POINT_MINDIST; revJointDesc.actor[0] = steerAxis; revJointDesc.actor[1] = holder; revJointDesc.setGlobalAnchor(pos); revJointDesc.setGlobalAxis(NxVec3(0,1,0)); steerJoint = (NxRevoluteJoint*)scene.createJoint(revJointDesc); // disable collision detection scene.setActorPairFlags(*wheel.wheel, *holder, NX_IGNORE_PAIR); }
/** * @brief * Constructor */ BodySphere::BodySphere(PLPhysics::World &cWorld, float fRadius, bool bStatic) : PLPhysics::BodySphere(cWorld, ((World&)cWorld).CreateBodyImpl(), fRadius) { // Get the PhysX physics scene NxScene *pPhysXScene = ((World&)cWorld).GetPhysXScene(); if (pPhysXScene) { // Create body NxBodyDesc BodyDesc; BodyDesc.angularDamping = 0.5f; // [TODO] Do we need this setting? // BodyDesc.maxAngularVelocity = 10.0f; NxSphereShapeDesc SphereDesc; SphereDesc.radius = m_fRadius; NxActorDesc ActorDesc; ActorDesc.shapes.pushBack(&SphereDesc); if (!bStatic) ActorDesc.body = &BodyDesc; ActorDesc.density = 10.0f; // [TODO] Do we need this setting? // ActorDesc.globalPose.t = pos; NxActor *pPhysXActor = pPhysXScene->createActor(ActorDesc); // Initialize the PhysX physics actor ((BodyImpl&)GetBodyImpl()).InitializePhysXActor(*this, *pPhysXActor); } }
plPXPhysical::~plPXPhysical() { SpamMsg(plSimulationMgr::Log("Destroying physical %s", GetKeyName().c_str())); if (fActor) { // Grab any mesh we may have (they need to be released manually) NxConvexMesh* convexMesh = nil; NxTriangleMesh* triMesh = nil; NxShape* shape = fActor->getShapes()[0]; if (NxConvexShape* convexShape = shape->isConvexMesh()) convexMesh = &convexShape->getConvexMesh(); else if (NxTriangleMeshShape* trimeshShape = shape->isTriangleMesh()) triMesh = &trimeshShape->getTriangleMesh(); if (!fActor->isDynamic()) plPXPhysicalControllerCore::RebuildCache(); if (fActor->isDynamic() && fActor->readBodyFlag(NX_BF_KINEMATIC)) { if (fGroup == plSimDefs::kGroupDynamic) fNumberAnimatedPhysicals--; else fNumberAnimatedActivators--; } // Release the actor NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey); scene->releaseActor(*fActor); fActor = nil; // Now that the actor is freed, release the mesh if (convexMesh) plSimulationMgr::GetInstance()->GetSDK()->releaseConvexMesh(*convexMesh); if (triMesh) plSimulationMgr::GetInstance()->GetSDK()->releaseTriangleMesh(*triMesh); // Release the scene, so it can be cleaned up if no one else is using it plSimulationMgr::GetInstance()->ReleaseScene(fWorldKey); } if (fWorldHull) delete [] fWorldHull; if (fSaveTriangles) delete [] fSaveTriangles; delete fProxyGen; // remove sdl modifier plSceneObject* sceneObj = plSceneObject::ConvertNoRef(fObjectKey->ObjectIsLoaded()); if (sceneObj && fSDLMod) { sceneObj->RemoveModifier(fSDLMod); } delete fSDLMod; }
int plPXPhysicalControllerCore::SweepControllerPath(const hsPoint3& startPos, const hsPoint3& endPos, hsBool vsDynamics, hsBool vsStatics, uint32_t& vsSimGroups, std::multiset< plControllerSweepRecord >& WhatWasHitOut) { NxCapsule tempCap; tempCap.p0 =plPXConvert::Point( startPos); tempCap.p0.z = tempCap.p0.z + fPreferedRadius; tempCap.radius = fPreferedRadius ; tempCap.p1 = tempCap.p0; tempCap.p1.z = tempCap.p1.z + fPreferedHeight; NxVec3 vec; vec.x = endPos.fX - startPos.fX; vec.y = endPos.fY - startPos.fY; vec.z = endPos.fZ - startPos.fZ; int numberofHits = 0; int HitsReturned = 0; WhatWasHitOut.clear(); NxScene *myscene = plSimulationMgr::GetInstance()->GetScene(fWorldKey); NxSweepQueryHit whatdidIhit[10]; unsigned int flags = NX_SF_ALL_HITS; if(vsDynamics) flags |= NX_SF_DYNAMICS; if(vsStatics) flags |= NX_SF_STATICS; numberofHits = myscene->linearCapsuleSweep(tempCap, vec, flags, nil, 10, whatdidIhit, nil, vsSimGroups); if(numberofHits) {//we hit a dynamic object lets make sure it is not animatable for(int i=0; i<numberofHits; i++) { plControllerSweepRecord CurrentHit; CurrentHit.ObjHit=(plPhysical*)whatdidIhit[i].hitShape->getActor().userData; CurrentHit.Norm.fX = whatdidIhit[i].normal.x; CurrentHit.Norm.fY = whatdidIhit[i].normal.y; CurrentHit.Norm.fZ = whatdidIhit[i].normal.z; if(CurrentHit.ObjHit != nil) { hsPoint3 where; where.fX = whatdidIhit[i].point.x; where.fY = whatdidIhit[i].point.y; where.fZ = whatdidIhit[i].point.z; CurrentHit.locHit = where; CurrentHit.TimeHit = whatdidIhit[i].t ; WhatWasHitOut.insert(CurrentHit); HitsReturned++; } } } return HitsReturned; }
void plPXPhysicalControllerCore::IDeleteController() { if (fController) { gControllerMgr.releaseController(*fController); fController = nil; if (fKinematicActor) { NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey); scene->releaseActor(*fKinematicActor); fKinematicActor = nil; } plSimulationMgr::GetInstance()->ReleaseScene(fWorldKey); } }
CarActor::CarActor(NxScene &scene, const VC3 &position) { NxBoxShapeDesc boxDesc1; //boxDesc1.dimensions = NxVec3(2.65f, 0.55f, 1.05f); boxDesc1.dimensions = NxVec3(1.05f, 0.55f, 2.65f); boxDesc1.localPose.t.set(NxVec3(0, boxDesc1.dimensions.y, 0)); NxBoxShapeDesc boxDesc2; //boxDesc2.dimensions = NxVec3(1.30f, 0.77f - boxDesc1.dimensions.y, 0.84f); boxDesc2.dimensions = NxVec3(0.84f, 0.77f - boxDesc1.dimensions.y, 1.30f); boxDesc2.localPose.t.set(NxVec3(0, (boxDesc1.dimensions.y * 2.f) + boxDesc2.dimensions.y, 0)); NxBodyDesc bodyDesc; NxActorDesc actorDesc; actorDesc.body = &bodyDesc; actorDesc.density = 10.f; actorDesc.shapes.pushBack(&boxDesc1); actorDesc.shapes.pushBack(&boxDesc2); actorDesc.globalPose.t.set(NxVec3(position.x, position.y, position.z)); actor = scene.createActor(actorDesc); this->scene = &scene; init(); }
void removeFluidContainmentSphere() { assert(scene->isWritable()); if(physicslib_fluid_containment_sphere_actor != NULL) { if(scene && physicslib_fluid_containment_sphere_actor) { assert(scene->isWritable()); scene->releaseActor(*physicslib_fluid_containment_sphere_actor); } physicslib_fluid_containment_sphere_actor = NULL; physicslib_fluid_containment_sphere_shape = NULL; } }
BoxActor::BoxActor(NxScene &scene, const VC3 &sizes, const VC3 &position, const VC3 &localPosition, bool ccd, float ccdMaxThickness) { NxBodyDesc bodyDesc; //bodyDesc.solverIterationCount = 2; NxBoxShapeDesc boxDesc; boxDesc.dimensions = NxVec3(sizes.x, sizes.y, sizes.z); boxDesc.localPose.t.set(NxVec3(localPosition.x, localPosition.y + sizes.y, localPosition.z)); // CCD, but for thin objects only... --jpk if (ccd && (sizes.x*2 < ccdMaxThickness || sizes.y*2 < ccdMaxThickness || sizes.z*2 < ccdMaxThickness)) { VC3 ccdSizes = sizes * 0.6f; boxDesc.ccdSkeleton = CreateCCDSkeleton(ccdSizes); boxDesc.shapeFlags |= NX_SF_DYNAMIC_DYNAMIC_CCD; // also, in this case, a minimal skin width too. boxDesc.skinWidth = 0.002f; } NxActorDesc actorDesc; actorDesc.body = &bodyDesc; actorDesc.density = 10.f; actorDesc.shapes.pushBack(&boxDesc); actorDesc.globalPose.t.set(NxVec3(position.x, position.y, position.z)); // !!!!!!!!!!!!!! //actorDesc.managedHwSceneIndex = 1; actor = scene.createActor(actorDesc); this->scene = &scene; init(); }
void plPXPhysicalControllerCore::IInformDetectors(bool entering,bool deferUntilNextSim=true) { static const NxU32 DetectorFlag= 1<<plSimDefs::kGroupDetector; if (fController) { #ifndef PLASMA_EXTERNAL_RELEASE DetectorLog("Informing from plPXPhysicalControllerCore::IInformDetectors"); #endif NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey); int kNumofShapesToStore=30; NxCapsule cap; GetWorldSpaceCapsule(cap); NxShape* shapes[30]; int numCollided=scene->overlapCapsuleShapes(cap,NX_ALL_SHAPES,kNumofShapesToStore,shapes,NULL,DetectorFlag,NULL,true); for (int i=0;i<numCollided;i++) { NxActor* myactor=&(shapes[i]->getActor()); if (myactor) { plPXPhysical* physical = (plPXPhysical*)myactor->userData; if (physical) { bool doReport = physical->DoReportOn(plSimDefs::kGroupAvatar); if(doReport) { plCollideMsg* msg = new plCollideMsg; msg->fOtherKey = fOwner; msg->fEntering = entering; msg->AddReceiver(physical->GetObjectKey()); if(!deferUntilNextSim) { DetectorLog("Sending an %s msg to %s" , entering? "entering":"exit", physical->GetObjectKey()->GetName().c_str()); msg->Send(); } else { DetectorLog("Queuing an %s msg to %s, which will be sent after the client update" , entering? "entering":"exit", physical->GetObjectKey()->GetName().c_str()); plgDispatch::Dispatch()->MsgQueue(msg); } } } } } DetectorLog("Done informing from plPXPhysicalControllerCore::IInformDetectors"); } }
void plSimulationMgr::ReleaseScene(plKey world) { if (!world) world = GetKey(); SceneMap::iterator it = fScenes.find(world); hsAssert(it != fScenes.end(), "Unknown scene"); if (it != fScenes.end()) { NxScene* scene = it->second; if (scene->getNbActors() == 0) { fSDK->releaseScene(*scene); fScenes.erase(it); } } }
/** * @brief * Constructor */ JointSlider::JointSlider(PLPhysics::World &cWorld, PLPhysics::Body *pParentBody, PLPhysics::Body *pChildBody, const Vector3 &vPivotPoint, const Vector3 &vPinDir) : PLPhysics::JointSlider(cWorld, ((World&)cWorld).CreateJointImpl(), pParentBody, pChildBody, vPivotPoint, vPinDir) { // Get the PhysX physics scene NxScene *pPhysXScene = ((World&)cWorld).GetPhysXScene(); if (pPhysXScene) { // Create the PhysX physics joint NxCylindricalJointDesc sJointDesc; sJointDesc.actor[0] = pParentBody ? ((BodyImpl&)pParentBody->GetBodyImpl()).GetPhysXActor() : nullptr; sJointDesc.actor[1] = pChildBody ? ((BodyImpl&)pChildBody ->GetBodyImpl()).GetPhysXActor() : nullptr; sJointDesc.setGlobalAnchor(NxVec3(m_vPivotPoint.x, m_vPivotPoint.y, m_vPivotPoint.z)); sJointDesc.setGlobalAxis(NxVec3(m_vPinDir.x, m_vPinDir.y, m_vPinDir.z)); NxJoint *pPhysXJoint = pPhysXScene->createJoint(sJointDesc); // Initialize the PhysX physics joint ((JointImpl&)GetJointImpl()).InitializePhysXJoint(*this, *pPhysXJoint); } }
void plSimulationMgr::UpdateAvatarInDetector(plKey world, plPXPhysical* detector) { // search thru the actors in a scene looking for avatars that might be in the newly enabled detector region // ... and then send appropiate collision message if needed if ( detector->DoDetectorHullWorkaround() ) { NxScene* scene = GetScene(world); if (scene) { uint32_t numActors = scene->getNbActors(); NxActor** actors = scene->getActors(); for (int i = 0; i < numActors; i++) { if ( actors[i]->userData == nil ) { // we go a controller bool isController; plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(*actors[i],&isController); if (controller && controller->IsEnabled()) { plKey avatar = controller->GetOwner(); plSceneObject* avObj = plSceneObject::ConvertNoRef(avatar->ObjectIsLoaded()); const plCoordinateInterface* ci; if ( avObj && ( ci = avObj->GetCoordinateInterface() ) ) { if ( detector->IsObjectInsideHull(ci->GetWorldPos()) ) { detector->SetInsideConvexHull(true); // we are entering this world... say we entered this detector ISendCollisionMsg(detector->GetObjectKey(), avatar, true); } } } } } } } }
~Data() { removeFluidContainmentSphere(); #ifdef PROJECT_CLAW_PROTO unitMaterial = NULL; #endif if(physicslib_fluid_containment_actor != NULL) { if(scene && physicslib_fluid_containment_actor) { assert(scene->isWritable()); scene->releaseActor(*physicslib_fluid_containment_actor); } physicslib_fluid_containment_actor = NULL; physicslib_fluid_containment_shape = NULL; } if(sdk && scene) { #ifndef NDEBUG int actors = scene->getNbActors(); assert(actors == 1 || actors == 2); #ifndef NX_DISABLE_FLUIDS int fluids = scene->getNbFluids(); assert(fluids == 0); #endif #endif scene->shutdownWorkerThreads(); sdk->releaseScene(*scene); } if(sdk) sdk->release(); }
void create(NxScene& scene, const NxVec3& pos, float rad, NxActor* holder) { NxActorDesc actorDesc; NxBodyDesc bodyDesc; NxSphereShapeDesc sphereDesc; bodyDesc.solverIterationCount = 20; // wheel sphereDesc.radius = rad; sphereDesc.materialIndex = wheelMaterialIndex; actorDesc.shapes.pushBack(&sphereDesc); bodyDesc.mass = 400; actorDesc.body = &bodyDesc; actorDesc.globalPose.t = pos; wheel = scene.createActor(actorDesc); // roll axis bodyDesc.mass = 50; bodyDesc.massSpaceInertia = NxVec3(1,1,1); actorDesc.body = &bodyDesc; actorDesc.shapes.clear(); actorDesc.globalPose.t = pos; rollAxis = scene.createActor(actorDesc); // revolute joint connecting wheel with rollAxis NxRevoluteJointDesc revJointDesc; revJointDesc.projectionMode = NX_JPM_POINT_MINDIST; revJointDesc.actor[0] = wheel; revJointDesc.actor[1] = rollAxis; revJointDesc.setGlobalAnchor(pos); revJointDesc.setGlobalAxis(NxVec3(0,0,1)); rollJoint = (NxRevoluteJoint*)scene.createJoint(revJointDesc); // prismatic joint connecting rollAxis with holder NxPrismaticJointDesc prisJointDesc; prisJointDesc.actor[0] = rollAxis; prisJointDesc.actor[1] = holder; prisJointDesc.setGlobalAnchor(pos); prisJointDesc.setGlobalAxis(NxVec3(0,1,0)); scene.createJoint(prisJointDesc); // add springs and dampers to the suspension (i.e. the related actors) float springLength = 0.1f; NxSpringAndDamperEffector * springNdamp = scene.createSpringAndDamperEffector(NxSpringAndDamperEffectorDesc()); springNdamp->setBodies(rollAxis, pos, holder, pos + NxVec3(0,springLength,0)); springNdamp->setLinearSpring(0, springLength, 2*springLength, 100000, 100000); springNdamp->setLinearDamper(-1, 1, 1e5, 1e5); // disable collision detection scene.setActorPairFlags(*wheel, *holder, NX_IGNORE_PAIR); }
void create(NxScene& scene ) { NxBodyDesc bodyDesc; NxBoxShapeDesc boxDesc0; NxBoxShapeDesc boxDesc1; bodyDesc.solverIterationCount = 20; // tractor actor (two shapes) NxActorDesc tractorDesc; bodyDesc.mass = 5000; tractorDesc.body = &bodyDesc; tractorDesc.globalPose.t = NxVec3(0,0,0); boxDesc0.dimensions = NxVec3(3.5,3,4); boxDesc0.localPose.t = NxVec3(3.5,4,0); tractorDesc.shapes.pushBack(&boxDesc0); //boxDesc1.dimensions = NxVec3(8.5,0.7,3); //boxDesc1.localPose.t = NxVec3(8.7,1.3,0); //tractorDesc.shapes.pushBack(&boxDesc1); tractor = scene.createActor(tractorDesc); //sPhysObject* pPhys = new sPhysObject; //pPhys->iID = 5; //tractor->userData = ( void* )pPhys; // remove collision between lower truck parts and ground //scene.setShapePairFlags(*tractor->getShapes()[1], *ground.getShapes()[0], NX_IGNORE_PAIR); //scene.setShapePairFlags(*trailer->getShapes()[1], *ground.getShapes()[0], NX_IGNORE_PAIR); // wheels float staticFriction = 1.2f; float dynamicFriction = 1.0f; steerWheels[0].create(scene, NxVec3(3.5,1.5,4), 1.5, tractor); steerWheels[1].create(scene, NxVec3(3.5,1.5,-4), 1.5, tractor); frontWheels[0].create(scene, NxVec3(16,1.5,4), 1.5, tractor); frontWheels[1].create(scene, NxVec3(16,1.5,-4), 1.5, tractor); }
void plSimulationMgr::ISendUpdates() { for (CollisionVec::iterator it = fCollideMsgs.begin(); it != fCollideMsgs.end(); ++it) { plCollideMsg* pMsg = *it; DetectorLogYellow("Collision: %s was triggered by %s. Sending an %s msg", pMsg->GetReceiver(0)->GetName().c_str(), pMsg->fOtherKey ? pMsg->fOtherKey->GetName().c_str() : "(nil)" , pMsg->fEntering ? "'enter'" : "'exit'"); plgDispatch::Dispatch()->MsgSend(pMsg); } fCollideMsgs.clear(); SceneMap::iterator it = fScenes.begin(); for (; it != fScenes.end(); it++) { NxScene* scene = it->second; uint32_t numActors = scene->getNbActors(); NxActor** actors = scene->getActors(); for (int i = 0; i < numActors; i++) { plPXPhysical* physical = (plPXPhysical*)actors[i]->userData; if (physical) { // apply any hit forces physical->ApplyHitForce(); if (physical->GetSceneNode()) { physical->SendNewLocation(); } else { // if there's no scene node, it's not active (probably about to be collected) const plKey physKey = physical->GetKey(); if (physKey) { const plString &physName = physical->GetKeyName(); if (!physName.IsNull()) { plSimulationMgr::Log("Removing physical <%s> because of missing scene node.\n", physName.c_str()); } } // Remove(physical); } } } // // iterate through the db types, which are powers-of-two enums. // for( plLOSDB db = static_cast<plLOSDB>(1) ; // db < plSimDefs::kLOSDBMax; // db = static_cast<plLOSDB>(db << 1) ) // { // fLOSSolvers[db]->Resolve(fSubspace); // } // if(fNeedLOSCullPhase) // { // for( plLOSDB db = static_cast<plLOSDB>(1) ; // db < plSimDefs::kLOSDBMax; // db = static_cast<plLOSDB>(db << 1) ) // { // fLOSSolvers[db]->Resolve(fSubspace); // } // fNeedLOSCullPhase = false; // } } }
void plSimulationMgr::Advance(float delSecs) { if (fSuspended) return; plProfile_IncCount(StepLen, (int)(delSecs*1000)); #ifndef PLASMA_EXTERNAL_RELASE uint32_t stepTime = hsTimer::GetPrecTickCount(); #endif plProfile_BeginTiming(Step); plPXPhysicalControllerCore::UpdatePrestep(delSecs); plPXPhysicalControllerCore::UpdatePoststep( delSecs); for (SceneMap::iterator it = fScenes.begin(); it != fScenes.end(); it++) { NxScene* scene = it->second; bool do_advance = true; if (fSubworldOptimization) { plKey world = (plKey)it->first; if (world == GetKey()) world = nil; do_advance = plPXPhysicalControllerCore::AnyControllersInThisWorld(world); } if (do_advance) { scene->simulate(delSecs); scene->flushStream(); scene->fetchResults(NX_RIGID_BODY_FINISHED, true); } } plPXPhysicalControllerCore::UpdatePostSimStep(delSecs); plProfile_EndTiming(Step); #ifndef PLASMA_EXTERNAL_RELEASE if(plSimulationMgr::fDisplayAwakeActors)IDrawActiveActorList(); #endif if (fExtraProfile) { int contacts = 0, dynActors = 0, dynShapes = 0, awake = 0, stShapes=0, actors=0, scenes=0, controllers=0 ; for (SceneMap::iterator it = fScenes.begin(); it != fScenes.end(); it++) { bool do_advance = true; if (fSubworldOptimization) { plKey world = (plKey)it->first; if (world == GetKey()) world = nil; do_advance = plPXPhysicalControllerCore::AnyControllersInThisWorld(world); } if (do_advance) { NxScene* scene = it->second; NxSceneStats stats; scene->getStats(stats); contacts += stats.numContacts; dynActors += stats.numDynamicActors; dynShapes += stats.numDynamicShapes; awake += stats.numDynamicActorsInAwakeGroups; stShapes += stats.numStaticShapes; actors += stats.numActors; scenes += 1; controllers += plPXPhysicalControllerCore::NumControllers(); } } plProfile_IncCount(Awake, awake); plProfile_IncCount(Contacts, contacts); plProfile_IncCount(DynActors, dynActors); plProfile_IncCount(DynShapes, dynShapes); plProfile_IncCount(StaticShapes, stShapes); plProfile_IncCount(Actors, actors); plProfile_IncCount(Scenes, scenes); plProfile_IncCount(Controllers, controllers); } plProfile_IncCount(AnimatedPhysicals, plPXPhysical::fNumberAnimatedPhysicals); plProfile_IncCount(AnimatedActivators, plPXPhysical::fNumberAnimatedActivators); fSoundMgr->Update(); plProfile_BeginTiming(ProcessSyncs); IProcessSynchs(); plProfile_EndTiming(ProcessSyncs); plProfile_BeginTiming(UpdateContexts); ISendUpdates(); plProfile_EndTiming(UpdateContexts); }
CVoid CScene::Destroy() { NxScene* tempScene = gPhysXscene/*gPhysicsSDK->getScene(i)*/; if(tempScene && !g_clickedNew && !g_clickedOpen) { for( CUInt i = 0; i < m_instanceGeometries.size(); i++ ) { CInstanceGeometry* m_instanceGeo = m_instanceGeometries[i]; if( tempScene ) { for( CUInt j = 0; j < tempScene->getNbActors(); j++ ) { CChar actorName[MAX_NAME_SIZE]; if( !tempScene->getActors()[j]->getName() ) continue; Cpy( actorName, tempScene->getActors()[j]->getName() ); if( !Cmp(m_instanceGeo->m_physXName, "\n" ) && Cmp( actorName, m_instanceGeo->m_physXName ) ) { for(CInt nItem =0 ; nItem < ex_pVandaEngine1Dlg->m_listBoxPhysXElements.GetItemCount(); nItem++) { CString strText = ex_pVandaEngine1Dlg->m_listBoxPhysXElements.GetItemText(nItem, 0); char charPtr[MAX_NAME_SIZE]; sprintf(charPtr, "%s", strText); if(Cmp( m_instanceGeo->m_physXName, charPtr ) ) { ex_pVandaEngine1Dlg->m_listBoxPhysXElements.DeleteItem(nItem); ex_pVandaEngine1Dlg->SortPhysXList(); } } tempScene->releaseActor( *tempScene->getActors()[j] ); g_multipleView->m_nx->gControllers->reportSceneChanged(); m_instanceGeo->m_hasPhysX = CFalse; Cpy( m_instanceGeo->m_physXName, "\n" ); } } } } } //while(!m_cfxMaterials.empty()) //{ //std::map<std::string, cfxMaterial*>::iterator iter = m_cfxMaterials.begin(); //CDelete(iter->second); //m_cfxMaterials.erase(iter); //} //m_cfxEffects.clear(); //while(!m_cfxEffects.empty()) //{ //std::map<std::string, cfxEffect*>::iterator iter = m_cfxEffects.begin(); //CDelete(iter->second); //m_cfxEffects.erase(iter); //} //m_cfxEffects.clear(); //delete all the geometries m_textureList.clear(); //save functions m_prefabList.clear(); //save functions if (g_editorMode == eMODE_PREFAB) { while (!m_geometries.empty()) { CDelete(m_geometries[0]); m_geometries.erase(m_geometries.begin()); } m_geometries.clear(); } m_instanceGeometries.clear(); //m_instanceControllers.clear(); while(!m_lightInstances.empty()) { CDelete(m_lightInstances[0]); m_lightInstances.erase(m_lightInstances.begin()); } while(!m_lights.empty()) { CDelete( m_lights[0] ); m_lights.erase(m_lights.begin()); } while(!m_cameraInstances.empty()) { for( CUInt size = 0; size < g_cameraInstances.size(); size++ ) { if( Cmp( m_cameraInstances[0]->m_abstractCamera->GetName(), g_cameraInstances[size]->m_abstractCamera->GetName() ) ) { if( g_render.GetActiveInstanceCamera() == g_cameraInstances[size] ) { if (g_multipleView && g_render.GetDefaultInstanceCamera()) { g_render.SetActiveInstanceCamera(g_render.GetDefaultInstanceCamera()); g_currentCameraType = eCAMERA_DEFAULT_FREE; g_multipleView->m_lockInput = CFalse; } else { g_render.SetActiveInstanceCamera(NULL); } } g_cameraInstances.erase( g_cameraInstances.begin() + size ); } } CDelete(m_cameraInstances[0]); m_cameraInstances.erase(m_cameraInstances.begin()); } while(!m_cameras.empty()) { CDelete( m_cameras[0] ); m_cameras.erase(m_cameras.begin()); } while(!m_controllers.empty()) { CDelete( m_controllers[0] ); m_controllers.erase(m_controllers.begin()); } //Delete all the nodes CDelete( m_sceneRoot ); m_nodes.clear(); //Clear all the images //for( std::vector<CImage*>::iterator it = m_images.begin(); it != m_images.end(); it++ ) //{ // CDelete( *it ); //} //Clear the vector objects m_images.clear(); //clear all the effects for( std::vector<CEffect*>::iterator it = m_effects.begin(); it != m_effects.end(); it++ ) { CDelete( *it ); } //Clear the vector objects m_effects.clear(); for( std::vector<CMaterial*>::iterator it = m_materials.begin(); it != m_materials.end(); it++ ) { CDelete( *it ); } //Clear the vector objects m_materials.clear(); for( std::vector<CAnimation*>::iterator it = m_animations.begin(); it != m_animations.end(); it++ ) { CDelete( *it ); } //Clear the vector objects m_animations.clear(); for( std::vector<CAnimationClip*>::iterator it = m_animationClips.begin(); it != m_animationClips.end(); it++ ) { CDelete( *it ); } //Clear the vector objects m_animationClips.clear(); }
/// Flush the scene's command queue for processing. virtual void FlushStream () { m_pScene->flushStream(); }
NxScene* plSimulationMgr::GetScene(plKey world) { if (!world) world = GetKey(); NxScene* scene = fScenes[world]; if (!scene) { NxSceneDesc sceneDesc; sceneDesc.gravity.set(0, 0, -32.174049f); sceneDesc.userTriggerReport = &gSensorReport; sceneDesc.userContactReport = &gContactReport; scene = fSDK->createScene(sceneDesc); // See "Advancing The Simulation State" in the PhysX SDK Documentation // This will cause PhysX to only update for our step size. If we call simulate // faster than that, PhysX will return immediately. If we call it slower than that, // PhysX will do some extra steps for us (isn't that nice?). // Anyway, this should be a good way to make us independent of the framerate. // If not, I blame the usual suspects (Tye, eap, etc...) scene->setTiming(kDefaultStepSize); // Most physicals use the default friction and restitution values, so we // make them the default. NxMaterial* mat = scene->getMaterialFromIndex(0); float rest = mat->getRestitution(); float sfriction = mat->getStaticFriction(); float dfriction = mat->getDynamicFriction(); mat->setRestitution(0.5); mat->setStaticFriction(0.5); mat->setDynamicFriction(0.5); // By default we just leave all the collision groups enabled, since // PhysX already makes sure that things like statics and statics don't // collide. However, we do make it so the avatar and dynamic blockers // only block avatars and dynamics. for (int i = 0; i < plSimDefs::kGroupMax; i++) { scene->setGroupCollisionFlag(i, plSimDefs::kGroupAvatarBlocker, false); scene->setGroupCollisionFlag(i, plSimDefs::kGroupDynamicBlocker, false); scene->setGroupCollisionFlag(i, plSimDefs::kGroupLOSOnly, false); scene->setGroupCollisionFlag(plSimDefs::kGroupLOSOnly, i, false); } scene->setGroupCollisionFlag(plSimDefs::kGroupAvatar, plSimDefs::kGroupAvatar, false); scene->setGroupCollisionFlag(plSimDefs::kGroupAvatar, plSimDefs::kGroupAvatarBlocker, true); scene->setGroupCollisionFlag(plSimDefs::kGroupDynamic, plSimDefs::kGroupDynamicBlocker, true); scene->setGroupCollisionFlag(plSimDefs::kGroupAvatar, plSimDefs::kGroupStatic, true); scene->setGroupCollisionFlag( plSimDefs::kGroupStatic, plSimDefs::kGroupAvatar, true); scene->setGroupCollisionFlag(plSimDefs::kGroupAvatar, plSimDefs::kGroupDynamic, true); // The dynamics are in actor group 1, everything else is in 0. Request // a callback for whenever a dynamic touches something. scene->setActorGroupPairFlags(0, 1, NX_NOTIFY_ON_TOUCH); scene->setActorGroupPairFlags(1, 1, NX_NOTIFY_ON_TOUCH); fScenes[world] = scene; } return scene; }
bool plPXPhysical::Init(PhysRecipe& recipe) { bool startAsleep = false; fBoundsType = recipe.bounds; fGroup = recipe.group; fReportsOn = recipe.reportsOn; fObjectKey = recipe.objectKey; fSceneNode = recipe.sceneNode; fWorldKey = recipe.worldKey; NxActorDesc actorDesc; NxSphereShapeDesc sphereDesc; NxConvexShapeDesc convexShapeDesc; NxTriangleMeshShapeDesc trimeshShapeDesc; NxBoxShapeDesc boxDesc; plPXConvert::Matrix(recipe.l2s, actorDesc.globalPose); switch (fBoundsType) { case plSimDefs::kSphereBounds: { hsMatrix44 sphereL2W; sphereL2W.Reset(); sphereL2W.SetTranslate(&recipe.offset); sphereDesc.radius = recipe.radius; plPXConvert::Matrix(sphereL2W, sphereDesc.localPose); sphereDesc.group = fGroup; actorDesc.shapes.pushBack(&sphereDesc); } break; case plSimDefs::kHullBounds: // FIXME PHYSX - Remove when hull detection is fixed // If this is read time (ie, meshStream is nil), turn the convex hull // into a box. That way the data won't have to change when convex hulls // actually work right. if (fGroup == plSimDefs::kGroupDetector && recipe.meshStream == nil) { #ifdef USE_BOXES_FOR_DETECTOR_HULLS MakeBoxFromHull(recipe.convexMesh, boxDesc); plSimulationMgr::GetInstance()->GetSDK()->releaseConvexMesh(*recipe.convexMesh); boxDesc.group = fGroup; actorDesc.shapes.push_back(&boxDesc); #else #ifdef USE_PHYSX_CONVEXHULL_WORKAROUND // make a hull of planes for testing IsInside IMakeHull(recipe.convexMesh,recipe.l2s); #endif // USE_PHYSX_CONVEXHULL_WORKAROUND convexShapeDesc.meshData = recipe.convexMesh; convexShapeDesc.userData = recipe.meshStream; convexShapeDesc.group = fGroup; actorDesc.shapes.pushBack(&convexShapeDesc); #endif // USE_BOXES_FOR_DETECTOR_HULLS } else { convexShapeDesc.meshData = recipe.convexMesh; convexShapeDesc.userData = recipe.meshStream; convexShapeDesc.group = fGroup; actorDesc.shapes.pushBack(&convexShapeDesc); } break; case plSimDefs::kBoxBounds: { boxDesc.dimensions = plPXConvert::Point(recipe.bDimensions); hsMatrix44 boxL2W; boxL2W.Reset(); boxL2W.SetTranslate(&recipe.bOffset); plPXConvert::Matrix(boxL2W, boxDesc.localPose); boxDesc.group = fGroup; actorDesc.shapes.push_back(&boxDesc); } break; case plSimDefs::kExplicitBounds: case plSimDefs::kProxyBounds: if (fGroup == plSimDefs::kGroupDetector) { SimLog("Someone using an Exact on a detector region: %s", GetKeyName().c_str()); } trimeshShapeDesc.meshData = recipe.triMesh; trimeshShapeDesc.userData = recipe.meshStream; trimeshShapeDesc.group = fGroup; actorDesc.shapes.pushBack(&trimeshShapeDesc); break; default: hsAssert(false, "Unknown geometry type during read."); return false; break; } // Now fill out the body, or dynamic part of the physical NxBodyDesc bodyDesc; fMass = recipe.mass; if (recipe.mass != 0) { bodyDesc.mass = recipe.mass; actorDesc.body = &bodyDesc; if (GetProperty(plSimulationInterface::kPinned)) { bodyDesc.flags |= NX_BF_FROZEN; startAsleep = true; // put it to sleep if they are going to be frozen } if (fGroup != plSimDefs::kGroupDynamic || GetProperty(plSimulationInterface::kPhysAnim)) { SetProperty(plSimulationInterface::kPassive, true); // Even though the code for animated physicals and animated activators are the same // keep these code snippets separated for fine tuning. Thanks. if (fGroup == plSimDefs::kGroupDynamic) { // handle the animated physicals.... make kinematic for now. fNumberAnimatedPhysicals++; bodyDesc.flags |= NX_BF_KINEMATIC; startAsleep = true; } else { // handle the animated activators.... fNumberAnimatedActivators++; bodyDesc.flags |= NX_BF_KINEMATIC; startAsleep = true; } } } else { if ( GetProperty(plSimulationInterface::kPhysAnim) ) SimLog("An animated physical that has no mass: %s", GetKeyName().c_str()); } actorDesc.userData = this; actorDesc.name = GetKeyName().c_str(); // Put the dynamics into actor group 1. The actor groups are only used for // deciding who we get contact reports for. if (fGroup == plSimDefs::kGroupDynamic) actorDesc.group = 1; NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey); try { fActor = scene->createActor(actorDesc); } catch (...) { hsAssert(false, "Actor creation crashed"); return false; } hsAssert(fActor, "Actor creation failed"); if (!fActor) return false; NxShape* shape = fActor->getShapes()[0]; shape->setMaterial(plSimulationMgr::GetInstance()->GetMaterialIdx(scene, recipe.friction, recipe.restitution)); // Turn on the trigger flags for any detectors. // // Normally, we'd set these flags on the shape before it's created. However, // in the case where the detector is going to be animated, it'll have a rigid // body too, and that will cause problems at creation. According to Ageia, // a detector shape doesn't actually count as a shape, so the SDK will have // problems trying to calculate an intertial tensor. By letting it be // created as a normal dynamic first, then setting the flags, we work around // that problem. if (fGroup == plSimDefs::kGroupDetector) { shape->setFlag(NX_TRIGGER_ON_ENTER, true); shape->setFlag(NX_TRIGGER_ON_LEAVE, true); } if (GetProperty(plSimulationInterface::kStartInactive) || startAsleep) { if (!fActor->isSleeping()) { if (plSimulationMgr::fExtraProfile) SimLog("Deactivating %s in SetPositionAndRotationSim", GetKeyName().c_str()); fActor->putToSleep(); } } if (GetProperty(plSimulationInterface::kDisable)) IEnable(false); if (GetProperty(plSimulationInterface::kSuppressed_DEAD)) IEnable(false); plNodeRefMsg* refMsg = new plNodeRefMsg(fSceneNode, plRefMsg::kOnCreate, -1, plNodeRefMsg::kPhysical); hsgResMgr::ResMgr()->AddViaNotify(GetKey(), refMsg, plRefFlags::kActiveRef); if (fWorldKey) { plGenRefMsg* ref = new plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kPhysRefWorld); hsgResMgr::ResMgr()->AddViaNotify(fWorldKey, ref, plRefFlags::kActiveRef); } // only dynamic physicals without noSync need SDLs if ( fGroup == plSimDefs::kGroupDynamic && !fProps.IsBitSet(plSimulationInterface::kNoSynchronize) ) { // add SDL modifier plSceneObject* sceneObj = plSceneObject::ConvertNoRef(fObjectKey->ObjectIsLoaded()); hsAssert(sceneObj, "nil sceneObject, failed to create and attach SDL modifier"); delete fSDLMod; fSDLMod = new plPhysicalSDLModifier; sceneObj->AddModifier(fSDLMod); } return true; }
/// Advances the simulation by an elapsedTime time. virtual void Simulate ( Scalar elapsedTime ) { m_pScene->simulate( elapsedTime ); }
void plPXPhysical::Write(hsStream* stream, hsResMgr* mgr) { plPhysical::Write(stream, mgr); hsAssert(fActor, "nil actor"); hsAssert(fActor->getNbShapes() == 1, "Can only write actors with one shape. Writing first only."); NxShape* shape = fActor->getShapes()[0]; NxMaterialIndex matIdx = shape->getMaterial(); NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey); NxMaterial* mat = scene->getMaterialFromIndex(matIdx); float friction = mat->getStaticFriction(); float restitution = mat->getRestitution(); stream->WriteLEScalar(fActor->getMass()); stream->WriteLEScalar(friction); stream->WriteLEScalar(restitution); stream->WriteByte(fBoundsType); stream->WriteByte(fGroup); stream->WriteLE32(fReportsOn); stream->WriteLE16(fLOSDBs); mgr->WriteKey(stream, fObjectKey); mgr->WriteKey(stream, fSceneNode); mgr->WriteKey(stream, fWorldKey); mgr->WriteKey(stream, fSndGroup); hsPoint3 pos; hsQuat rot; IGetPositionSim(pos); IGetRotationSim(rot); pos.Write(stream); rot.Write(stream); fProps.Write(stream); if (fBoundsType == plSimDefs::kSphereBounds) { const NxSphereShape* sphereShape = shape->isSphere(); stream->WriteLEScalar(sphereShape->getRadius()); hsPoint3 localPos = plPXConvert::Point(sphereShape->getLocalPosition()); localPos.Write(stream); } else if (fBoundsType == plSimDefs::kBoxBounds) { const NxBoxShape* boxShape = shape->isBox(); hsPoint3 dim = plPXConvert::Point(boxShape->getDimensions()); dim.Write(stream); hsPoint3 localPos = plPXConvert::Point(boxShape->getLocalPosition()); localPos.Write(stream); } else { if (fBoundsType == plSimDefs::kHullBounds) hsAssert(shape->isConvexMesh(), "Hull shape isn't a convex mesh"); else hsAssert(shape->isTriangleMesh(), "Exact shape isn't a trimesh"); // We hide the stream we used to create this mesh away in the shape user data. // Pull it out and write it to disk. hsVectorStream* vecStream = (hsVectorStream*)shape->userData; stream->Write(vecStream->GetEOF(), vecStream->GetData()); delete vecStream; } }
virtual void FlushCaches () { m_pScene->flushCaches(); }
void plPXPhysicalControllerCore::ICreateController(const hsPoint3& pos) { NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey); NxCapsuleControllerDesc desc; desc.position.x = pos.fX; desc.position.y = pos.fY; desc.position.z = pos.fZ; desc.upDirection = NX_Z; desc.slopeLimit = kSLOPELIMIT; desc.skinWidth = kPhysxSkinWidth; desc.stepOffset = STEP_OFFSET; desc.callback = &gMyReport; desc.userData = this; desc.radius = fRadius; desc.height = fHeight; desc.interactionFlag = NXIF_INTERACTION_EXCLUDE; //desc.interactionFlag = NXIF_INTERACTION_INCLUDE; fController = (NxCapsuleController*)gControllerMgr.createController(scene, desc); // Change the avatars shape groups. The avatar doesn't actually use these when // it's determining collision, but if you're standing still and an object runs // into you, it'll pass through without this. NxActor* actor = fController->getActor(); NxShape* shape = actor->getShapes()[0]; shape->setGroup(plSimDefs::kGroupAvatar); // need to create the non-bouncing object that can be used to trigger things while the avatar is doing behaviors. NxActorDesc actorDesc; NxCapsuleShapeDesc capDesc; capDesc.radius = fRadius; capDesc.height = fHeight; capDesc.group = plSimDefs::kGroupAvatar; actorDesc.shapes.pushBack(&capDesc); capDesc.materialIndex= plSimulationMgr::GetInstance()->GetMaterialIdx(scene, 0.0,0.0); actorDesc.globalPose=actor->getGlobalPose(); NxBodyDesc bodyDesc; bodyDesc.mass = kAvatarMass; actorDesc.body = &bodyDesc; bodyDesc.flags = NX_BF_KINEMATIC; bodyDesc.flags |=NX_BF_DISABLE_GRAVITY ; actorDesc.name = "AvatarTriggerKinematicGuy"; fSeeking=false; try { fKinematicActor = scene->createActor(actorDesc); } catch (...) { hsAssert(false, "Actor creation crashed"); } // set the matrix to be the same as the controller's actor... that should orient it to be the same //fKinematicActor->setGlobalPose(actor->getGlobalPose()); // the proxy for the debug display //hsAssert(!fProxyGen, "Already have proxy gen, double read?"); hsColorRGBA physColor; float opac = 1.0f; // local avatar is light purple and transparent physColor.Set(.2f, .1f, .2f, 1.f); opac = 0.8f; /* // the avatar proxy doesn't seem to work... not sure why? fProxyGen = new plPhysicalProxy(hsColorRGBA().Set(0,0,0,1.f), physColor, opac); fProxyGen->Init(this); */ }
Data(bool useHardware, bool useHardwareOnly, bool useMultithreading, PhysicsParams *params) : sdk(0), scene(0), crashed(false), statsNumActors(0), statsNumDynamicActors(0), statsNumDynamicActorsInAwakeGroups(0), statsMaxDynamicActorsInAwakeGroups(0), statsSimulationTime(0), statsSimulationWaitTime(0), statsSimulationStartWaitTime(0), startSimulationTime(0), statsContacts(0), ccd(false), ccdMaxThickness(0.5f), runningInHardware(false), physicslib_fluid_containment_actor(0), physicslib_fluid_containment_shape(0), physicslib_fluid_containment_sphere_actor(0), physicslib_fluid_containment_sphere_shape(0) { if (params == NULL) { params = &physics_defaultParams; ::Logger::getInstance()->debug("PhysicsLib - No physics params given, using defaults."); } if (params->scriptRunner == NULL) { ::Logger::getInstance()->warning("PhysicsLib - No script runner given, collision groups, etc. will be initialized to default values."); } NxPhysicsSDKDesc sdkDesc; if(!useHardware) sdkDesc.flags |= NX_SDKF_NO_HARDWARE; sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, 0, getLogger(), sdkDesc); //sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION); // HACK: ... physxSDK = sdk; if(sdk) { if(sdk->getHWVersion() == NX_HW_VERSION_NONE) useHardware = false; if (params->ccd) { sdk->setParameter(NX_CONTINUOUS_CD, true); sdk->setParameter(NX_CCD_EPSILON, 0.001f); } this->ccd = params->ccd; this->ccdMaxThickness = params->ccdMaxThickness; NxSceneDesc sceneDesc; sceneDesc.gravity = NxVec3(params->gravity.x, params->gravity.y, params->gravity.z); sceneDesc.userContactReport = &contactReport; //sceneDesc.userNotify = &userNotify; if(useHardware) { sceneDesc.simType = NX_SIMULATION_HW; if (useHardwareOnly) { sceneDesc.flags |= NX_SF_RESTRICTED_SCENE; } } else { sceneDesc.simType = NX_SIMULATION_SW; } if (!useMultithreading) { // Disable threading sceneDesc.flags = 0; } runningInHardware = useHardware; sceneDesc.flags |= NX_SF_ENABLE_ACTIVETRANSFORMS; scene = sdk->createScene(sceneDesc); if(scene) { NxMaterial *defaultMaterial = scene->getMaterialFromIndex(0); defaultMaterial->setStaticFriction(params->defaultStaticFriction); defaultMaterial->setDynamicFriction(params->defaultDynamicFriction); defaultMaterial->setRestitution(params->defaultRestitution); #ifdef PROJECT_CLAW_PROTO // Create material for cops (larger friction, no restitution) NxMaterialDesc materialDesc; materialDesc.restitution = 0.0f; materialDesc.restitutionCombineMode = NX_CM_MIN; materialDesc.staticFriction = 10.0f; materialDesc.dynamicFriction = 10.0f; unitMaterial = scene->createMaterial(materialDesc); #endif sdk->setParameter(NX_VISUALIZATION_SCALE, 1.f); #ifndef PROJECT_SHADOWGROUNDS sdk->setParameter(NX_SKIN_WIDTH, 0.01f); #endif // NEW: the new scriptable collision/contact group initialization int contactFlags1 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_TOUCH | NX_NOTIFY_FORCES; #ifdef PHYSICS_FEEDBACK int contactFlags2 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_TOUCH | NX_NOTIFY_FORCES; #else int contactFlags2 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_FORCES; #endif if (params->scriptRunner != NULL) { bool ok = params->scriptRunner->runPhysicsLibScript("physics_init", "set_contacts"); if (!ok) ::Logger::getInstance()->error("PhysicsLib - Failed to run physics_init:set_contacts script (script/sub may not be loaded or did not return expected value)."); } for (int i = 0; i < PHYSICS_MAX_COLLISIONGROUPS; i++) { for (int j = 0; j < PHYSICS_MAX_COLLISIONGROUPS; j++) { if (physicslib_group_cont[i][j] != physicslib_group_cont[j][i]) { ::Logger::getInstance()->error("PhysicsLib - Improperly mirrored physics contacts data (group1 -> group2 does not have same flag as group2 -> group1)."); ::Logger::getInstance()->debug("contacts data group numbers follow:"); ::Logger::getInstance()->debug(int2str(i)); ::Logger::getInstance()->debug(int2str(j)); } if (physicslib_group_cont[i][j] == PHYSICSLIB_GROUP_CONTACT_FLAGS1) scene->setActorGroupPairFlags(i, j, contactFlags1); else if (physicslib_group_cont[i][j] == PHYSICSLIB_GROUP_CONTACT_FLAGS2) scene->setActorGroupPairFlags(i, j, contactFlags2); } } if (params->scriptRunner != NULL) { bool ok = params->scriptRunner->runPhysicsLibScript("physics_init", "set_collisions"); if (!ok) ::Logger::getInstance()->error("PhysicsLib - Failed to run physics_init:set_collision script (script/sub may not be loaded or did not return expected value)."); } for (int i = 0; i < PHYSICS_MAX_COLLISIONGROUPS; i++) { for (int j = 0; j < PHYSICS_MAX_COLLISIONGROUPS; j++) { if (physicslib_group_coll[i][j] != physicslib_group_coll[j][i]) { ::Logger::getInstance()->error("PhysicsLib - Improperly mirrored physics collision data (group1 -> group2 does not have same flag as group2 -> group1)."); ::Logger::getInstance()->debug("collision data group numbers follow:"); ::Logger::getInstance()->debug(int2str(i)); ::Logger::getInstance()->debug(int2str(j)); } scene->setGroupCollisionFlag(i, j, physicslib_group_coll[i][j]); } } // OLD SCHEISSE... /* // Contact groups { int contactFlags1 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_TOUCH | NX_NOTIFY_FORCES; #ifdef PHYSICS_FEEDBACK int contactFlags2 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_TOUCH | NX_NOTIFY_FORCES; #else int contactFlags2 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_FORCES; #endif //int contactFlags3 = NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_FORCES; scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_STATIC, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, contactFlags2); scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_STATIC, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, contactFlags2); scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_STATIC, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags1); scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags2); scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags2); //scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags2); scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, contactFlags1); scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, PHYSICS_COLLISIONGROUP_UNITS, contactFlags2); scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_STATIC, PHYSICS_COLLISIONGROUP_UNITS, contactFlags2); scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_STATIC, contactFlags1); //scene->setActorGroupPairFlags(PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, PHYSICS_COLLISIONGROUP_UNITS, contactFlags3); } // Collision groups { // claw scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_CLAW, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_NOCOLLISION, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_CLAW, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_CLAW, PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, false); // Model particles scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); // Doors scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_DOORS, PHYSICS_COLLISIONGROUP_DOORS, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_DOORS, PHYSICS_COLLISIONGROUP_STATIC, false); // Units and model particles scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_UNITS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_UNITS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false); // Fluids scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); // Fluids w/ detailed collision scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); // Fluid containment scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_STATIC, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_UNITS, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_DOORS, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, PHYSICS_COLLISIONGROUP_FLUIDS_DETAILED, false); // No collision scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_STATIC, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_WO_UNIT_COLL_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_MODEL_PARTICLES_NO_SOUND, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_UNITS, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_DOORS, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_DYNAMIC_TERRAINOBJECTS, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_FLUID_CONTAINMENT_PLANES, false); scene->setGroupCollisionFlag(PHYSICS_COLLISIONGROUP_NOCOLLISION, PHYSICS_COLLISIONGROUP_NOCOLLISION, false); } */ } } }
int PMaterialIterator(const CKBehaviorContext& behcontext) { CKBehavior* beh = behcontext.Behavior; CKContext* ctx = behcontext.Context; PhysicManager *pm = GetPMan(); pFactory *pf = pFactory::Instance(); if (beh->IsInputActive(0)) { beh->ActivateInput(0,FALSE); ////////////////////////////////////////////////////////////////////////// //we reset our session counter int sessionIndex=-1; beh->SetOutputParameterValue(0,&sessionIndex); LMaterials*sResults = NULL; beh->GetLocalParameterValue(0,&sResults); if (!sResults) { sResults = new LMaterials(); }else sResults->clear(); NxScene * scene = GetPMan()->getDefaultWorld()->getScene(); for(int i = 0 ; i < GetPMan()->getDefaultWorld()->getScene()->getNbMaterials() ; i ++) { NxMaterial *currentMaterial = scene->getMaterialFromIndex(i); sResults->push_back(currentMaterial); } beh->SetLocalParameterValue(0,&sResults); if (sResults->size()) { beh->ActivateInput(1); }else { beh->ActivateOutput(0); return 0; } } if( beh->IsInputActive(1) ) { beh->ActivateInput(1,FALSE); int currentIndex=0; CKParameterOut *pout = beh->GetOutputParameter(0); pout->GetValue(¤tIndex); currentIndex++; LMaterials *sResults = NULL; beh->GetLocalParameterValue(0,&sResults); if (!sResults) { beh->ActivateOutput(0); return 0; } if (currentIndex>=sResults->size()) { sResults->clear(); beh->ActivateOutput(0); return 0; } NxMaterial * material = sResults->at(currentIndex); if (material!=NULL) { int sIndex = currentIndex+1; beh->SetOutputParameterValue(0,&sIndex); //SetOutputParameterValue<int>(beh,O_XML,material->xmlLinkID); SetOutputParameterValue<float>(beh,O_DFRICTION,material->getDynamicFriction()); SetOutputParameterValue<float>(beh,O_SFRICTION,material->getStaticFriction()); SetOutputParameterValue<float>(beh,O_RES,material->getRestitution()); SetOutputParameterValue<float>(beh,O_DFRICTIONV,material->getDynamicFrictionV()); SetOutputParameterValue<float>(beh,O_SFRICTIONV,material->getStaticFrictionV()); SetOutputParameterValue<VxVector>(beh,O_ANIS,getFrom(material->getDirOfAnisotropy())); SetOutputParameterValue<int>(beh,O_FCMODE,material->getFrictionCombineMode()); SetOutputParameterValue<int>(beh,O_RCMODE,material->getFrictionCombineMode()); SetOutputParameterValue<int>(beh,O_FLAGS,material->getFlags()); } if(material->userData ) { pMaterial *bMaterial = static_cast<pMaterial*>(material->userData); if (bMaterial && bMaterial->xmlLinkID ) { int xid = bMaterial->xmlLinkID; XString nodeName = vtAgeia::getEnumDescription(GetPMan()->GetContext()->GetParameterManager(),VTE_XML_MATERIAL_TYPE,xid); CKParameterOut *nameStr = beh->GetOutputParameter(O_NAME); nameStr->SetStringValue(nodeName.Str()); } } //pFactory::Instance()->copyTo(beh->GetOutputParameter(O_MATERIAL),material); beh->ActivateOutput(0); } return 0; }
/// Sets a constant gravity for the entire scene. virtual void SetGravity ( const Vector3 &vec ) { m_pScene->setGravity( ToNxVec3(vec) ); }