Esempio n. 1
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;
}
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;
}
Esempio n. 3
0
bool plPXPhysical::OverlapWithController(const plPXPhysicalControllerCore* controller)
{
    NxCapsule cap;
    controller->GetWorldSpaceCapsule(cap);
    NxShape* shape = fActor->getShapes()[0];
    return shape->checkOverlapCapsule(cap);
}
Esempio n. 4
0
//----------------------------------------------------------------------------
// ReleaseAllActors : Alliberem tots els actors de l'escena de PhysX 
//----------------------------------------------------------------------------
bool CPhysicsManager::ReleaseAllActors ( void ) //EUserDataFlag _eFlags )
{
	assert ( m_pScene != NULL );
	assert ( m_pPhysicsSDK != NULL );

	bool isOk = true;

	NxActor** l_ppActorList = m_pScene->getActors();
	NxU32 l_TotalActors		= m_pScene->getNbActors();

	while ( l_TotalActors -- )
	{
		NxActor* nxActor = *l_ppActorList;
		if ( nxActor != 0)
		{
			NxArray<NxCCDSkeleton*> skeletons;
			for (NxU32 i = 0; i < nxActor->getNbShapes(); i++) 
			{
				NxShape* shape = nxActor->getShapes()[i];
				if (shape->getCCDSkeleton() != NULL) {
					skeletons.pushBack(shape->getCCDSkeleton());
				}
			}

			for (NxU32 i = 0; i < skeletons.size(); i++) 
			{
				m_pPhysicsSDK->releaseCCDSkeleton(*skeletons[i]);
			}
			m_pScene->releaseActor(*nxActor);
			nxActor = 0;
		}
	}
	
	return isOk;
}
bool CPhysicsManager::ReleasePhysicActor (CPhysicActor* actor)
{
	assert(actor != NULL);
	assert(m_pScene != NULL);
	assert(m_pPhysicsSDK != NULL);

	bool isOk = false;
	NxActor* nxActor = actor->GetPhXActor();

	if( nxActor != 0)
	{
		NxArray<NxCCDSkeleton*> skeletons;
		for (NxU32 i = 0; i < nxActor->getNbShapes(); i++) 
		{
			NxShape* shape = nxActor->getShapes()[i];
			if (shape->getCCDSkeleton() != NULL) {
				skeletons.pushBack(shape->getCCDSkeleton());
			}
		}

		for (NxU32 i = 0; i < skeletons.size(); i++) 
		{
			m_pPhysicsSDK->releaseCCDSkeleton(*skeletons[i]);
		}
		m_pScene->releaseActor(*nxActor);
		nxActor = 0;
	}
	
	return true;
}
Esempio n. 6
0
// Release one of the shapes from our compound. At the moment
// we are just releasing the first object in the array.
// As long as the index is below the number of shapes (uiNumShapes)
// it should work, but be careful about releasing an object inside
// other objects (for performance reasons)
void ReleaseRandomShape()
{
	// Get the array of pointers to shapes
	NxShape*const* ppShapeArray = mainBox->getShapes();

	// Find out how many shapes there are left
	NxU32 uiNumShapes = mainBox->getNbShapes();

	// Don't remove the last shape (or we'll have a shapeless actor)
	if (uiNumShapes < 2)
		return;

	// Record the pose of the shape we intend to release, for later
	NxShape* pShapeToRelease = ppShapeArray[0];
	NxMat34 mNewBoxPose = pShapeToRelease->getGlobalPose();

	// Release the object, and make a note of the new total number of objects
	mainBox->releaseShape(*pShapeToRelease);
	--iNumberObjects;

	// We need to update the mass and intertial tensors. We choose to base it
	// on the density of the objects, which are all fBoxDensity
	mainBox->updateMassFromShapes(fBoxDensity, 0.0f);

	// Create the new box, in the pose we recorded earlier
	CreateBoxPiece(mNewBoxPose);
}
Esempio n. 7
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);
}
int CPhysicsActor::GetCollisionGroup()
{
	NxShape*const* shapes = m_Actor->getShapes();
   	NxShape* shape;

	shape = shapes[0];

	return shape->getGroup();
}
Esempio n. 9
0
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;
}
Esempio n. 10
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;
}
Esempio n. 11
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

	}*/

	
	

}
		//-----------------------------------------------------------------------
		void PhysXActorExtern::_processParticle(
			ParticleTechnique* particleTechnique, 
			Particle* particle, 
			Ogre::Real timeElapsed, 
			bool firstParticle)
		{
			// Only update after a PhysX simulation step
			if (mSynchronize)
			{
				if (particle->particleType != Particle::PT_VISUAL)
					return;

				if (!particle->physicsActor)
					return;

				VisualParticle* visualParticle = static_cast<VisualParticle*>(particle);
				PhysXActor* physXActor = static_cast<PhysXActor*>(particle->physicsActor);
				NxActor* nxActor = physXActor->nxActor;
				if (nxActor)
				{
					// Synchronize both the particle and the pysicsActor with the nxActor
					particle->position = PhysXMath::convert(nxActor->getGlobalPosition());
					particle->direction = PhysXMath::convert(nxActor->getLinearVelocity());
					visualParticle->orientation = PhysXMath::convert(nxActor->getGlobalOrientationQuat());
					physXActor->position = particle->position;
					physXActor->direction = particle->direction;
					physXActor->orientation = visualParticle->orientation;

					if (nxActor->getNbShapes())
					{
						NxShape *shape = nxActor->getShapes()[0]; // Max one.
						switch(shape->getType())
						{
							case NX_SHAPE_BOX:
								(static_cast<NxBoxShape*>(shape))->setDimensions(
									PhysXMath::convert(0.5 * Ogre::Vector3(
									visualParticle->width, visualParticle->height, visualParticle->depth)));
							break;
							 case NX_SHAPE_SPHERE:
								(static_cast<NxSphereShape*>(shape))->setRadius(0.5f * visualParticle->width);
							break;
							case NX_SHAPE_CAPSULE:
							{
								(static_cast<NxCapsuleShape*>(shape))->setRadius(0.5f * visualParticle->width);
								(static_cast<NxCapsuleShape*>(shape))->setHeight(0.5f * visualParticle->height);
							}
							break;
						}
					}
				}
			}
		}
Esempio n. 13
0
	virtual void  onContactNotify(NxContactPair& pair, NxU32 events)
	{
		
		NxU32 carIndex = 0;
		if (isCar(pair.actors[0]))
			carIndex = 0;
		else if (isCar(pair.actors[1]))
			carIndex = 1;
		else
			return;
		
		//ignore the 'both are cars' case for now.

		// Iterate through contact points
		NxContactStreamIterator i(pair.stream);
		//user can call getNumPairs() here
		while (i.goNextPair())
        {
			//user can also call getShape() and getNumPatches() here
			NxShape * s = i.getShape(carIndex);
			while (i.goNextPatch())
            {
				//user can also call getPatchNormal() and getNumPoints() here
				const NxVec3& contactNormal = i.getPatchNormal();
				while (i.goNextPoint())
                {
					//user can also call getPoint() and getSeparation() here
					const NxVec3& contactPoint = i.getPoint();

					NxVec3 contactNormalForce = pair.sumNormalForce;
					NxVec3 contactFrictionForce = pair.sumFrictionForce;

					//add forces:

					//assuming front wheel drive we need to apply a force at the wheels.
					if (s->is(NX_SHAPE_CAPSULE))		//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
                    {
						CarWheelContact cwc;
						cwc.car = pair.actors[carIndex];
						cwc.wheel = s;
						cwc.contactPoint = contactPoint;
						cwc.contactNormalForce = contactNormalForce;
						cwc.contactFrictionForce = contactFrictionForce;
						wheelContactPoints.pushBack(cwc);
						//#error too bad this is illegal (reentry) and also technically busted because the accumulators get zeroed after this returns.
						//pair.actors[carIndex]->addForceAtPos(NxVec3(100,0,0),contactPoint);
                    }
                }
            }		
        }
	}
Esempio n. 14
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();

}
Esempio n. 15
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;
}
Esempio n. 16
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;
	}
Esempio n. 17
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);
	}
	
}
void CPhysicsManager::ReleaseActorCapsule (CPhysicActor* actor)
{
	assert(actor != NULL);
	assert(m_pScene != NULL);
	assert(m_pPhysicsSDK != NULL);

	NxActor* nxActor = actor->GetPhXActor();
	if( nxActor != 0)
	{
		NxArray<NxCCDSkeleton*> skeletons;
		for (NxU32 i = 0; i < nxActor->getNbShapes(); i++) 
		{
			NxShape* shape = nxActor->getShapes()[i];
			if (shape->isCapsule())
				shape->setGroup(ECG_LAST_GROUP);	
		}
	}
}
Esempio n. 19
0
void CPhysicsActor::SetCollisionGroup( COLLISIONGROUP group )
{
	unsigned int numShapes = m_Actor->getNbShapes();
	NxShape*const* shapes = m_Actor->getShapes();
   	NxShape* shape;

	if( group < 0 || group >= 32 )
	{
		m_ToolBox->Log( LOGERROR, _T("CPhysicsObject::SetCollisionGroup() Invalid collision group! Group must be between 1-31!\n") );
		return;
	}

	while( numShapes-- )
	{
		shape = shapes[numShapes];
   		shape->setGroup( group );
	}
}
Esempio n. 20
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);
            }
        }
    }
Esempio n. 21
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 );
	}
}
Esempio n. 22
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;
}
Esempio n. 23
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
	}
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;
}
Esempio n. 25
0
void AddUserDataToShapes(NxActor* actor)
{
    NxU32 i = 0;

	NxShape*const* shapes = actor->getShapes();
	NxU32 nbShapes = actor->getNbShapes();
	while (nbShapes--)
	{
		NxShape* shape = shapes[nbShapes];
        shape->userData = new ShapeUserData;
		ShapeUserData* sud = (ShapeUserData*)(shape->userData);
		sud->id = i++;
		if (shape->getType() == NX_SHAPE_CONVEX)
		{
			sud->mesh = new NxConvexMeshDesc;
			shape->isConvexMesh()->getConvexMesh().saveToDesc(*(NxConvexMeshDesc*)sud->mesh);
		}
		if (shape->getType() == NX_SHAPE_MESH)
		{
			sud->mesh = new NxTriangleMeshDesc;
			shape->isTriangleMesh()->getTriangleMesh().saveToDesc(*(NxTriangleMeshDesc*)sud->mesh);
		}
	}
}
Esempio n. 26
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);

	}
}
Esempio n. 27
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
        }
    }
Esempio n. 28
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;
}
Esempio n. 29
0
// Make a visible object that can be viewed by users for debugging purposes.
plDrawableSpans* plPXPhysical::CreateProxy(hsGMaterial* mat, hsTArray<uint32_t>& idx, plDrawableSpans* addTo)
{
    plDrawableSpans* myDraw = addTo;
    hsMatrix44 l2w, unused;
    GetTransform(l2w, unused);
    
    bool blended = ((mat->GetLayer(0)->GetBlendFlags() & hsGMatState::kBlendMask));

    NxShape* shape = fActor->getShapes()[0];

    NxTriangleMeshShape* trimeshShape = shape->isTriangleMesh();
    if (trimeshShape)
    {
        NxTriangleMeshDesc desc;
        trimeshShape->getTriangleMesh().saveToDesc(desc);

        hsTArray<hsPoint3>  pos;
        hsTArray<uint16_t>    tris;

        const int kMaxTris = 10000;
        const int kMaxVerts = 32000;
        if ((desc.numVertices < kMaxVerts) && (desc.numTriangles < kMaxTris))
        {
            pos.SetCount(desc.numVertices);
            tris.SetCount(desc.numTriangles * 3);

            for (int i = 0; i < desc.numVertices; i++ )
                pos[i] = GetTrimeshVert(desc, i);

            for (int i = 0; i < desc.numTriangles; i++)
                GetTrimeshTri(desc, i, &tris[i*3]);

            myDraw = plDrawableGenerator::GenerateDrawable(pos.GetCount(), 
                                            pos.AcquireArray(),
                                            nil,    // normals - def to avg (smooth) norm
                                            nil,    // uvws
                                            0,      // uvws per vertex
                                            nil,    // colors - def to white
                                            true,   // do a quick fake shade
                                            nil,    // optional color modulation
                                            tris.GetCount(),
                                            tris.AcquireArray(),
                                            mat,
                                            l2w,
                                            blended,
                                            &idx,
                                            myDraw);
        }
        else
        {
            int curTri = 0;
            int trisToDo = desc.numTriangles;
            while (trisToDo > 0)
            {
                int trisThisRound = trisToDo > kMaxTris ? kMaxTris : trisToDo;
                
                trisToDo -= trisThisRound;

                pos.SetCount(trisThisRound * 3);
                tris.SetCount(trisThisRound * 3);

                for (int i = 0; i < trisThisRound; i++)
                {
                    GetTrimeshTri(desc, curTri, &tris[i*3]);
                    pos[i*3 + 0] = GetTrimeshVert(desc, tris[i*3+0]);
                    pos[i*3 + 1] = GetTrimeshVert(desc, tris[i*3+1]);
                    pos[i*3 + 2] = GetTrimeshVert(desc, tris[i*3+2]);

                    curTri++;
                }
                myDraw = plDrawableGenerator::GenerateDrawable(pos.GetCount(), 
                                                pos.AcquireArray(),
                                                nil,    // normals - def to avg (smooth) norm
                                                nil,    // uvws
                                                0,      // uvws per vertex
                                                nil,    // colors - def to white
                                                true,   // do a quick fake shade
                                                nil,    // optional color modulation
                                                tris.GetCount(),
                                                tris.AcquireArray(),
                                                mat,
                                                l2w,
                                                blended,
                                                &idx,
                                                myDraw);
            }
        }
    }

    NxConvexShape* convexShape = shape->isConvexMesh();
    if (convexShape)
    {
        NxConvexMeshDesc desc;
        convexShape->getConvexMesh().saveToDesc(desc);

        hsTArray<hsPoint3>  pos;
        hsTArray<uint16_t>    tris;

        pos.SetCount(desc.numVertices);
        tris.SetCount(desc.numTriangles * 3);

        for (int i = 0; i < desc.numVertices; i++ )
            pos[i] = GetConvexVert(desc, i);

        for (int i = 0; i < desc.numTriangles; i++)
            GetConvexTri(desc, i, &tris[i*3]);

        myDraw = plDrawableGenerator::GenerateDrawable(pos.GetCount(), 
            pos.AcquireArray(),
            nil,    // normals - def to avg (smooth) norm
            nil,    // uvws
            0,      // uvws per vertex
            nil,    // colors - def to white
            true,   // do a quick fake shade
            nil,    // optional color modulation
            tris.GetCount(),
            tris.AcquireArray(),
            mat,
            l2w,
            blended,
            &idx,
            myDraw);
    }

    NxSphereShape* sphere = shape->isSphere();
    if (sphere)
    {
        float radius = sphere->getRadius();
        hsPoint3 offset = plPXConvert::Point(sphere->getLocalPosition());
        myDraw = plDrawableGenerator::GenerateSphericalDrawable(offset, radius,
            mat, l2w, blended,
            nil, &idx, myDraw);
    }

    NxBoxShape* box = shape->isBox();
    if (box)
    {
        hsPoint3 dim = plPXConvert::Point(box->getDimensions());
        myDraw = plDrawableGenerator::GenerateBoxDrawable(dim.fX*2.f, dim.fY*2.f, dim.fZ*2.f,
            mat,l2w,blended,
            nil,&idx,myDraw);
    }
    return myDraw;
}
Esempio n. 30
0
bool plPXPhysical::OverlapWithCapsule(NxCapsule& cap)
{
    NxShape* shape = fActor->getShapes()[0];
    return shape->checkOverlapCapsule(cap);
}