Exemplo n.º 1
0
//************************************
// 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;
}
Exemplo n.º 2
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();

}
Exemplo n.º 3
0
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 );
	}
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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);
			}
		}
	}
}