Пример #1
0
//-----------------------------------------------------------------------------
//  onTrigger
//-----------------------------------------------------------------------------
//!!
void  CPhysicScene::onTrigger (NxShape &triggerShape, NxShape &otherShape, NxTriggerFlag status)
{
	if (!m_pCollisionMng)
		return;
		
	TActorInfo *triggerInfo = (TActorInfo*) triggerShape.getActor().userData;
	TActorInfo *otherInfo = (TActorInfo*) otherShape.getActor().userData;
	m_pCollisionMng->onTrigger(*triggerInfo, *otherInfo, status);
}
Пример #2
0
void pTriggerReport::onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
{

	NxActor *triggerActor = &triggerShape.getActor();
	NxActor *otherActor = &otherShape.getActor();




	pRigidBody *triggerBody  = NULL;
	pRigidBody *otherBody  = NULL;

	if (triggerActor)
	{
		triggerBody  = static_cast<pRigidBody*>(triggerActor->userData);
		triggerBody->getTriggers().Clear();
	}

	if (otherActor)
	{
		otherBody  = static_cast<pRigidBody*>(otherActor->userData);
		otherBody->getTriggers().Clear();
	}
	

	pTriggerEntry entry;
	entry.shapeA  = &triggerShape;
	entry.shapeB = &otherShape;
	entry.triggerEvent = status;

	if (triggerBody)
	{
		triggerBody->getTriggers().PushBack(entry);

	}
	/*if(status & NX_TRIGGER_ON_ENTER)
	{


	}
	if(status & NX_TRIGGER_ON_LEAVE)
	{
				
	}
	if(status & NX_TRIGGER_ON_STAY)
	{
		// A body entered the trigger area for the first time

	}*/

	
	

}
Пример #3
0
CPhysicUserData* CPhysicsManager::RaycastClosestActor( const Vect3f _vPosRay, const Vect3f& _vDirRay, uint32 _uiImpactMask, SCollisionInfo& _Info, float _uiMaxDistance )
{
  //NxUserRaycastReport::ALL_SHAPES
	assert(m_pScene != NULL);

	NxRay ray; 
	ray.dir =  NxVec3 ( _vDirRay.x, _vDirRay.y, _vDirRay.z );
	ray.orig = NxVec3 ( _vPosRay.x, _vPosRay.y, _vPosRay.z );

	NxRaycastHit hit;
	NxShape* closestShape = NULL;
	
	//closestShape = m_pScene->raycastClosestShape ( ray, NX_ALL_SHAPES, hit, _uiImpactMask,  NX_MAX_F32, _uiImpactMask );
	//closestShape = m_pScene->raycastClosestShape( ray, NX_ALL_SHAPES, hit, 0xffffffff, NX_MAX_F32, 0xffffffff, NULL, NULL );
	NxReal l_Distance = (NxReal) _uiMaxDistance;

	// --- Jordi : Provisional. Cal deixar aquesta linia i modificar la col·lisió de càmera 
	closestShape = m_pScene->raycastClosestShape( ray, NX_ALL_SHAPES, hit, _uiImpactMask, l_Distance );
	if (!closestShape) 
	{
		//No hemos tocado a ningún objeto físico de la escena.
		return NULL;
	}
	NxActor* actor = &closestShape->getActor();
	CPhysicUserData* impactObject =(CPhysicUserData*)actor->userData;
	//Si está petando aquí quiere decir que se ha registrado un objeto físico sin proporcionarle UserData
	assert(impactObject);

	_Info.m_fDistance		= hit.distance;
	_Info.m_Normal			= Vect3f(hit.worldNormal.x, hit.worldNormal.y, hit.worldNormal.z ); 
	_Info.m_CollisionPoint	= Vect3f(hit.worldImpact.x, hit.worldImpact.y, hit.worldImpact.z ); 

	return impactObject;
}
Пример #4
0
CPhysicUserData* CPhysicsManager::RaycastClosestActor (const Vect3f posRay, const Vect3f& dirRay, uint32 impactMask, SCollisionInfo& info )
{
	//NxUserRaycastReport::ALL_SHAPES
	assert(m_pScene != NULL);

	NxRay ray; 
	ray.dir =  NxVec3(dirRay.x, dirRay.y, dirRay.z);
	ray.orig = NxVec3(posRay.x, posRay.y, posRay.z);

	NxRaycastHit hit;
	NxShape* closestShape = NULL;

	closestShape = m_pScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit, impactMask);
	if (!closestShape) 
	{
		//No hemos tocado a ningún objeto físico de la escena.
		return NULL;
	}
	NxActor* actor = &closestShape->getActor();
	CPhysicUserData* impactObject =(CPhysicUserData*)actor->userData;
	//Si está petando aquí quiere decir que se ha registrado un objeto físico sin proporcionarle UserData
	assert(impactObject);

	info.m_fDistance	= hit.distance;
	info.m_Normal				= Vect3f(hit.worldNormal.x, hit.worldNormal.y, hit.worldNormal.z ); 
	info.m_CollisionPoint	= Vect3f(hit.worldImpact.x, hit.worldImpact.y, hit.worldImpact.z ); 

	return impactObject;
}
Пример #5
0
void myTrigger::onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status){

	if ( ! triggerShape.getActor().userData && ! otherShape.getActor().userData )
	{
		return;
	}
	
	if (status & NX_TRIGGER_ON_ENTER)
	{
		// A body just entered the trigger area
		NxActor* triggerActor = &triggerShape.getActor();
		String name = triggerActor->getName();
		int thisTarget = StringConverter::parseInt(name);
		creditTarget(thisTarget);
	}
	
}
Пример #6
0
pWheelContactData* pWheel2::getContact()
{
	NxWheelShape *wShape = getWheelShape();
	if (!wShape)
	{
		return new pWheelContactData();
	}
	
	NxWheelContactData wcd; 
	NxShape* contactShape = wShape->getContact(wcd);
	
	pWheelContactData result;
	result.contactEntity = NULL;


	if (contactShape)
	{

		result.contactForce = wcd.contactForce;
		result.contactNormal = getFrom(wcd.contactNormal);
		result.contactPoint= getFrom(wcd.contactPoint);
		result.contactPosition= wcd.contactPosition;

		
		result.lateralDirection= getFrom(wcd.lateralDirection);
		result.lateralImpulse= wcd.lateralImpulse;
		result.lateralSlip = wcd.lateralSlip;
		
		result.longitudalDirection = getFrom(wcd.longitudalDirection);
		result.longitudalImpulse = wcd.longitudalImpulse;
		result.longitudalSlip= wcd.longitudalSlip;

		pSubMeshInfo *sInfo  = static_cast<pSubMeshInfo*>(contactShape->userData);
		if (sInfo->entID)
		{
			CKObject *obj = (CKObject*)GetPMan()->m_Context->GetObject(sInfo->entID);
			if (obj)
			{
				result.contactEntity = (CK3dEntity*)obj;
			}else
			{
				result.contactEntity = NULL;
			}
		}

		result.otherShapeMaterialIndex = contactShape->getMaterial();
		
		NxMaterial* otherMaterial = contactShape->getActor().getScene().getMaterialFromIndex(contactShape->getMaterial());
		if (otherMaterial)
		{
			pFactory::Instance()->copyTo(result.otherMaterial,otherMaterial);
		}
	}
	return &result;
}
Пример #7
0
    virtual void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
    {
        plKey otherKey = nil;
        bool doReport = false;

        // Get our trigger physical.  This should definitely have a plPXPhysical
        plPXPhysical* triggerPhys = (plPXPhysical*)triggerShape.getActor().userData;

        // Get the triggerer. If it doesn't have a plPXPhyscial, it's an avatar
        plPXPhysical* otherPhys = (plPXPhysical*)otherShape.getActor().userData;
        if (otherPhys)
        {
            otherKey = otherPhys->GetObjectKey();
            doReport = triggerPhys->DoReportOn((plSimDefs::Group)otherPhys->GetGroup());
        }
        else
        {
            plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(otherShape.getActor());
            if (controller)
            {
                otherKey = controller->GetOwner();
                doReport = triggerPhys->DoReportOn(plSimDefs::kGroupAvatar);
            }
        }

        if (doReport)
        {
            if (status & NX_TRIGGER_ON_ENTER)
            {
                if (plSimulationMgr::fExtraProfile)
                    DetectorLogRed("-->Send Collision %s enter",triggerPhys->GetObjectKey()->GetName().c_str());
                plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
            }
            else if (status & NX_TRIGGER_ON_LEAVE)
            {
                if (plSimulationMgr::fExtraProfile)
                    DetectorLogRed("-->Send Collision %s exit",triggerPhys->GetObjectKey()->GetName().c_str());
                plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
            }
        }
    }
Пример #8
0
NxActor*pWheel2::getTouchedActor()const
{
	NxWheelContactData wcd;
	NxShape * s = mWheelShape->getContact(wcd);	
	if (s)
	{
		if (&s->getActor())
		{
			return &s->getActor();
		}else
		{
			return NULL;
		}
		
	}else
	{
		return NULL;
	}

	return NULL;
	//return s ? &s->getActor() : NULL;
}
Пример #9
0
	virtual void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
	{
		// other actor is a trigger too?
		if (*(int *)(&otherShape.getActor().userData) < 0)
			return;

		NxActor& triggerActor = triggerShape.getActor();
		NxI32 triggerNumber = -(*(int *)(&triggerActor.userData));
		NxI32 triggerIndex = triggerNumber - 1;

		if(status & NX_TRIGGER_ON_ENTER)
		{
			// A body entered the trigger area for the first time
			gNbTouchedBodies[triggerIndex]++;
		}
		if(status & NX_TRIGGER_ON_LEAVE)
		{
			// A body left the trigger area
			gNbTouchedBodies[triggerIndex]--;
		}
		NX_ASSERT(gNbTouchedBodies[triggerIndex]>=0);	//Shouldn't go negative
	}
Пример #10
0
	//NX_STATIC_SHAPES,NX_DYNAMIC_SHAPES,NX_ALL_SHAPES
	GameObject* PhysicsManager::castRayGetClosest(Vector3 startPosition, Vector3 direction, bool omitTriggers,bool omitActors, bool omitStatic, bool omitDynamic, bool omitCharacters)
	{
		NxRay worldRay;
		worldRay.orig = NxTools::convert(startPosition);
		worldRay.dir	= NxTools::convert(direction);

		NxShapesType flags = NX_ALL_SHAPES; // NxShapeType::;
		
		NxRaycastHit hit;
		NxShape* shape = mScene->raycastClosestShape(worldRay, flags, hit);

		if(shape) {
			NxActor& actor = shape->getActor();
			if(!omitTriggers) {
				CPhysicsTrigger* trigger = static_cast<CPhysicsTrigger*>(actor.userData);
				if(trigger)
					return trigger->getOwnerObject();
			}

			if(!omitActors) {
				
				CPhysicsActor* physicsActor = static_cast<CPhysicsActor*>(actor.userData);
				if(physicsActor) {
					//if(!omitDynamic) {
					//	if(physicsActor->isDynamic()) {
							return physicsActor->getOwnerObject();
					//	}
					//} else {
						
					//}

				}
			}
			
			if(!omitCharacters) {
				CCharacterController* character = static_cast<CCharacterController*>(actor.userData);
				if(character)
					return character->getOwnerObject();
			}
		
		}

		//if(shape)
		//	return hit.distance;
		//else
		//	return 0;

		return NULL;
	}
Пример #11
0
CPhysicUserData* CPhysicsManager::RaycastClosestActorShoot (const Vect3f posRay, const Vect3f& dirRay, uint32 impactMask, SCollisionInfo& info, float _fPower)
{

	//NxUserRaycastReport::ALL_SHAPES
	assert(m_pScene != NULL);

	NxRay ray; 
	ray.dir =  NxVec3(dirRay.x, dirRay.y, dirRay.z);
	ray.orig = NxVec3(posRay.x, posRay.y, posRay.z);

	NxRaycastHit hit;
	NxShape* closestShape = NULL;

	closestShape = m_pScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit, impactMask);
	if (!closestShape) 
	{
		//No hemos tokado a ningún objeto físico de la escena.
		return NULL;
	}
	NxActor* actor = &closestShape->getActor();
	CPhysicUserData* impactObject =(CPhysicUserData*)actor->userData;
	//Si está petando aquí quiere decir que se ha registrado un objeto físico sin proporcionarle UserData
	assert(impactObject);

	info.m_fDistance	= hit.distance;
	info.m_Normal				= Vect3f(hit.worldNormal.x, hit.worldNormal.y, hit.worldNormal.z ); 
	info.m_CollisionPoint	= Vect3f(hit.worldImpact.x, hit.worldImpact.y, hit.worldImpact.z ); 

	Vect3f l_vDirection(dirRay.x-posRay.x,dirRay.y-posRay.y,dirRay.z-posRay.z);
	l_vDirection.Normalize();

	NxVec3 l_vDirectionVec(dirRay.x,dirRay.y,dirRay.z); 
	NxF32 coeff = actor->getMass() * _fPower;
	actor->addForceAtLocalPos(l_vDirectionVec*coeff, NxVec3(0,0,0), NX_IMPULSE,true);


	return impactObject;
}
Пример #12
0
void Pick(int x, int y)
{
	LetGo();

	NxRay ray; 
	ViewUnProject(x, y, 0.0f, ray.orig);
	ViewUnProject(x, y, 1.0f, ray.dir);
	ray.dir -= ray.orig; 
	ray.dir.normalize();

	NxRaycastHit hit;
	NxShape* closestShape = gScene->raycastClosestShape(ray, NX_ALL_SHAPES, hit);

	NxVec3 origin = ray.orig;
	NxVec3 impact = hit.worldImpact;
	NxReal distRB = NX_MAX_REAL;
	if (closestShape && closestShape->getActor().isDynamic()) 
	{
		distRB = (impact.x - origin.x) * (impact.x - origin.x) + (impact.y - origin.y) * (impact.y - origin.y) + (impact.z - origin.z) * (impact.z - origin.z);
	}

	NxVec3 hitcloth, hitRecord;
	NxU32 vertexId;
	NxReal distCloth, closest= NX_MAX_REAL;
	NxU32 indexCloth, indexClothVertex;

	NxCloth **cloths = gScene->getCloths();
	for (NxU32 i = 0; i < gScene->getNbCloths(); i++) 
	{
		if (cloths[i]->raycast(ray, hitcloth, vertexId))
		{
			distCloth = (hitcloth.x - origin.x) * (hitcloth.x - origin.x) + (hitcloth.y - origin.y) * (hitcloth.y - origin.y) + (hitcloth.z - origin.z) * (hitcloth.z - origin.z);
			if(distCloth < closest)	
			{
				closest = distCloth;
				indexCloth = i;
				indexClothVertex = vertexId;
				hitRecord = hitcloth;

			}
		}
	}

	if (distRB > closest) // Pick cloth
	{
		gHitCloth = cloths[indexCloth];
		gHitClothVertex = indexClothVertex;

		int hitx, hity;
		ViewProject(hitRecord, hitx, hity, gMouseDepth);

	}
	else if (distRB < closest) // Pick actor
	{
		gHitActor = &closestShape->getActor();
		gHitActor->wakeUp();

		int hitx, hity;
		gMouseSphere = CreateSphere(hit.worldImpact, 0.1, 1);
		gMouseSphere->raiseBodyFlag(NX_BF_KINEMATIC);
		gMouseSphere->raiseActorFlag(NX_AF_DISABLE_COLLISION);
		ViewProject(hit.worldImpact, hitx, hity, gMouseDepth);

		NxDistanceJointDesc desc;
		desc.actor[0] = gMouseSphere;
		desc.actor[1] = gHitActor;
		gMouseSphere->getGlobalPose().multiplyByInverseRT(hit.worldImpact, desc.localAnchor[0]);
		gHitActor->getGlobalPose().multiplyByInverseRT(hit.worldImpact, desc.localAnchor[1]);
		desc.spring.damper = 1;
		desc.spring.spring = 200;
		desc.flags |= NX_DJF_MAX_DISTANCE_ENABLED | NX_DJF_SPRING_ENABLED;
		NxJoint* joint = gScene->createJoint(desc);
		gMouseJoint = (NxDistanceJoint*)joint->is(NX_JOINT_DISTANCE);

	}
}
Пример #13
0
    virtual void onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
    {
        // Get our trigger physical.  This should definitely have a plPXPhysical
        plPXPhysical* triggerPhys = (plPXPhysical*)triggerShape.getActor().userData;
        bool doReport = false;

        // Get the triggerer.  This may be an avatar, which doesn't have a
        // plPXPhysical, so we have to extract the necessary info.
        plKey otherKey = nil;
        hsPoint3 otherPos = plPXConvert::Point(otherShape.getGlobalPosition());

        if (plSimulationMgr::fExtraProfile)
            DetectorLogRed("-->%s %s (status=%x) other@(%f,%f,%f)",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit",status,otherPos.fX,otherPos.fY,otherPos.fZ);

        plPXPhysical* otherPhys = (plPXPhysical*)otherShape.getActor().userData;
        if (otherPhys)
        {
            otherKey = otherPhys->GetObjectKey();
            doReport = triggerPhys->DoReportOn((plSimDefs::Group)otherPhys->GetGroup());
            if (!doReport)
            {
                if (plSimulationMgr::fExtraProfile)
                    DetectorLogRed("<--Kill collision %s :failed group. US=%x OTHER=(%s)%x",triggerPhys->GetObjectKey()->GetName().c_str(),triggerPhys->GetGroup(),otherPhys->GetObjectKey()->GetName().c_str(),otherPhys->GetGroup());
            }
        }
        else
        {
            bool isController;
            plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(otherShape.getActor(),&isController);
            if (controller)
            {
                if (isController)
                {
#ifdef PHYSX_ONLY_TRIGGER_FROM_KINEMATIC
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s : ignoring controller events.",triggerPhys->GetObjectKey()->GetName().c_str());
                    return;
#else // else if trigger on both controller and kinematic
                    // only suppress controller collision 'enters' when disabled but let 'exits' continue
                    // ...this is because there are detector regions that are on the edge on ladders that the exit gets missed.
                    if ( ( !controller->IsEnabled() /*&& (status & NX_TRIGGER_ON_ENTER)*/ ) || controller->IsKinematic() )
                    {
                        if (plSimulationMgr::fExtraProfile)
                            DetectorLogRed("<--Kill collision %s : controller is not enabled.",triggerPhys->GetObjectKey()->GetName().c_str());
                        return;
                    }
#endif  // PHYSX_ONLY_TRIGGER_FROM_KINEMATIC
                }
#ifndef PHYSX_ONLY_TRIGGER_FROM_KINEMATIC  // if triggering only kinematics, then all should trigger
                else
                {
                    // only suppress kinematic collision 'enters' when disabled but let 'exits' continue
                    // ...this is because there are detector regions that are on the edge on ladders that the exit gets missed.
                    if ( !controller->IsKinematic() /*&& (status & NX_TRIGGER_ON_ENTER) */ )
                    {
                        if (plSimulationMgr::fExtraProfile)
                            DetectorLogRed("<--Kill collision %s : kinematic is not enabled.",triggerPhys->GetObjectKey()->GetName().c_str());
                        return;
                    }
                }
#endif  // PHYSX_ONLY_TRIGGER_FROM_KINEMATIC
                otherKey = controller->GetOwner();
                doReport = triggerPhys->DoReportOn(plSimDefs::kGroupAvatar);
                if (plSimulationMgr::fExtraProfile )
                {
                    if (!doReport)
                    {
                        DetectorLogRed("<--Kill collision %s :failed group. US=%x OTHER=(NotAvatar)",triggerPhys->GetObjectKey()->GetName().c_str(),triggerPhys->GetGroup());
                    }
                    else
                    {
                        hsPoint3 avpos;
                        controller->GetPositionSim(avpos);
                        DetectorLogRed("-->Avatar at (%f,%f,%f)",avpos.fX,avpos.fY,avpos.fZ);
                    }
                }
            }
        }

        if (doReport)
        {
#ifdef USE_PHYSX_CONVEXHULL_WORKAROUND
            if ( triggerPhys->DoDetectorHullWorkaround() )
            {
                if (status & NX_TRIGGER_ON_ENTER && triggerPhys->Should_I_Trigger(status & NX_TRIGGER_ON_ENTER, otherPos) )
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
                    plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
                }
                else if (status & NX_TRIGGER_ON_ENTER)
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s :failed Should I trigger",triggerPhys->GetObjectKey()->GetName().c_str());
                }
                if (status & NX_TRIGGER_ON_LEAVE && triggerPhys->Should_I_Trigger(status & NX_TRIGGER_ON_ENTER, otherPos) )
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
                    plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
                }
                else if (status & NX_TRIGGER_ON_LEAVE)
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s :failed Should I trigger",triggerPhys->GetObjectKey()->GetName().c_str());
                }
                if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) )
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s :failed event(CH)",triggerPhys->GetObjectKey()->GetName().c_str());
                }
            }
            else
            {
#endif  // USE_PHYSX_CONVEXHULL_WORKAROUND
                if (status & NX_TRIGGER_ON_ENTER)
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
                    plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
                }
                if (status & NX_TRIGGER_ON_LEAVE)
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
                    plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
                }
                if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) )
                {
                    if (plSimulationMgr::fExtraProfile)
                        DetectorLogRed("<--Kill collision %s :failed event",triggerPhys->GetObjectKey()->GetName().c_str());
                }
#ifdef USE_PHYSX_CONVEXHULL_WORKAROUND
            }
#endif  // USE_PHYSX_CONVEXHULL_WORKAROUND
        }
    }
Пример #14
0
	void PhysicsManager::onTrigger(NxShape& triggerShape, NxShape& otherShape, NxTriggerFlag status)
	{

		NxActor& triggerActor = triggerShape.getActor();
		NxActor& otherActor = otherShape.getActor();
		
		CPhysicsTrigger* trigger = (CPhysicsTrigger*)(triggerActor.userData);
		CPhysicsActor* actor = (CPhysicsActor*)(otherActor.userData);
		CCharacterController* character = (CCharacterController*)(otherActor.userData);

		if(trigger) {

			if(status & NX_TRIGGER_ON_ENTER)
			{
				if(actor) {
					if(actor->componentID() == "CPhysicsActor") {
						trigger->OnActorEnter(actor);
						actor->OnTriggerEnter(trigger);
						return;
					}
				}
				
				if(character) {
					if(character->componentID() == "CCharacterController") {
						trigger->OnControllerEnter(character);
						character->OnTriggerEnter(trigger);
						return;
					}
				}
			}
			
			if(status & NX_TRIGGER_ON_STAY)
			{
				if(actor) {
					if(actor->componentID() == "CPhysicsActor") {
						trigger->OnActorStay(actor);
						actor->OnTriggerStay(trigger);
						return;
					}
				}

				if(character) {
					if(character->componentID() == "CCharacterController") {
						trigger->OnControllerStay(character);
						character->OnTriggerStay(trigger);
						return;
					}
				}
			}

			if(status & NX_TRIGGER_ON_LEAVE)
			{
				if(actor) {
					if(actor->componentID() == "CPhysicsActor") {
						trigger->OnActorLeave(actor);
						actor->OnTriggerLeave(trigger);
						return;
					}
				}

				if(character) {
					if(character->componentID() == "CCharacterController") {
						trigger->OnControllerLeave(character);
						character->OnTriggerLeave(trigger);
						return;
					}
				}
			}

		}

	}
Пример #15
0
void pWheel2::_tick(float dt)
{
	NxWheelShape *wShape = getWheelShape();
	if (!wShape) return;


	NxVec3 _localVelocity;
	bool _breaking=false;
	//////////////////////////////////////////////////////////////////////////
	//
	//
	//
	NxWheelContactData wcd; 
	NxShape* contactShape = wShape->getContact(wcd);

	if (contactShape)
	{

		NxVec3 relativeVelocity;
		if ( !contactShape->getActor().isDynamic())
		{
			relativeVelocity = getActor()->getLinearVelocity();
		} else {
			relativeVelocity = getActor()->getLinearVelocity() - contactShape->getActor().getLinearVelocity();
		}
		NxQuat rotation = getActor()->getGlobalOrientationQuat();

		_localVelocity = relativeVelocity;
		rotation.inverseRotate(_localVelocity);
		_breaking = false; //NxMath::abs(_localVelocity.z) < ( 0.1 );
		//					wShape->setAxleSpeed()
	}


	float rollAngle = getWheelRollAngle();
	
	rollAngle+=wShape->getAxleSpeed() * (dt* 0.01f);
	//rollAngle+=wShape->getAxleSpeed() * (1.0f/60.0f /*dt* 0.01f*/);

	while (rollAngle > NxTwoPi)	//normally just 1x
		rollAngle-= NxTwoPi;
	while (rollAngle< -NxTwoPi)	//normally just 1x
		rollAngle+= NxTwoPi;

	setWheelRollAngle(rollAngle);

	NxMat34& wheelPose = wShape->getGlobalPose();


	NxReal  stravel = wShape->getSuspensionTravel();
	NxReal radius = wShape->getRadius();


	//have ground contact?
	if( contactShape && wcd.contactPosition <=  (stravel + radius) ) {
		wheelPose.t = NxVec3( wheelPose.t.x, wcd.contactPoint.y + getRadius(), wheelPose.t.z );
	}
	else {
		wheelPose.t = NxVec3( wheelPose.t.x, wheelPose.t.y - getSuspensionTravel(), wheelPose.t.z );
	}


	float rAngle = getWheelRollAngle();
	float steer = wShape->getSteerAngle();

	NxVec3 p0;
	NxVec3 dir;
	/*
	getWorldSegmentFast(seg);
	seg.computeDirection(dir);
	dir.normalize();
	*/
	NxReal r = wShape->getRadius();
	NxReal st = wShape->getSuspensionTravel();
	NxReal steerAngle = wShape->getSteerAngle();
	p0 = wheelPose.t;  //cast from shape origin
	wheelPose.M.getColumn(1, dir);
	dir = -dir;	//cast along -Y.
	NxReal castLength = r + st;	//cast ray this long


	NxMat33 rot, axisRot, rollRot;
	rot.rotY( wShape->getSteerAngle() );
	axisRot.rotY(0);
	rollRot.rotX(rAngle);
	wheelPose.M = rot * wheelPose.M * axisRot * rollRot;
	setWheelPose(wheelPose);
}
Пример #16
0
/**
	Creado por Isaac el 13/4/2012
	si teneis alguna duda ya sabeis :P
*/
int CPhysicScene::detectCollisions(Vector3 point, float maxDist, IPhysicObj * *& physicObjects) const
{
	NxSphere worldSphere;
	worldSphere.center = NxVec3(point.x, point.y, point.z);
   
	worldSphere.radius = maxDist;

	m_pScene->checkOverlapSphere(worldSphere);

	NxU32 nbShapes = 100;

	NxShape** result = new NxShape* [nbShapes];

	for (NxU32 i = 0; i < nbShapes; ++i)
	{
		result[i] = NULL;
	}

	unsigned int overlapCount = m_pScene->overlapSphereShapes(worldSphere, NX_ALL_SHAPES, nbShapes, result, NULL );

	//variable en la que guardaremos los objetos fisicos que encontremos, abra como mucho, tantos como detecte el overlapSphereShapes
	IPhysicObj * * resultado = new IPhysicObj*[overlapCount];
	
	for (int i = 0; i < overlapCount; ++i)
	{
		resultado[i] = NULL;
	}


	//Recorremos lo devuelto por la funcion overlapSphereShapes, y lo transformamos y añadimos a un array de objetos fisicos
	int numEntidades = 0;
	for (int i = 0; i < overlapCount; i++) 
	{
		if( result[i] != NULL )
		{
			//printf("Shape!!!");
			//Solo nos interesan las capsulas
			if (result[i]->isCapsule()) {
				NxShape* capsula = result[i];
				TActorInfo* pActorInfo = (TActorInfo*) capsula->getActor().userData;
				
				//printf("Capsul!!!");

				IPhysicObj * entidadFisica = pActorInfo->pPhysicObj;
				resultado[numEntidades] = entidadFisica;
				++numEntidades;
			}
		}
	}

	if (numEntidades) {
		//Creamos y guardamos el resultado en la variable referenciada que nos pasan, esta la creamos con el tamaño exacto
		physicObjects =  new IPhysicObj*[numEntidades];
		for (int i = 0; i < numEntidades; ++i) {
			physicObjects[i] = resultado[i];
		}
	} else {
		physicObjects = NULL;
	}

	//Destruimos el array de punteros anterior;
	delete resultado;

	return numEntidades;
}
Пример #17
0
void NxVehicle::handleContactPair(NxContactPair& pair, NxU32 carIndex)
{
	NxContactStreamIterator i(pair.stream);
	
	while(i.goNextPair())
	{
		NxShape * s = i.getShape(carIndex);
		
		while(i.goNextPatch())
		{
			const NxVec3& contactNormal = i.getPatchNormal();
			
			while(i.goNextPoint())
			{
				//user can also call getPoint() and getSeparation() here
	
				const NxVec3& contactPoint = i.getPoint();

				//add forces:

				//assuming front wheel drive we need to apply a force at the wheels.
				if (s->is(NX_SHAPE_CAPSULE) && s->userData != NULL) {
					//assuming only the wheels of the car are capsules, otherwise we need more checks.
					//this branch can't be pulled out of loops because we have to do a full iteration through the stream
				
					NxQuat local2global = s->getActor().getGlobalOrientationQuat();
					NxWheel* w = (NxWheel*)s->userData;
					if (!w->getWheelFlag(NX_WF_USE_WHEELSHAPE))
						{
						NxWheel1 * wheel = static_cast<NxWheel1*>(w);
						wheel->contactInfo.otherActor = pair.actors[1-carIndex];
						wheel->contactInfo.contactPosition = contactPoint;
						
						wheel->contactInfo.contactPositionLocal = contactPoint;
						wheel->contactInfo.contactPositionLocal -= _bodyActor->getGlobalPosition();
						local2global.inverseRotate(wheel->contactInfo.contactPositionLocal);
						
						wheel->contactInfo.contactNormal = contactNormal;
						if (wheel->contactInfo.otherActor->isDynamic()) 
							{
							NxVec3 globalV = s->getActor().getLocalPointVelocity(wheel->getWheelPos());
							globalV -= wheel->contactInfo.otherActor->getLinearVelocity();
							local2global.inverseRotate(globalV);
							wheel->contactInfo.relativeVelocity = globalV.x;
							//printf("%2.3f (%2.3f %2.3f %2.3f)\n", wheel->contactInfo.relativeVelocity,
							//	globalV.x, globalV.y, globalV.z);
							} 
						else 
							{
							NxVec3 vel = s->getActor().getLocalPointVelocity(wheel->getWheelPos());
							local2global.inverseRotate(vel);
							wheel->contactInfo.relativeVelocity = vel.x;
							wheel->contactInfo.relativeVelocitySide = vel.z;
							}
						NX_ASSERT(wheel->hasGroundContact());
						//printf(" Wheel %x is touching\n", wheel);
						}
				}
			}
		}		
	}
	//printf("----\n");
}