void UPhysicsHandleComponent::UpdateHandleTransform(const FTransform& NewTransform)
{
	if(!KinActorData)
	{
		return;
	}

#if WITH_PHYSX
	bool bChangedPosition = true;
	bool bChangedRotation = true;

	PxRigidDynamic* KinActor = KinActorData;

	// Check if the new location is worthy of change
	PxVec3 PNewLocation = U2PVector(NewTransform.GetTranslation());
	PxVec3 PCurrentLocation = KinActor->getGlobalPose().p;
	if((PNewLocation - PCurrentLocation).magnitudeSquared() <= 0.01f*0.01f)
	{
		PNewLocation = PCurrentLocation;
		bChangedPosition = false;
	}

	// Check if the new rotation is worthy of change
	PxQuat PNewOrientation = U2PQuat(NewTransform.GetRotation());
	PxQuat PCurrentOrientation = KinActor->getGlobalPose().q;
	if(!(FMath::Abs(PNewOrientation.dot(PCurrentOrientation)) < (1.f - KINDA_SMALL_NUMBER)))
	{
		PNewOrientation = PCurrentOrientation;
		bChangedRotation = false;
	}

	// Don't call moveKinematic if it hasn't changed - that will stop bodies from going to sleep.
	if (bChangedPosition || bChangedRotation)
	{
		KinActor->setKinematicTarget(PxTransform(PNewLocation, PNewOrientation));

		//LOC_MOD
		//PxD6Joint* Joint = (PxD6Joint*) HandleData;
		//if(Joint)// && (PNewLocation - PCurrentLocation).magnitudeSquared() > 0.01f*0.01f)
		//{
		//	PxRigidActor* Actor0, *Actor1;
		//	Joint->getActors(Actor0, Actor1);
		//	//Joint->setDrivePosition(PxTransform(Actor0->getGlobalPose().transformInv(PNewLocation)));
		//	Joint->setDrivePosition(PxTransform::createIdentity());
		//	//Joint->setDriveVelocity(PxVec3(0), PxVec3(0));
		//}
	}
#endif // WITH_PHYSX
}
void defaultCCTInteraction(const PxControllerShapeHit& hit)
{
	PxRigidDynamic* actor = hit.shape->getActor()->is<PxRigidDynamic>();
	if(actor)
	{
		if(actor->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC)
			return;

		if(0)
		{
			const PxVec3 p = actor->getGlobalPose().p + hit.dir * 10.0f;

			PxShape* shape;
			actor->getShapes(&shape, 1);
			PxRaycastHit newHit;
			PxU32 n = PxShapeExt::raycast(*shape, *shape->getActor(), p, -hit.dir, 20.0f, PxHitFlag::ePOSITION, 1, &newHit, false);
			if(n)
			{
				// We only allow horizontal pushes. Vertical pushes when we stand on dynamic objects creates
				// useless stress on the solver. It would be possible to enable/disable vertical pushes on
				// particular objects, if the gameplay requires it.
				const PxVec3 upVector = hit.controller->getUpDirection();
				const PxF32 dp = hit.dir.dot(upVector);
		//		shdfnd::printFormatted("%f\n", fabsf(dp));
				if(fabsf(dp)<1e-3f)
		//		if(hit.dir.y==0.0f)
				{
					const PxTransform globalPose = actor->getGlobalPose();
					const PxVec3 localPos = globalPose.transformInv(newHit.position);
					::addForceAtLocalPos(*actor, hit.dir*hit.length*1000.0f, localPos, PxForceMode::eACCELERATION);
				}
			}
		}

		// We only allow horizontal pushes. Vertical pushes when we stand on dynamic objects creates
		// useless stress on the solver. It would be possible to enable/disable vertical pushes on
		// particular objects, if the gameplay requires it.
		const PxVec3 upVector = hit.controller->getUpDirection();
		const PxF32 dp = hit.dir.dot(upVector);
//		shdfnd::printFormatted("%f\n", fabsf(dp));
		if(fabsf(dp)<1e-3f)
//		if(hit.dir.y==0.0f)
		{
			const PxTransform globalPose = actor->getGlobalPose();
			const PxVec3 localPos = globalPose.transformInv(toVec3(hit.worldPos));
			::addForceAtLocalPos(*actor, hit.dir*hit.length*1000.0f, localPos, PxForceMode::eACCELERATION);
		}
	}
}
Example #3
0
void AddRadialForceToPxRigidDynamic(PxRigidDynamic& PRigidDynamic, const FVector& Origin, float Radius, float Strength, uint8 Falloff)
{
#if WITH_PHYSX
	if (!(PRigidDynamic.getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC))
	{
		float Mass = PRigidDynamic.getMass();
		PxTransform PCOMTransform = PRigidDynamic.getGlobalPose().transform(PRigidDynamic.getCMassLocalPose());
		PxVec3 PCOMPos = PCOMTransform.p; // center of mass in world space
		PxVec3 POrigin = U2PVector(Origin); // origin of radial impulse, in world space
		PxVec3 PDelta = PCOMPos - POrigin; // vector from

		float Mag = PDelta.magnitude(); // Distance from COM to origin, in Unreal scale : @todo: do we still need conversion scale?

		// If COM is outside radius, do nothing.
		if (Mag > Radius)
		{
			return;
		}

		PDelta.normalize();

		// If using linear falloff, scale with distance.
		float ForceMag = Strength;
		if (Falloff == RIF_Linear)
		{
			ForceMag *= (1.0f - (Mag / Radius));
		}

		// Apply force
		PxVec3 PImpulse = PDelta * ForceMag;
		PRigidDynamic.addForce(PImpulse, PxForceMode::eFORCE);
	}
#endif // WITH_PHYSX
}
Example #4
0
void AddRadialImpulseToPxRigidDynamic(PxRigidDynamic& PRigidDynamic, const FVector& Origin, float Radius, float Strength, uint8 Falloff, bool bVelChange)
{
#if WITH_PHYSX
	if (!(PRigidDynamic.getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC))
	{
		float Mass = PRigidDynamic.getMass();
		PxTransform PCOMTransform = PRigidDynamic.getGlobalPose().transform(PRigidDynamic.getCMassLocalPose());
		PxVec3 PCOMPos = PCOMTransform.p; // center of mass in world space
		PxVec3 POrigin = U2PVector(Origin); // origin of radial impulse, in world space
		PxVec3 PDelta = PCOMPos - POrigin; // vector from origin to COM

		float Mag = PDelta.magnitude(); // Distance from COM to origin, in Unreal scale : @todo: do we still need conversion scale?

		// If COM is outside radius, do nothing.
		if (Mag > Radius)
		{
			return;
		}

		PDelta.normalize();

		// Scale by U2PScale here, because units are velocity * mass. 
		float ImpulseMag = Strength;
		if (Falloff == RIF_Linear)
		{
			ImpulseMag *= (1.0f - (Mag / Radius));
		}

		PxVec3 PImpulse = PDelta * ImpulseMag;

		PxForceMode::Enum Mode = bVelChange ? PxForceMode::eVELOCITY_CHANGE : PxForceMode::eIMPULSE;
		PRigidDynamic.addForce(PImpulse, Mode);
	}
#endif // WITH_PHYSX
}
Example #5
0
void getSimplePose( PxActor* actor, float* data ) //TODO rework
{
    PxShape* shp[1];
    PxRigidDynamic* rigid = (PxRigidDynamic*)actor;
    rigid->getShapes( shp, PxU32(1) );
    PxMat44 shape_pose = rigid->getGlobalPose(); //(PxShapeExt::getGlobalPose(*shp[0], *rigid));
    for( int i = 0; i < 4; i++ )
        for( int j = 0; j < 4; j++ )
            data[i*4 + j] = shape_pose[j][i];
}
void UGripMotionControllerComponent::UpdatePhysicsHandleTransform(const FBPActorGripInformation &GrippedActor, const FTransform& NewTransform)
{
	if (!GrippedActor.Actor && !GrippedActor.Component)
		return;

	FBPActorPhysicsHandleInformation * HandleInfo = GetPhysicsGrip(GrippedActor);

	if (!HandleInfo || !HandleInfo->KinActorData)
		return;

#if WITH_PHYSX
	bool bChangedPosition = true;
	bool bChangedRotation = true;

	PxRigidDynamic* KinActor = HandleInfo->KinActorData;
	PxScene* PScene = GetPhysXSceneFromIndex(HandleInfo->SceneIndex);
	SCOPED_SCENE_WRITE_LOCK(PScene);

	// Check if the new location is worthy of change
	PxVec3 PNewLocation = U2PVector(NewTransform.GetTranslation());
	PxVec3 PCurrentLocation = KinActor->getGlobalPose().p;
	if ((PNewLocation - PCurrentLocation).magnitudeSquared() <= 0.01f*0.01f)
	{
		PNewLocation = PCurrentLocation;
		bChangedPosition = false;
	}

	// Check if the new rotation is worthy of change
	PxQuat PNewOrientation = U2PQuat(NewTransform.GetRotation());
	PxQuat PCurrentOrientation = KinActor->getGlobalPose().q;
	if ((FMath::Abs(PNewOrientation.dot(PCurrentOrientation)) > (1.f - SMALL_NUMBER)))
	{
		PNewOrientation = PCurrentOrientation;
		bChangedRotation = false;
	}

	// Don't call moveKinematic if it hasn't changed - that will stop bodies from going to sleep.
	if (bChangedPosition || bChangedRotation)
	{
		KinActor->setKinematicTarget(PxTransform(PNewLocation, PNewOrientation));
	}
#endif // WITH_PHYSX
}
Example #7
0
		void setup(){
			ofSetFrameRate(150);

			w=ofGetScreenWidth();
			h=ofGetScreenHeight();
		        InitPhysX();
        		for(int i=0; i<=300; i++) {
		                if(gScene) StepPhysX();
		                PxVec3 boxPos = gBox->getGlobalPose().p;
                		cout<<"BoxPosition: X:"<<boxPos.x <<" - Y:"<<boxPos.y <<" - Z:"<<boxPos.z<<"\n";
		        }
		}
void 
Spacetime::saveState(void) {
	linearVelocityVector.clear();
	angularVelocityVector.clear();
	globalPoseVector.clear();
	for (int i = 0; i < dynamic_actors.size(); i++) {
		PxRigidDynamic* current = dynamic_actors[i];
		linearVelocityVector.push_back(current->getLinearVelocity());
		angularVelocityVector.push_back(current->getAngularVelocity());
		globalPoseVector.push_back(current->getGlobalPose());
	}
}
void PhysicsSystemPhysX::update(const Time& deltaTime)
{	
	// Step the simulation forward
	mScene->simulate(deltaTime.seconds());

	if (mScene->fetchResults())
	{

		// Now let's push back the transforms into the World
		ComponentManager* colliderBoxManager = getWorld()->getComponentManager<CColliderBox>();
		ComponentManager* transformManager = getWorld()->getComponentManager<CTransform>();
		for (std::size_t i = 0; i < colliderBoxManager->size(); ++i)
		{
			Entity E = colliderBoxManager->getInstanceEntity(i);
			CColliderBox* box = (CColliderBox*)colliderBoxManager->getInstance(i);
			CTransform* transform = (CTransform*)transformManager->getComponentFromEntity(E);

			// Create
			if (box->userData == nullptr)
			{
				PxMaterial* boxMaterial = mPhysics->createMaterial(0.5f, 0.5f, 0.1f);

				PxRigidDynamic* boxActor = mPhysics->createRigidDynamic(PxTransform(transform->position.x, transform->position.y, transform->position.z));
				boxActor->createShape(PxBoxGeometry(10.f, 10.f, 10.f), *boxMaterial);
				PxRigidBodyExt::updateMassAndInertia(*boxActor, 30);
				//boxActor->setLinearVelocity(PxVec3(0, -50, 0));

				mScene->addActor(*boxActor);
				box->userData = boxActor;
			}
			// Update
			else
			{
				PxRigidDynamic* boxActor = (PxRigidDynamic*)box->userData;
				PxTransform pxTransform = boxActor->getGlobalPose();

				transform->position.x = pxTransform.p.x;
				transform->position.y = pxTransform.p.y;
				transform->position.z = pxTransform.p.z;

				transform->rotation.x = pxTransform.q.x;
				transform->rotation.y = pxTransform.q.y;
				transform->rotation.z = pxTransform.q.z;
				transform->rotation.w = pxTransform.q.w;
			}
		}

		syncActors();
	}
}
Example #10
0
void ScoreCallback::onTrigger(PxTriggerPair* pairs, PxU32 count)
{
	for (int i = 0; i < count; i++)
	{
		if (pairs[i].otherActor->isRigidDynamic() && pairs[i].otherActor->getName() == "Ball")
		{
			if (pairs[i].status & PxPairFlag::eNOTIFY_TOUCH_FOUND)
			{

				PxRigidDynamic* ball = static_cast<PxRigidDynamic*>(pairs[i].otherActor);

				if (pairs[i].triggerActor->getName() == "BumperHigh" || pairs[i].triggerActor->getName() == "BumperLow")
				{
					PxRigidDynamic* bumper = static_cast<PxRigidDynamic*>(pairs[i].triggerActor);

					if (pairs[i].triggerActor->getName() == "BumperHigh")
						Pinball::AddScoreHigh = true;
					else
						Pinball::AddScoreLow = true;

					Transform bumperPose = bumper->getGlobalPose();
					Transform ballPose = ball->getGlobalPose();
					Vec3 dir = bumperPose.p - ballPose.p;
					dir.normalize();

					dir = Vec3(dir.x, dir.y, dir.z);
					Pinball::BounceBall = true;
					Pinball::BallBounceDirection = dir;
				}
				if (pairs[i].triggerActor->getName() == "SpinnerSwitch")
				{
						Pinball::EnableSpinners = true;
				}
			}
		}
	}
}
Example #11
0
PxReal labscale::getRegolithSurface()
{
    PxReal regSurf = -PX_MAX_REAL;
    PxU32 nbActors = gPhysX.mScene->getActors(gPhysX.roles.dynamics,gPhysX.cast,MAX_ACTORS_PER_SCENE);
    while (nbActors--)
    {
        PxRigidDynamic* actor = gPhysX.cast[nbActors]->isRigidDynamic();
        if (actor && strcmp(actor->getName(), "regolith") == 0)
        {
            PxReal y = actor->getGlobalPose().p.y;
            if (y>regSurf) regSurf = y;
        }
    }

    return (regSurf + labscale::regolith.diameter/2.0);
}
Example #12
0
void PhysX::AddLocalTorque(PintObjectHandle handle, const Point& local_torque)
{
	PxRigidActor* RigidActor = GetActorFromHandle(handle);
	if(!RigidActor)
	{
		PxShape* Shape = GetShapeFromHandle(handle);
		ASSERT(Shape);
		RigidActor = &Shape->getActor();
	}

	if(RigidActor->getConcreteType()==PxConcreteType::eRIGID_DYNAMIC)
	{
		PxRigidDynamic* RigidDynamic = static_cast<PxRigidDynamic*>(RigidActor);
		const PxVec3 GlobalTorque = RigidDynamic->getGlobalPose().rotate(ToPxVec3(local_torque));
		RigidDynamic->addTorque(GlobalTorque, PxForceMode::eACCELERATION, true);
	}
}
void CSlingshotEngine::loadSlingshot()
{
	Matrix44 transformation2;
	setTranslation(transformation2, Vector3(0.0f, -2.5f, -15.0f));
	Entity* pBird = SceneFactory::CreateBird(transformation2, EntityCategories::BIRD, 1.0f);

	m_pBirdBody = pBird->getSingleComponent<PhysXBody>();
	PxRigidDynamic* pBirdDynamic = m_pBirdBody->getActor()->isRigidDynamic();

	Vector3 arm0Position = PhysXVector::toVector3(m_pArm0Body->getActor()->isRigidActor()->getGlobalPose().p);
	Vector3 arm1Position = PhysXVector::toVector3(m_pArm1Body->getActor()->isRigidActor()->getGlobalPose().p);
	Vector3 birdPosition = PhysXVector::toVector3(pBirdDynamic->getGlobalPose().p);
	Vector3 arm0ToBird = birdPosition - arm0Position;
	Matrix44 arm0LocalFrame;
	setTranslation(arm0LocalFrame, arm0ToBird * 0.5f);
	Vector3 arm1ToBird = birdPosition - arm1Position;
	Matrix44 arm1LocalFrame;
	setTranslation(arm1LocalFrame, arm1ToBird * 0.5f);
	Matrix44 birdLocalFrame;
	setTranslation(birdLocalFrame, arm0ToBird * -0.5f);

	PxPhysics* pPhysics = static_cast<PhysXPhysicsFactory*>(PhysicsFactory::getInstance())->getPhysics();

	m_pArm0Joint = PxD6JointCreate(*pPhysics, m_pArm0Body->getActor()->isRigidActor(),
		PhysXMatrix::toPxTransform(arm0LocalFrame), pBirdDynamic, PhysXMatrix::toPxTransform(birdLocalFrame));

	setTranslation(birdLocalFrame, arm1ToBird * -0.5f);

	m_pArm1Joint = PxD6JointCreate(*pPhysics, m_pArm1Body->getActor()->isRigidActor(),
		PhysXMatrix::toPxTransform(arm1LocalFrame), pBirdDynamic, PhysXMatrix::toPxTransform(birdLocalFrame));

	m_pArm0Joint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
	m_pArm0Joint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
	m_pArm0Joint->setMotion(PxD6Axis::eZ, PxD6Motion::eFREE);
	m_pArm1Joint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
	m_pArm1Joint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
	m_pArm1Joint->setMotion(PxD6Axis::eZ, PxD6Motion::eFREE);

	PxD6JointDrive drive(500.0f, -20.0f, PX_MAX_F32);
	m_pArm0Joint->setDrive(PxD6Drive::eX, drive);
	m_pArm0Joint->setDrive(PxD6Drive::eY, drive);
	m_pArm0Joint->setDrive(PxD6Drive::eZ, drive);
	m_pArm1Joint->setDrive(PxD6Drive::eX, drive);
	m_pArm1Joint->setDrive(PxD6Drive::eY, drive);
	m_pArm1Joint->setDrive(PxD6Drive::eZ, drive);
}
Example #14
0
void defaultCCTInteraction(const PxControllerShapeHit& hit)
{
	PxRigidDynamic* actor = hit.shape->getActor().is<PxRigidDynamic>();
	if(actor)
	{
		if(actor->getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC)
			return;

		// We only allow horizontal pushes. Vertical pushes when we stand on dynamic objects creates
		// useless stress on the solver. It would be possible to enable/disable vertical pushes on
		// particular objects, if the gameplay requires it.
		const PxVec3 upVector = hit.controller->getUpDirection();
		const PxF32 dp = hit.dir.dot(upVector);
//		printf("%f\n", fabsf(dp));
		if(fabsf(dp)<1e-3f)
//		if(hit.dir.y==0.0f)
		{
			const PxTransform globalPose = actor->getGlobalPose();
			const PxVec3 localPos = globalPose.transformInv(toVec3(hit.worldPos));
			::addForceAtLocalPos(*actor, hit.dir*hit.length*1000.0f, localPos, PxForceMode::eACCELERATION);
		}
	}
}
void UPhysicsHandleComponent::GrabComponent(UPrimitiveComponent* InComponent, FName InBoneName, FVector Location, bool bConstrainRotation)
{
	// If we are already holding something - drop it first.
	if(GrabbedComponent != NULL)
	{
		ReleaseComponent();
	}

	if(!InComponent)
	{
		return;
	}

#if WITH_PHYSX
	// Get the PxRigidDynamic that we want to grab.
	FBodyInstance* BodyInstance = InComponent->GetBodyInstance(InBoneName);
	if (!BodyInstance)
	{
		return;
	}

	PxRigidDynamic* Actor = BodyInstance->GetPxRigidDynamic();
	if (!Actor)
		return;

	// Get the scene the PxRigidDynamic we want to grab is in.
	PxScene* Scene = Actor->getScene();
	check(Scene);

	// Get transform of actor we are grabbing
	PxVec3 KinLocation = U2PVector(Location);
	PxTransform GrabbedActorPose = Actor->getGlobalPose();
	PxTransform KinPose(KinLocation, GrabbedActorPose.q);

	// set target and current, so we don't need another "Tick" call to have it right
	TargetTransform = CurrentTransform = P2UTransform(KinPose);

	// If we don't already have a handle - make one now.
	if (!HandleData)
	{
		// Create kinematic actor we are going to create joint with. This will be moved around with calls to SetLocation/SetRotation.
		PxRigidDynamic* KinActor = Scene->getPhysics().createRigidDynamic(KinPose);
		KinActor->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true);
		KinActor->setMass(1.0f);
		KinActor->setMassSpaceInertiaTensor(PxVec3(1.0f, 1.0f, 1.0f));

		// No bodyinstance
		KinActor->userData = NULL;

		// Add to Scene
		Scene->addActor(*KinActor);

		// Save reference to the kinematic actor.
		KinActorData = KinActor;
		
		// Create the joint
		PxVec3 LocalHandlePos = GrabbedActorPose.transformInv(KinLocation);
		PxD6Joint* NewJoint = PxD6JointCreate(Scene->getPhysics(), KinActor, PxTransform::createIdentity(), Actor, PxTransform(LocalHandlePos));

		if(!NewJoint)
		{
			HandleData = 0;
		}
		else
		{
			// No constraint instance
			NewJoint->userData = NULL;
			HandleData = NewJoint;

			// Remember the scene index that the handle joint/actor are in.
			FPhysScene* RBScene = FPhysxUserData::Get<FPhysScene>(Scene->userData);
			const uint32 SceneType = InComponent->BodyInstance.UseAsyncScene() ? PST_Async : PST_Sync;
			SceneIndex = RBScene->PhysXSceneIndex[SceneType];

			// Setting up the joint
			NewJoint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
			NewJoint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
			NewJoint->setMotion(PxD6Axis::eZ, PxD6Motion::eFREE);

			NewJoint->setDrive(PxD6Drive::eX, PxD6JointDrive(LinearStiffness, LinearDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
			NewJoint->setDrive(PxD6Drive::eY, PxD6JointDrive(LinearStiffness, LinearDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
			NewJoint->setDrive(PxD6Drive::eZ, PxD6JointDrive(LinearStiffness, LinearDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
			NewJoint->setDrivePosition(PxTransform(PxVec3(0,0,0)));


			NewJoint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
			NewJoint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
			NewJoint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
			
			bRotationConstrained = bConstrainRotation;
			
			if (bRotationConstrained)
			{
				NewJoint->setDrive(PxD6Drive::eSLERP, PxD6JointDrive(AngularStiffness, AngularDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));

				//NewJoint->setDrive(PxD6Drive::eTWIST, PxD6JointDrive(AngularStiffness, AngularDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
				//NewJoint->setDrive(PxD6Drive::eSWING, PxD6JointDrive(AngularStiffness, AngularDamping, PX_MAX_F32, PxD6JointDriveFlag::eACCELERATION));
				
				//PosJointDesc.setGlobalAxis(NxVec3(0,0,1));
			}

		}
	
	}
#endif // WITH_PHYSX


	GrabbedComponent = InComponent;
	GrabbedBoneName = InBoneName;
}
DestructibleActorJointImpl::DestructibleActorJointImpl(const DestructibleActorJointDesc& desc, DestructibleScene& dscene) :
    joint(NULL)
{
    if (desc.destructible[0] == NULL && desc.destructible[1] == NULL)
    {
        APEX_DEBUG_WARNING("Both destructible actors in DestructibleActorJoint are NULL.");
        return;
    }

    PxRigidActor*	actor[2]		= {desc.actor[0], desc.actor[1]};
    PxVec3			localAxis[2]	= {desc.localAxis[0], desc.localAxis[1]};
    PxVec3			localAnchor[2]	= {desc.localAnchor[0], desc.localAnchor[1]};
    PxVec3			localNormal[2]	= {desc.localNormal[0], desc.localNormal[1]};

    PxTransform		localFrame[2];

    for (int i = 0; i < 2; ++i)
    {
        if (desc.destructible[i] == NULL)
        {
            structure[i] = NULL;
            attachmentChunkIndex[i] = ModuleDestructibleConst::INVALID_CHUNK_INDEX;

            if(NULL == actor[i])
            {
                // World constrained
                PxMat33	rot(desc.globalAxis[i],desc.globalNormal[i],desc.globalAxis[i].cross(desc.globalNormal[i]));

                localFrame[i].p	= desc.globalAnchor[i];
                localFrame[i].q	= PxQuat(rot);
                localFrame[i].q.normalize();
            }
            else
            {
                // Constrained to physics object
                PxMat33	rot(localAxis[i], localNormal[i], localAxis[i].cross(localNormal[i]));

                localFrame[i].p	= localAnchor[i];
                localFrame[i].q	= PxQuat(rot);
                localFrame[i].q.normalize();
            }
            continue;
        }

        PxRigidDynamic* attachActor = NULL;
        DestructibleActorImpl& destructible = ((DestructibleActorProxy*)desc.destructible[i])->impl;
        structure[i] = destructible.getStructure();

        attachmentChunkIndex[i] = desc.attachmentChunkIndex[i];

        if (attachmentChunkIndex[i] >= 0 && attachmentChunkIndex[i] < (int32_t)destructible.getDestructibleAsset()->getChunkCount())
        {
            DestructibleStructure::Chunk& chunk = structure[i]->chunks[destructible.getFirstChunkIndex() + attachmentChunkIndex[i]];
            attachActor = structure[i]->dscene->chunkIntact(chunk);
        }

        SCOPED_PHYSX_LOCK_READ(dscene.getModulePhysXScene());

        if (attachActor == NULL)
        {
            float minDistance = PX_MAX_F32;
            for (uint32_t j = 0; j < destructible.getDestructibleAsset()->getChunkCount(); ++j)
            {
                DestructibleAssetParametersNS::Chunk_Type& source = destructible.getDestructibleAsset()->mParams->chunks.buf[j];
                const bool hasChildren = source.numChildren != 0;
                if (!hasChildren)	// Only attaching to lowest-level chunks, initially
                {
                    DestructibleStructure::Chunk& chunk = structure[i]->chunks[destructible.getFirstChunkIndex() + j];
                    PxRigidDynamic* actor = structure[i]->dscene->chunkIntact(chunk);
                    if (actor)
                    {
                        const float distance = (actor->getGlobalPose().transform(chunk.localSphereCenter) - desc.globalAnchor[i]).magnitude();
                        if (distance < minDistance)
                        {
                            attachActor = actor;
                            attachmentChunkIndex[i] = (int32_t)(destructible.getFirstChunkIndex() + j);
                            minDistance = distance;
                        }
                    }
                }
            }
        }

        if (attachActor == NULL)
        {
            APEX_DEBUG_WARNING("No physx actor could be found in destructible actor %p to attach the joint.", desc.destructible[i]);
            return;
        }

        actor[i] = (PxRigidActor*)attachActor;

        if (attachActor->getScene() != NULL && dscene.getModulePhysXScene() != attachActor->getScene())
        {
            APEX_DEBUG_WARNING("Trying to joint actors from a scene different from the joint scene.");
            return;
        }

        localAnchor[i] = attachActor->getGlobalPose().transformInv(desc.globalAnchor[i]);
        localAxis[i] = attachActor->getGlobalPose().rotateInv(desc.globalAxis[i]);
        localNormal[i] = attachActor->getGlobalPose().rotateInv(desc.globalNormal[i]);

        PxMat33	rot(localAxis[i], localNormal[i], localAxis[i].cross(localNormal[i]));

        localFrame[i].p	= localAnchor[i];
        localFrame[i].q	= PxQuat(rot);
        localFrame[i].q.normalize();
    }

    dscene.getModulePhysXScene()->lockRead();
    switch (desc.type)
    {
    case PxJointConcreteType::eD6:
        joint	= PxD6JointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]);
        break;
    case PxJointConcreteType::eDISTANCE:
        joint	= PxDistanceJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]);
        break;
    case PxJointConcreteType::eFIXED:
        joint	= PxFixedJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]);
        break;
    case PxJointConcreteType::ePRISMATIC:
        joint	= PxPrismaticJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]);
        break;
    case PxJointConcreteType::eREVOLUTE:
        joint	= PxRevoluteJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]);
        break;
    case PxJointConcreteType::eSPHERICAL:
        joint	= PxSphericalJointCreate(dscene.getModulePhysXScene()->getPhysics(), actor[0], localFrame[0], actor[1], localFrame[1]);
        break;
    default:
        PX_ALWAYS_ASSERT();
        break;
    }
    dscene.getModulePhysXScene()->unlockRead();

    PX_ASSERT(joint != NULL);
}
Example #17
0
physx::PxRigidDynamic* CPhysicManager::createDynamicSphere(const Vector3 &position, const float &radius, float mass, bool kinematic, bool trigger, int group, const Logic::Component::IPhysic *component)
{
    assert(m_scene);

    PxTransform pose(Vector3ToPxVec3(position));
    PxSphereGeometry geom(radius);
    PxMaterial *material = m_defaultMaterial;
    float density = mass / ((4/3) * Common::Util::Math::PI * radius * radius * radius);

    PxRigidDynamic *actor = nullptr;
    if(kinematic) {
        actor = PxCreateKinematic(*m_physics,pose,geom,*material,density);
    } else {
        actor = PxCreateDynamic(*m_physics,pose,geom,*material,density);
    }

    if(trigger) {
        PxShape *shape;
        actor->getShapes(&shape,1,0);
        shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
        shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
    }

    actor->userData = (void*)component;

    PxSetGroup(*actor,group);

    setupFiltering(actor,FilterGroup::eSPACE_FILTER,FilterGroup::eSPACE_FILTER);

    PxD6Joint* joint = PxD6JointCreate(*m_physics, actor, PxTransform::createIdentity(), nullptr, actor->getGlobalPose());
    joint->setMotion(PxD6Axis::eX,PxD6Motion::eFREE);
    joint->setMotion(PxD6Axis::eY,PxD6Motion::eLOCKED);
    joint->setMotion(PxD6Axis::eZ,PxD6Motion::eFREE);
    joint->setMotion(PxD6Axis::eSWING1,PxD6Motion::eFREE);
    joint->setMotion(PxD6Axis::eSWING2,PxD6Motion::eLOCKED);
    joint->setMotion(PxD6Axis::eTWIST,PxD6Motion::eLOCKED);
    //TODO release

    //m_scene->addActor(*actor);

    return actor;
}
Example #18
0
void SampleSubmarine::onTickPreRender(float dtime)
{
	// handle mine (and submarine) explosion
	if(mSubmarineActor)
	{
		// explode all touched mines, apply damage and force to submarine
		PxVec3 subMarinePos = mSubmarineActor->getGlobalPose().p;
		const size_t nbExplodeSeamines = mMinesToExplode.size();
		for(PxU32 i=0; i < nbExplodeSeamines; i++)
		{
			Seamine* mine = mMinesToExplode[i];
			PxVec3 explosionPos = mine->mMineHead->getGlobalPose().p;
			
			// disable contact trigger callback of the chain & enable gravity
			const size_t nbLinks = mine->mLinks.size();
			for(PxU32 j = 0; j < nbLinks; j++)
			{
				PxRigidDynamic* link = mine->mLinks[j];
				setupFiltering(link, 0, 0);
				link->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
			}
			
			// remove mine head
			std::vector<Seamine*>::iterator mineIter = std::find(mSeamines.begin(), mSeamines.end(), mine);
			if(mineIter != mSeamines.end())
				mSeamines.erase(mineIter);
			removeActor(mine->mMineHead);
			delete mine;

			// give damage to submarine
			static const PxReal strength = 400.0f;
			PxVec3 explosion = subMarinePos - explosionPos;
			PxReal len = explosion.normalize();
			PxReal damage = strength * (1.0f/len);
			explosion *= damage;
			mSubmarineActor->addForce(explosion*300);
			gSubmarineHealth = PxMax(gSubmarineHealth-PxI32(damage), 0);
			if(gSubmarineHealth == 0)
			{
				mSubmarineCameraController->init(subMarinePos - getCamera().getViewDir()*10.0f, getCamera().getRot());
				explode(mSubmarineActor, subMarinePos /*- explosion*0.2f*/, damage);
				mCameraAttachedToActor = NULL;
				mSubmarineCameraController->setFollowingMode(false);
				mSubmarineActor = NULL;
				break;
			}
		}
		mMinesToExplode.clear();
	}

	// respawn Crabs
	const size_t nbCrabs = mCrabs.size();
	for(PxU32 i = 0; i < nbCrabs; i++)
	{
		Crab* crab = mCrabs[i];
		if(crab->needsRespawn())
		{
			PxRigidDynamic* prevBody = crab->getCrabBody();
			PxVec3 prevPos = prevBody->getGlobalPose().p;
			delete crab;
			mCrabs[i] = SAMPLE_NEW(Crab)(*this, prevPos, mManagedMaterials[MATERIAL_RED]);
			if(gCrab == crab)
				gCrab = mCrabs[i];
			if(mCameraAttachedToActor == prevBody)
				mCameraAttachedToActor = mCrabs[i]->getCrabBody();
		}
	}

	// update camera
	if(mCameraAttachedToActor)
		mSubmarineCameraController->updateFollowingMode(getCamera(), dtime, mCameraAttachedToActor->getGlobalPose().p);

	// start the simulation
	PhysXSample::onTickPreRender(dtime);
}