//************************************ // Method: PBSetTriggerMask // FullName: PBSetTriggerMask // Access: public // Returns: int // Qualifier: // Parameter: const CKBehaviorContext& behcontext //************************************ int PBSetTriggerMask(const CKBehaviorContext& behcontext) { CKBehavior* beh = behcontext.Behavior; CKContext* ctx = behcontext.Context; PhysicManager *pm = GetPMan(); pFactory *pf = pFactory::Instance(); using namespace vtTools::BehaviorTools; if( beh->IsInputActive(0) ) { beh->ActivateInput(0,FALSE); ////////////////////////////////////////////////////////////////////////// //the object : CK3dEntity *target = (CK3dEntity *) beh->GetTarget(); if( !target ) return CKBR_OWNERERROR; ////////////////////////////////////////////////////////////////////////// // the world : pWorld *world = GetPMan()->getWorldByShapeReference(target); if (!world) { beh->ActivateOutput(0); return 0; } if (world) { NxShape *shape = world->getShapeByEntityID(target->GetID()); if (shape) { int onEnter = GetInputParameterValue<int>(beh,bbI_OnEnter); int onStay = GetInputParameterValue<int>(beh,bbI_OnStay); int onLeave = GetInputParameterValue<int>(beh,bbI_OnLeave); shape->setFlag(NX_TRIGGER_ON_ENTER,onEnter); shape->setFlag(NX_TRIGGER_ON_STAY,onStay); shape->setFlag(NX_TRIGGER_ON_LEAVE,onLeave); } } beh->ActivateOutput(0); } return 0; }
void plPXPhysical::ExcludeRegionHack(bool cleared) { NxShape* shape = fActor->getShapes()[0]; shape->setFlag(NX_TRIGGER_ON_ENTER, !cleared); shape->setFlag(NX_TRIGGER_ON_LEAVE, !cleared); fGroup = cleared ? plSimDefs::kGroupExcludeRegion : plSimDefs::kGroupDetector; shape->setGroup(fGroup); /*if switching a static need to inform the controller that it needs to rebuild the collision cache otherwise will still think that the detector is still static or that the static is still a detector*/ plPXPhysicalControllerCore::RebuildCache(); }
void CPhysicsActor::SetShapeFlag( int flag, bool enable ) { NxShapeFlag nxShapeFlag = (NxShapeFlag) flag; if( m_Actor == NULL ) { m_ToolBox->Log( LOGERROR, _T("CPhysicsObject::SetShapeFlag() Actor is NULL.\n") ); return; } // Loop through shapes in the actor unsigned int numShapes = m_Actor->getNbShapes(); NxShape*const* shapes = m_Actor->getShapes(); NxShape* shape; while( numShapes-- ) { shape = shapes[numShapes]; shape->setFlag( nxShapeFlag, enable ); } }
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; }
void PhysicsLib::updateVisualization(const VC3 &cameraPosition, float range, bool forceUpdate) { bool visualizeCollisionShapes = data->featureMap[PhysicsLib::VISUALIZE_COLLISION_SHAPES]; bool visualizeDynamic = data->featureMap[PhysicsLib::VISUALIZE_DYNAMIC]; bool visualizeStatic = data->featureMap[PhysicsLib::VISUALIZE_STATIC]; bool visualizeCollisionContacts = data->featureMap[PhysicsLib::VISUALIZE_COLLISION_CONTACTS]; bool visualizeFluids = data->featureMap[PhysicsLib::VISUALIZE_FLUIDS]; bool visualizeJoints = data->featureMap[PhysicsLib::VISUALIZE_JOINTS]; bool visualizeCCD = data->featureMap[PhysicsLib::VISUALIZE_CCD]; if (forceUpdate || visualizeCollisionShapes || visualizeDynamic || visualizeStatic || visualizeCollisionContacts || visualizeFluids || visualizeJoints || visualizeCCD) { // (do the update) } else { // do not unnecessarily do this stuff! return; } float rangeSq = range * range; int actorAmount = data->scene->getNbActors(); NxActor **actorArray = data->scene->getActors(); if(visualizeCollisionShapes || visualizeStatic || visualizeCollisionContacts) data->sdk->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1); else data->sdk->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 0); if(visualizeDynamic) data->sdk->setParameter(NX_VISUALIZE_BODY_MASS_AXES, 1); else data->sdk->setParameter(NX_VISUALIZE_BODY_MASS_AXES, 0); data->sdk->setParameter(NX_VISUALIZE_CONTACT_NORMAL, visualizeCollisionContacts); data->sdk->setParameter(NX_VISUALIZE_CONTACT_FORCE, visualizeCollisionContacts); data->sdk->setParameter(NX_VISUALIZE_CONTACT_POINT, visualizeCollisionContacts); data->sdk->setParameter(NX_VISUALIZE_COLLISION_SKELETONS, visualizeCCD); for(int i = 0; i < actorAmount; ++i) { NxActor *actor = actorArray[i]; if(!actor) continue; NxVec3 nxpos = actor->getGlobalPosition(); VC3 pos(nxpos.x, nxpos.y, nxpos.z); VC3 diff = (pos - cameraPosition); diff.y = 0; // ignore height bool inRange = false; if (diff.GetSquareLength() < rangeSq) inRange = true; if(actor->isDynamic()) { //if(visualizeDynamic && inRange) if(visualizeDynamic) actor->raiseBodyFlag(NX_BF_VISUALIZATION); else actor->clearBodyFlag(NX_BF_VISUALIZATION); } int shapeAmount = actor->getNbShapes(); NxShape *const*shapes = actor->getShapes(); while(shapeAmount--) { NxShape *shape = shapes[shapeAmount]; if(actor->isDynamic()) { //if(visualizeCollisionShapes && inRange) if(visualizeCollisionShapes) shape->setFlag(NX_SF_VISUALIZATION, true); else shape->setFlag(NX_SF_VISUALIZATION, false); } else { if(visualizeStatic && !shape->isHeightField() && inRange) shape->setFlag(NX_SF_VISUALIZATION, true); else shape->setFlag(NX_SF_VISUALIZATION, false); } } } }