Example #1
0
PxActor* World::createRigidBody(const PxGeometry& geometry, float mass, const ofVec3f& pos, const ofQuaternion& rot, float density)
{
	assert(inited);
	
	PxTransform transform;
	toPx(pos, transform.p);
	toPx(rot, transform.q);
	
	PxActor *actor;
	
	if (mass > 0)
	{
		PxRigidDynamic* rigid = PxCreateDynamic(*physics, transform, geometry, *defaultMaterial, density);
		rigid->setMass(mass);
		rigid->setLinearDamping(0.25);
		rigid->setAngularDamping(0.25);
		
		actor = rigid;
	}
	else
	{
		PxRigidStatic *rigid = PxCreateStatic(*physics, transform, geometry, *defaultMaterial);
		actor = rigid;
	}
	
	scene->addActor(*actor);
	
	return actor;
}
PxRigidDynamic* PxCloneDynamic(PxPhysics& physicsSDK, 
							   const PxTransform& transform,
							   const PxRigidDynamic& from)
{
	PxRigidDynamic* to = physicsSDK.createRigidDynamic(transform);
	if(!to)
		return NULL;

	copyStaticProperties(*to, from);

	to->setRigidDynamicFlags(from.getRigidDynamicFlags());

	to->setMass(from.getMass());
	to->setMassSpaceInertiaTensor(from.getMassSpaceInertiaTensor());
	to->setCMassLocalPose(from.getCMassLocalPose());

	to->setLinearVelocity(from.getLinearVelocity());
	to->setAngularVelocity(from.getAngularVelocity());

	to->setLinearDamping(from.getAngularDamping());
	to->setAngularDamping(from.getAngularDamping());

	to->setMaxAngularVelocity(from.getMaxAngularVelocity());

	PxU32 posIters, velIters;
	from.getSolverIterationCounts(posIters, velIters);
	to->setSolverIterationCounts(posIters, velIters);

	to->setSleepThreshold(from.getSleepThreshold());

	to->setContactReportThreshold(from.getContactReportThreshold());

	return to;
}
Example #3
0
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity = PxVec3(0))
{
	PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
	dynamic->setAngularDamping(0.5f);
	dynamic->setLinearVelocity(velocity);
	gScene->addActor(*dynamic);
	return dynamic;
}
Example #4
0
void PhysXInterface::createSphere( int id, double radius, double density )
{
    PxSphereGeometry geometry( radius );
    PxRigidDynamic* actor = PxCreateDynamic( *_physicsSDK, PxTransform::createIdentity(), geometry, *_material, density );
    if ( actor )
    {
        actor->setAngularDamping( 0.75 );
        _scene->addActor( *actor );
        _actors[id] = actor;
    }
}
Example #5
0
void PhysXInterface::createBox( int id, const osg::Vec3& dim, double density )
{
    PxBoxGeometry geometry( PxVec3(dim[0], dim[1], dim[2]) );
    PxRigidDynamic* actor = PxCreateDynamic( *_physicsSDK, PxTransform::createIdentity(), geometry, *_material, density );
    if ( actor )
    {
        actor->setAngularDamping( 0.75 );
        _scene->addActor( *actor );
        _actors[id] = actor;
    }
}
void PhysXPhysics::AddShape(Actor* pActor, PxGeometry* geometry, float density, const std::string& physicsMaterial, bool gravityEnabled, float linearDamping, float angularDamping, const std::string& bodyType)
{
	BE_ASSERT(pActor);
	ActorId actorId = pActor->GetId();
	BE_ASSERTf(m_actorRigidBodyMap.find(actorId) == m_actorRigidBodyMap.end(), "Actor with more than one rigidbody");

	Mat4x4 transform = Mat4x4::g_Identity;
	
	TransformComponent* pTransformComponent = pActor->GetComponent<TransformComponent>(TransformComponent::g_Name);

	if (pTransformComponent)
	{
		transform = pTransformComponent->GetTransform();
	}
	else 
	{
		//Doesnt work without transform
		BE_ERROR("Actor %s PhysicsComponent requires Shape to have Transform Component: %d", actorId);
		return;
	}

	PhysicsMaterialData material(LookupMaterialData(physicsMaterial));
	PxMaterial* mat = m_pPhysicsSdk->createMaterial(material.m_friction, material.m_friction, material.m_restitution);

	Vec3 translation, scale;
	Quaternion rotation;
	
	bool ok = transform.Decompose(translation, rotation, scale);
	PxQuat pxRot;
	PxVec3 pxLoc;
	Vec3ToPxVec(translation, &pxLoc);
	QuaternionToPxQuat(rotation, &pxRot);
	PxTransform t(pxLoc, pxRot);

	if (bodyType == "Dynamic")
	{
		PxRigidDynamic* body = PxCreateDynamic(*m_pPhysicsSdk, t, *geometry, *mat, density);
		body->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, !gravityEnabled);
		PxRigidBodyExt::updateMassAndInertia(*body, density);
		body->setLinearDamping(linearDamping);
		body->setAngularDamping(angularDamping);
		m_pScene->addActor(*body);

		m_actorRigidBodyMap[actorId] = body;
		m_rigidBodyActorMap[body] = actorId;
	}
	else
	{
		BE_ERROR("[Physics] BodyType not supported: %s", bodyType.c_str());
		return;
	}
}
Example #7
0
PxRigidDynamic* CreateSphere(const PxVec3& pos, const PxReal radius, const PxReal density) {
	// Add a single-shape actor to the scene
	PxTransform transform(pos, PxQuat::createIdentity());
	PxSphereGeometry geometry(radius);

	PxMaterial* mMaterial = gPhysicsSDK->createMaterial(0.5, 0.5, 0.5);

	PxRigidDynamic *actor = PxCreateDynamic(*gPhysicsSDK, transform, geometry, *mMaterial, density);
	if(!actor)
		cerr<<"create actor failed!"<<endl;
	actor->setAngularDamping(0.75);
	actor->setLinearVelocity(PxVec3(0, 0, 0));
	gScene->addActor(*actor);
	return actor;
}
// add some physics objects into the scene
void AddPhyObjects()
{
	PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0, 1, 0, 0), *gMaterial);
	gScene->addActor(*groundPlane);

	PxShape* shape = gPhysics->createShape(PxBoxGeometry(1.0f, 1.0f, 1.0f), *gMaterial);
	PxTransform localTm(PxVec3(-3.0f, 5.0f, 0.f));
	PxRigidDynamic* body = gPhysics->createRigidDynamic(localTm);
	body->attachShape(*shape);
	PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
	gScene->addActor(*body);

	shape->release();

	shape = gPhysics->createShape(PxSphereGeometry(1.0f), *gMaterial);
	PxTransform localTmS(PxVec3(3.0f, 5.0f, 0.f));
	body = gPhysics->createRigidDynamic(localTmS);
	body->attachShape(*shape);
	PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
	gScene->addActor(*body);

	shape->release();

	PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, PxTransform(PxVec3(0, 20, 20)), PxSphereGeometry(1), *gMaterial, 10.0f);
	dynamic->setAngularDamping(0.5f);
	dynamic->setLinearVelocity(PxVec3(0, -5, -10));
	gScene->addActor(*dynamic);

	// add capsule into the scene
	shape = gPhysics->createShape(PxCapsuleGeometry(1.0f, 3.0f), *gMaterial);
	PxTransform localTmC(PxVec3(3.0f, 5.0f, -3.f));
	body = gPhysics->createRigidDynamic(localTmC);
	body->attachShape(*shape);
	PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
	gScene->addActor(*body);

	// add a static box as the trigger
	shape = gPhysics->createShape(PxBoxGeometry(1.0f, 1.0f, 1.0f), *gMaterial);
	PxTransform localTmTrigger(PxVec3(0.0f, 1.0f, -10.f));
	body = gPhysics->createRigidDynamic(localTmTrigger);
	shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
	shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
	body->attachShape(*shape);
	body->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
	gScene->addActor(*body);

	shape->release();
}
Example #9
0
bool Collider::Init(bool isDynamic)
{
	bool ret = false;

	const Transform& transform = mOwner.GetTransform();

	mTransform.position = transform.position;
	mTransform.rotation = transform.rotation;

	PxVec3 pos = ConvertPxVec3(transform.position);
	PxQuat rot = ConvertPxQuat(transform.rotation);

	PxScene* scene = mOwner.GetScene().GetPxScene();
	CHECK(scene);

	if (isDynamic)
	{
		PxRigidDynamic* dyn = gPhysics->createRigidDynamic(PxTransform(pos, rot));
		dyn->setLinearDamping(0.25);
		dyn->setAngularDamping(0.25);
		mActor = dyn;
		mRigidBody = new RigidBody(*dyn);
	}
	else
	{
		mActor = gPhysics->createRigidStatic(PxTransform(pos, rot));
	}

	CHECK(mActor);

	mActor->userData = &mOwner;

	OnInitShape();

	CHECK(mGizmo);
	mOwner.GetScene().AddGizmo(mGizmo);

	mGizmo->SetColor(Color(0, 1, 0, 1));

	scene->addActor(*mActor);

	SetLocalPose(Vector3(), Quat());

	ret = true;
Exit0:
	return ret;
}
PxRigidDynamic* CloneDynamic(PxPhysics& physicsSDK, 
							   const PxTransform& transform,
							   const PxRigidDynamic& from,
							   NxMirrorScene::MirrorFilter &mirrorFilter)
{
	PxRigidDynamic* to = physicsSDK.createRigidDynamic(transform);
	if(!to)
		return NULL;

	if ( !copyStaticProperties(*to, from, mirrorFilter) )
	{
		to->release();
		to = NULL;
		return NULL;
	}

	to->setRigidDynamicFlags(from.getRigidDynamicFlags());

	to->setMass(from.getMass());
	to->setMassSpaceInertiaTensor(from.getMassSpaceInertiaTensor());
	to->setCMassLocalPose(from.getCMassLocalPose());

	if ( !(to->getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC) )
	{
		to->setLinearVelocity(from.getLinearVelocity());
		to->setAngularVelocity(from.getAngularVelocity());
	}

	to->setLinearDamping(from.getAngularDamping());
	to->setAngularDamping(from.getAngularDamping());

	to->setMaxAngularVelocity(from.getMaxAngularVelocity());

	PxU32 posIters, velIters;
	from.getSolverIterationCounts(posIters, velIters);
	to->setSolverIterationCounts(posIters, velIters);

	to->setSleepThreshold(from.getSleepThreshold());

	to->setContactReportThreshold(from.getContactReportThreshold());

	return to;
}
Example #11
0
void initPhysX() {
	foundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback);
	physics = PxCreatePhysics(PX_PHYSICS_VERSION, *foundation, PxTolerancesScale());

	PxInitExtensions(*physics);
	
	PxSceneDesc sceneDesc(physics->getTolerancesScale());
	sceneDesc.gravity = PxVec3(0.0f,-9.8f,0.0f);

	if(!sceneDesc.cpuDispatcher)
	{
		PxDefaultCpuDispatcher* mCpuDispatcher = PxDefaultCpuDispatcherCreate(1);
		sceneDesc.cpuDispatcher = mCpuDispatcher;
	}

	if(!sceneDesc.filterShader)
		sceneDesc.filterShader  = gDefaultFilterShader;
	
	dxScene = physics->createScene(sceneDesc);

	//get objects from sceene graph and create the physics bodys.
	PxMaterial* mMaterial = physics->createMaterial(0.5,0.5,0.5);

	PxReal d = 0.0f;
	PxTransform pose = PxTransform(PxVec3(0.0f, 0, 0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f)));

	PxRigidStatic* plane = physics->createRigidStatic(pose);
	dxScene->addActor(*plane);

	PxReal density = 1.0f;
	PxTransform transform(PxVec3(0.0f, 10.0f, 0.0f), PxQuat::createIdentity());
	PxVec3 dimensions(0.5,0.5,0.5);
	PxBoxGeometry geometry(dimensions);
	
	PxRigidDynamic *actor = PxCreateDynamic(*physics, transform, geometry, *mMaterial, density);
	actor->setAngularDamping(0.75);
	actor->setLinearVelocity(PxVec3(0,0,0)); 
	dxScene->addActor(*actor);

	box = actor;
}
Example #12
0
void SampleSubmarine::explode(PxRigidActor* actor, const PxVec3& explosionPos, const PxReal explosionStrength)
{
	size_t numRenderActors = mRenderActors.size();
	for(PxU32 i = 0; i < numRenderActors; i++)
	{
		if(&(mRenderActors[i]->getPhysicsShape()->getActor()) == actor)
		{
			PxShape* shape = mRenderActors[i]->getPhysicsShape();
			PxTransform pose = PxShapeExt::getGlobalPose(*shape);
			
			PxGeometryHolder geom = shape->getGeometry();

			// create new actor from shape (to split compound)
			PxRigidDynamic* newActor = mPhysics->createRigidDynamic(pose);
			if(!newActor) fatalError("createRigidDynamic failed!");

			PxShape* newShape = newActor->createShape(geom.any(), *mMaterial);
			newShape->userData = mRenderActors[i];
			mRenderActors[i]->setPhysicsShape(newShape);
			
			newActor->setActorFlag(PxActorFlag::eVISUALIZATION, true);
			newActor->setLinearDamping(10.5f);
			newActor->setAngularDamping(0.5f);
			PxRigidBodyExt::updateMassAndInertia(*newActor, 1.0f);
			mScene->addActor(*newActor);
			mPhysicsActors.push_back(newActor);
			
			PxVec3 explosion = pose.p - explosionPos;
			PxReal len = explosion.normalize();
			explosion *= (explosionStrength / len);
			newActor->setLinearVelocity(explosion);
			newActor->setAngularVelocity(PxVec3(1,2,3));

		}
	}

	removeActor(actor);
}
Example #13
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;
	}
}
Example #14
0
// Creates an physics entity from an entity info structure and a starting transform
void PhysicsEngine::createEntity(PhysicsEntity* entity, PhysicsEntityInfo* info, PxTransform transform)
{
	transform.p.y += info->yPosOffset;
	// Set static/dynamic info for actor depending on its type
	PxRigidActor* actor;
	if (info->type == PhysicsType::DYNAMIC) 
	{
		DynamicInfo* dInfo = info->dynamicInfo;
		PxRigidDynamic* dynamicActor = physics->createRigidDynamic(transform);
		dynamicActor->setLinearDamping(dInfo->linearDamping);
		dynamicActor->setAngularDamping(dInfo->angularDamping);
		dynamicActor->setMaxAngularVelocity(dInfo->maxAngularVelocity);

		actor = dynamicActor;
	}
	else if (info->type == PhysicsType::STATIC)
	{
		PxRigidStatic* staticActor = physics->createRigidStatic(transform);
		actor = staticActor;
	}

	// All shapes in actor
	for (auto sInfo : info->shapeInfo)
	{
		// Create material and geometry for shape and add it to actor
		PxGeometry* geometry;
		PxMaterial* material;
		if (sInfo->geometry == Geometry::SPHERE)
		{
			SphereInfo* sphInfo = (SphereInfo*)sInfo;
			geometry = new PxSphereGeometry(sphInfo->radius);
		}
		else if (sInfo->geometry == Geometry::BOX)
		{
			BoxInfo* boxInfo = (BoxInfo*)sInfo;		
			geometry = new PxBoxGeometry(boxInfo->halfX, boxInfo->halfY, boxInfo->halfZ);
		}
		else if (sInfo->geometry == Geometry::CAPSULE)
		{
			CapsuleInfo* capInfo = (CapsuleInfo*)sInfo;
			geometry = new PxCapsuleGeometry(capInfo->radius, capInfo->halfHeight);
		}
		else if (sInfo->geometry == Geometry::CONVEX_MESH)
		{
			ConvexMeshInfo* cmInfo = (ConvexMeshInfo*)sInfo;

			PxConvexMesh* mesh = helper->createConvexMesh(cmInfo->verts.data(), cmInfo->verts.size());
			geometry = new PxConvexMeshGeometry(mesh);
		}
		// Not working until index drawing is set up
		else if (sInfo->geometry == Geometry::TRIANGLE_MESH)
		{
			TriangleMeshInfo* tmInfo = (TriangleMeshInfo*)sInfo;

			PxTriangleMesh* mesh = helper->createTriangleMesh(tmInfo->verts.data(), tmInfo->verts.size(), tmInfo->faces.data(), tmInfo->faces.size()/3);
			geometry = new PxTriangleMeshGeometry(mesh);
		}
		material = (sInfo->isDrivable) ? drivingSurfaces[0] : physics->createMaterial(sInfo->dynamicFriction, sInfo->staticFriction, sInfo->restitution);
		PxShape* shape = actor->createShape(*geometry, *material); // TODO support shape flags
		shape->setLocalPose(sInfo->transform);

		material->release();
		delete geometry;

		// Set up querry filter data for shape
		PxFilterData qryFilterData;
		qryFilterData.word3 = (sInfo->isDrivable) ? (PxU32)Surface::DRIVABLE : (PxU32)Surface::UNDRIVABLE;
		shape->setQueryFilterData(qryFilterData);

		// Set up simulation filter data for shape
		PxFilterData simFilterData;
		simFilterData.word0 = (PxU32)sInfo->filterFlag0;
		simFilterData.word1 = (PxU32)sInfo->filterFlag1;
		simFilterData.word2 = (PxU32)sInfo->filterFlag2;
		simFilterData.word3 = (PxU32)sInfo->filterFlag3;
		shape->setSimulationFilterData(simFilterData);

		if (info->type == PhysicsType::DYNAMIC) 
		{
			DynamicInfo* dInfo = info->dynamicInfo;
			PxRigidBodyExt::updateMassAndInertia(*(PxRigidBody*)actor, dInfo->density, &dInfo->cmOffset);

			PxRigidBody* body = (PxRigidBody*)actor;
		}
	}

	// Add actor to scene, set actor for entity, and set user data for actor. Creates one to one between entities and phyX
	scene->addActor(*actor);
	entity->setActor(actor);
	actor->userData = entity;
}
Example #15
0
Seamine* SampleSubmarine::createSeamine(const PxVec3& inPosition, PxReal inHeight)
{
	static const PxReal chainLinkLength = 2.0f;
	static const PxReal linkSpacing = 0.05f;
	static const PxReal mineHeadRadius = 1.5f;
	const PxVec3 mineStartPos = inPosition;
	static const PxVec3 linkOffset = PxVec3(0, chainLinkLength + linkSpacing, 0);
	static const PxVec3 halfLinkOffset = linkOffset * 0.5f;
	static const PxVec3 linkDim = PxVec3(chainLinkLength*0.125f, chainLinkLength*0.5f, chainLinkLength*0.125f);
	PxU32 numLinks = PxU32((inHeight - 2.0f*mineHeadRadius) / (chainLinkLength + linkSpacing));
	numLinks = numLinks ? numLinks : 1;

	Seamine* seamine = SAMPLE_NEW(Seamine);
	mSeamines.push_back(seamine);

	// create links from floor
	PxVec3 linkPos = mineStartPos + halfLinkOffset;
	PxRigidActor* prevActor = NULL;
	for(PxU32 i = 0; i < numLinks; i++)
	{
		// create the link actor
		PxRigidDynamic* link = createBox(linkPos, linkDim, NULL, mSeamineMaterial, 1.0f)->is<PxRigidDynamic>();
		if(!link) fatalError("createBox failed!");
		// back reference to mineHead
		link->userData = seamine;
		seamine->mLinks.push_back(link);

		setupFiltering(link, FilterGroup::eMINE_LINK, FilterGroup::eSUBMARINE);
		link->setLinearDamping(0.5f);
		link->setAngularDamping(0.5f);
		link->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);

		// create distance joint between link and prevActor
		PxTransform linkFrameA = prevActor ? PxTransform(halfLinkOffset, PxQuat::createIdentity()) : PxTransform(mineStartPos, PxQuat::createIdentity());
		PxTransform linkFrameB = PxTransform(-halfLinkOffset, PxQuat::createIdentity());
		PxDistanceJoint *joint = PxDistanceJointCreate(getPhysics(), prevActor, linkFrameA, link, linkFrameB);
		if(!joint) fatalError("PxDistanceJointCreate failed!");

		// set min & max distance to 0
		joint->setMaxDistance(0.0f);
		joint->setMinDistance(0.0f);
		// setup damping & spring
		joint->setDamping(1.0f * link->getMass());
		joint->setSpring(400.0f * link->getMass());
		joint->setDistanceJointFlags(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED | PxDistanceJointFlag::eMIN_DISTANCE_ENABLED | PxDistanceJointFlag::eSPRING_ENABLED);

		// add to joints array for cleanup
		mJoints.push_back(joint);

		prevActor = link;
		linkPos += linkOffset;
	}

	// create mine head
	linkPos.y += mineHeadRadius - (chainLinkLength*0.5f);
	PxRigidDynamic* mineHead = createSphere(linkPos, mineHeadRadius, NULL, mSeamineMaterial, 1.0f)->is<PxRigidDynamic>();
	mineHead->userData = seamine;
	seamine->mMineHead = mineHead;
	
	mineHead->setLinearDamping(0.5f);
	mineHead->setAngularDamping(0.5f);
	mineHead->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);
	
	// setup filtering to trigger contact reports when submarine touches the minehead
	setupFiltering(mineHead, FilterGroup::eMINE_HEAD, FilterGroup::eSUBMARINE);


	// create distance joint between mine head and prevActor
	PxTransform linkFrameA = PxTransform(halfLinkOffset, PxQuat::createIdentity());
	PxTransform linkFrameB = PxTransform(PxVec3(0, -mineHeadRadius - linkSpacing*0.5f, 0), PxQuat::createIdentity());
	PxDistanceJoint *joint = PxDistanceJointCreate(getPhysics(), prevActor, linkFrameA, mineHead, linkFrameB);
	if(!joint) fatalError("PxDistanceJointCreate failed!");

	// set min & max distance to 0
	joint->setMaxDistance(0.0f);
	joint->setMinDistance(0.0f);
	// setup damping & spring
	joint->setDamping(1.0f * mineHead->getMass());
	joint->setSpring(400.0f * mineHead->getMass());
	joint->setDistanceJointFlags(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED | PxDistanceJointFlag::eMIN_DISTANCE_ENABLED | PxDistanceJointFlag::eSPRING_ENABLED);

	// add to joints array for cleanup
	mJoints.push_back(joint);

	return seamine;
}
Example #16
0
		/**
		 * Method is used to add new dynamic actor to physics scene.
		 * @param	entity is pointer to scene entity which will be added to physics simulation.
		 * @param	type is enumeration of shape type.
		 * @param	filterGroup is actor own id.
		 * @param	filterMask is mask to filter pairs that trigger a contact callback.
		 */
		void PhysicsManager::addDynamicActor(SceneEntity* entity, ShapeType type, PxU32 filterGroup, PxU32 filterMask)
		{
			PxRigidDynamic* actor = nullptr;
			
			PxVec3 position = PxVec3(entity->entityState.position[0],entity->entityState.position[1],entity->entityState.position[2]);	
			PxQuat orientation = PxQuat(entity->entityState.orientation[0],entity->entityState.orientation[1],entity->entityState.orientation[2],entity->entityState.orientation[3]);
			PxReal density = 1.0f;
			PxTransform transformation = PxTransform(position,orientation); 

			if(type == BOX)
			{
				float x = (entity->entityGeometry.geometryBox->max.x() - entity->entityGeometry.geometryBox->min.x())*entity->entityState.scale.x()*0.5f;
				float y = (entity->entityGeometry.geometryBox->max.y() - entity->entityGeometry.geometryBox->min.y())*entity->entityState.scale.y()*0.5f;
				float z = (entity->entityGeometry.geometryBox->max.z() - entity->entityGeometry.geometryBox->min.z())*entity->entityState.scale.z()*0.5f;
				
				PxVec3 dimensions(x,y,z);
				actor = PxCreateDynamic(*physicsSDK,transformation,PxBoxGeometry(dimensions),*materials[0].second,density);
				PxRigidBodyExt::updateMassAndInertia(*actor, density);
			}
			else if(type == SPHERE)
			{
				float radius = entity->entityGeometry.geometrySphere->sphereRadius;
				actor = PxCreateDynamic(*physicsSDK,transformation,PxSphereGeometry(radius),*materials[0].second,density);
			}
			else if(type == CAPSULE)
			{
				float radius = entity->entityGeometry.geometrySphere->sphereRadius;
				actor = PxCreateDynamic(*physicsSDK,transformation,PxCapsuleGeometry(radius/2, radius),*materials[0].second,density);
			}
			else if(type == CONVEX)
			{
				/*int vertsCount = entity->entityGeometry.geometryMesh->getVerticesAmount();
				AyumiUtils::Vertex<>* verts = entity->entityGeometry.geometryMesh->getVertices();
				PxVec3* convexVerts = new PxVec3[vertsCount];

				for(int i = 0; i < vertsCount; ++i)
					convexVerts[i] = PxVec3(verts[i].x,verts[i].y,verts[i].z);

				PxConvexMeshDesc convexDesc;
				convexDesc.points.count = entity->entityGeometry.geometryMesh->getVerticesAmount();
				convexDesc.points.stride = sizeof(PxVec3);
				convexDesc.points.data = convexVerts;
				convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;

				MemoryWriteBuffer buf;
				if(cooking->cookConvexMesh(convexDesc, buf))
				{
					PxConvexMesh* convexMesh = physicsSDK->createConvexMesh(MemoryReadBuffer(buf.data));
					actor = PxCreateDynamic(*physicsSDK,transformation,PxConvexMeshGeometry(convexMesh,PxMeshScale()),*materials[0].second,density);
				}
				else
				{
					Logger::getInstance()->saveLog(Log<string>("Convex Mesh creation error occurred!"));
					return;
				}*/
				//delete[] convexVerts;
			}
			else
			{
				Logger::getInstance()->saveLog(Log<string>("Dynamic Actor shape creation error occurred!"));
				return;
			}

			if(!actor)
				Logger::getInstance()->saveLog(Log<string>("Static Actor creation error occurred!"));
			
			PxRigidBodyExt::updateMassAndInertia(*actor, density);
			actor->setAngularDamping(0.75);
			actor->setLinearVelocity(PxVec3(0,0,0));
			actor->setName(entity->entityName.c_str());
			setupFiltering(actor,filterGroup,filterMask);
			scene->addActor(*actor);
			
			DynamicActor* d = new DynamicActor();
			d->entityLogic = entity;
			d->entityPhysics = actor;
			d->shapesAmount = actor->getNbShapes();
			d->shapes = new PxShape*[d->shapesAmount];
			dynamicActors.push_back(d);
		}