예제 #1
0
void PhysX3::ApplyActionAtPoint(PintObjectHandle handle, PintActionType action_type, const Point& action, const Point& pos)
{
	PxRigidActor* RigidActor = GetActorFromHandle(handle);
	if(!RigidActor)
	{
		PxShape* Shape = GetShapeFromHandle(handle);
		ASSERT(Shape);
#ifdef SUPPORT_SHARED_SHAPES
		RigidActor = Shape->getActor();
#else
		RigidActor = &Shape->getActor();
#endif
	}

	if(RigidActor->getConcreteType()==PxConcreteType::eRIGID_DYNAMIC)
	{
		PxRigidDynamic* RigidDynamic = static_cast<PxRigidDynamic*>(RigidActor);
		if(!(RigidDynamic->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC))
		{
			PxForceMode::Enum mode;
			if(action_type==PINT_ACTION_FORCE)
				mode = PxForceMode::eFORCE;
			else if(action_type==PINT_ACTION_IMPULSE)
				mode = PxForceMode::eIMPULSE;
			else ASSERT(0);

			PxRigidBodyExt::addForceAtPos(*RigidDynamic, ToPxVec3(action), ToPxVec3(pos), mode);
		}
	}
}
예제 #2
0
PR PhysX3::GetWorldTransform(PintObjectHandle handle)
{
	PxTransform Pose;

	PxRigidActor* RigidActor = GetActorFromHandle(handle);
	if(RigidActor)
	{
		Pose = RigidActor->getGlobalPose();
	}
	else
	{
		PxShape* Shape = GetShapeFromHandle(handle);
		ASSERT(Shape);
#ifdef SUPPORT_SHARED_SHAPES
		ASSERT(Shape->getActor());
		Pose = PxShapeExt::getGlobalPose(*Shape, *Shape->getActor());
#else
		Pose = PxShapeExt::getGlobalPose(*Shape);
#endif
	}

	return PR(ToPoint(Pose.p), ToQuat(Pose.q));
}
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);
		}
	}
}
예제 #4
0
void PhysX::AddWorldImpulseAtWorldPos(PintObjectHandle handle, const Point& world_impulse, const Point& world_pos)
{
	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);
		PxRigidBodyExt::addForceAtPos(*RigidDynamic, ToPxVec3(world_impulse), ToPxVec3(world_pos), PxForceMode::eIMPULSE);
	}
}
예제 #5
0
PxU32 SampleBridges::getBehaviorFlags(const PxShape& shape)
{
	const char* actorName = shape.getActor().getName();
#ifdef PLATFORMS_AS_OBSTACLES
	PX_ASSERT(actorName!=gPlatformName);	// PT: in this mode we should have filtered out those guys already
#endif

	// PT: ride on planks
	if(actorName==gPlankName)
		return PxControllerBehaviorFlag::eCCT_CAN_RIDE_ON_OBJECT;

	// PT: ride & slide on platforms
	if(actorName==gPlatformName)
		return PxControllerBehaviorFlag::eCCT_CAN_RIDE_ON_OBJECT|PxControllerBehaviorFlag::eCCT_SLIDE;

	return 0;
}
예제 #6
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);
	}
}
	bool ParticleChain::checkPenetration(const Ogre::Vector3 &position, Ogre::Vector3 &closestSurfacePos, Ogre::Vector3 &collisionNormal)
	{
		PxShape *hit = nullptr;
		PxVec3 pxPos = Convert::toPx(position);
		if (mPhysXScene->getPxScene()->overlapAny(PxSphereGeometry(0.05f), PxTransform(pxPos), hit))
		{
			PxVec3 actorCenter = hit->getActor().getWorldBounds().getCenter();
			PxVec3 rayDir = actorCenter - pxPos;
			rayDir.normalize();
			PxVec3 rayOrigin = pxPos - rayDir.multiply(PxVec3(0.2f, 0.2f, 0.2f));
			if (mPhysXScene->getPxScene()->overlapAny(PxSphereGeometry(0.05f), PxTransform(rayOrigin), hit)) return false;
			PxRaycastHit rayHit;
			if (mPhysXScene->getPxScene()->raycastSingle(rayOrigin, rayDir,  0.2f, PxSceneQueryFlag::eIMPACT|PxSceneQueryFlag::eNORMAL|PxSceneQueryFlag::eDISTANCE, rayHit))
			{
				closestSurfacePos = Convert::toOgre(rayHit.impact);
				collisionNormal = Convert::toOgre(rayHit.normal);
				return true;
			}
		}
		return false;
	}
bool Test::GeometryHelpers::testForOverlap(const PxShape& s0, const PxGeometry& g1, const PxTransform& globalPose1)
{
	return PxGeometryQuery::overlap(g1, globalPose1, s0.getGeometry().any(), PxShapeExt::getGlobalPose(s0, *s0.getActor()));
}
예제 #9
0
void SampleParticles::Raygun::update(float dtime)
{
	if(!isEnabled())
		return;
	
	PX_ASSERT(mSample && mForceSmokeCapsule && mForceWaterCapsule && mRenderActor);

	// access properties from sample
	PxScene& scene = mSample->getActiveScene();
	PxVec3 position = mSample->getCamera().getPos();
	PxTransform cameraPose = mSample->getCamera().getViewMatrix();
	PxMat33 cameraBase(cameraPose.q);
	PxVec3 cameraForward = -cameraBase[2];
	PxVec3 cameraUp = -cameraBase[1];
	
	// perform raycast here and update impact point
	PxRaycastHit hit;
	mIsImpacting = scene.raycastSingle(cameraPose.p, cameraForward, 500.0f, PxSceneQueryFlags(0xffffffff), hit);
	float impactParam = mIsImpacting ? (hit.impact - position).magnitude() : FLT_MAX;	

	PxTransform rayPose(position + cameraUp * 0.5f, cameraPose.q*PxQuat(PxHalfPi, PxVec3(0,1,0)));

	updateRayCapsule(mForceSmokeCapsule, rayPose, 1.0f);
	updateRayCapsule(mForceWaterCapsule, rayPose, 0.3f);
	mRenderActor->setTransform(rayPose);

	// if we had an impact
	if (impactParam < FLT_MAX)
	{
		PxVec3 impactPos = position + cameraForward*impactParam;
		// update emitter with new impact point and direction
		if(mSmokeEmitter.emitter)
			mSmokeEmitter.emitter->setLocalPose(PxTransform(impactPos, directionToQuaternion(-cameraForward)));
		if(mDebrisEmitter.emitter)
			mDebrisEmitter.emitter->setLocalPose(PxTransform(impactPos, directionToQuaternion(-cameraForward)));

		// spawn new RB debris
		if(mRbDebrisTimer < 0.0f && impactParam < FLT_MAX) 
		{
			mRbDebrisTimer = RAYGUN_RB_DEBRIS_RATE;

			PxVec3 randDir(getSampleRandom().rand(-1.0f, 1.0f),
				getSampleRandom().rand(-1.0f, 1.0f),
				getSampleRandom().rand(-1.0f, 1.0f));
			PxVec3 vel = -7.0f * (cameraForward + RAYGUN_RB_DEBRIS_ANGLE_RANDOMNESS * randDir.getNormalized());
			PxVec3 dim(getSampleRandom().rand(0.0f, RAYGUN_RB_DEBRIS_SCALE),
				getSampleRandom().rand(0.0f, RAYGUN_RB_DEBRIS_SCALE),
				getSampleRandom().rand(0.0f, RAYGUN_RB_DEBRIS_SCALE));
			// give spawn position, initial velocity and dimensions, spawn convex
			// which will not act in scene queries
			PxConvexMesh* convexMesh = generateConvex(mSample->getPhysics(), mSample->getCooking(), RAYGUN_RB_DEBRIS_SCALE);
			mSample->runtimeAssert(convexMesh, "Error generating convex for debris.\n");
			PxRigidDynamic* debrisActor = PxCreateDynamic(
				mSample->getPhysics(), 
				PxTransform(impactPos - cameraForward * 0.5f), 
				PxConvexMeshGeometry(convexMesh), 
				mSample->getDefaultMaterial(), 1.f);  
			mSample->getActiveScene().addActor(*debrisActor);

			PX_ASSERT(debrisActor->getNbShapes() == 1);
			PxShape* debrisShape;
			debrisActor->getShapes(&debrisShape, 1);
			debrisShape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, false);
			debrisActor->setLinearVelocity(vel);
			debrisActor->setActorFlag(PxActorFlag::eVISUALIZATION, true);
			debrisActor->setAngularDamping(0.5f);
			
			// default material is green for debris
			RenderMaterial* debriMaterial = mSample->getMaterial(MATERIAL_HEIGHTFIELD);
			if(!debriMaterial) 
			{
				debriMaterial = mSample->mRenderMaterials[MATERIAL_GREEN];				
			}
			mSample->createRenderObjectsFromActor(debrisActor, debriMaterial);
			mDebrisLifetime[debrisShape] = RAYGUN_RB_DEBRIS_LIFETIME;
		}
	}

	// update debris lifetime, remove if life ends
	DebrisLifetimeMap::iterator it = mDebrisLifetime.begin();
	while(it != mDebrisLifetime.end()) 
	{
		(*it).second -= dtime;
		if((*it).second < 0.0f) 
		{
			PxShape* debrisShape = (*it).first;
			PX_ASSERT(debrisShape);

			// remove convex mesh
			PxConvexMeshGeometry geometry;
			bool isConvex = debrisShape->getConvexMeshGeometry(geometry);
			PX_ASSERT(isConvex);
			PX_UNUSED(isConvex);
			geometry.convexMesh->release();
			
			// remove render and physics actor
			PxRigidActor& actorToRemove = debrisShape->getActor();
			mSample->removeActor(&actorToRemove);			
			actorToRemove.release();
			
			// remove actor from lifetime map
			mDebrisLifetime.erase(it);
			it = mDebrisLifetime.begin();
			continue;
		}
		++it;
	}
}