Пример #1
0
//-------------------------------------------------------------------------------------------------
bool sdPhysicsSystem::CreateEmptyScene(uint uiSize)
{
	NIASSERT(!m_pkScene);
	NIASSERT(!m_pkControllerManager);

	float fSize = (float)uiSize;
	float fWalkHeight = 4000.f;
	NxBounds3 nxBound;
	nxBound.setCenterExtents(NxVec3(fSize * 0.5f, fSize * 0.5f, 0.f), NxVec3(fSize * 0.5f, fSize * 0.5f, fWalkHeight *0.5f));

	NxSceneDesc nxSceneDesc;
	nxSceneDesc.gravity = NxVec3(0.f, 0.f, -9.8f);
	nxSceneDesc.simType = NX_SIMULATION_SW;
	nxSceneDesc.maxBounds = &nxBound;
	nxSceneDesc.upAxis = 2;							///< Z up
	nxSceneDesc.bpType = NX_BP_TYPE_SAP_MULTI;
	nxSceneDesc.nbGridCellsX = 8u;
	nxSceneDesc.nbGridCellsY = 8u;
	nxSceneDesc.subdivisionLevel = 5;

	m_pkScene = m_pkPhysicsSDK->createScene(nxSceneDesc);
	NIASSERT(m_pkScene);

	m_pkControllerManager = NxCreateControllerManager(m_pkAllocator);
	NIASSERT(m_pkControllerManager);

	return true;
}
void CCTDebugData::addAABB(const NxExtendedBounds3& bounds, NxU32 color)
{
	NxExtendedVec3 center;
	NxVec3 extents;
	bounds.getCenter(center);
	bounds.getExtents(extents);

	NxBounds3 tmp;
	tmp.setCenterExtents(NxVec3((float)center.x, (float)center.y, (float)center.z), extents);

	addAABB(tmp, color, false);
}
Пример #3
0
static void CreateCube(const NxVec3& pos, const NxVec3 * vel = 0)
	{
	// Avoid creating one compound within another
	NxBounds3 bounds;
	bounds.setCenterExtents(pos, NxVec3(10.0f, 10.0f, 10.0f));
	if(gScene->checkOverlapAABB(bounds))
		return;

	// Create cube made up of 6 individual boxes as its faces, with each box having a different material
	NxActorDesc actorDesc;
	NxBodyDesc bodyDesc;
	bodyDesc.linearVelocity.set(0,5,0);
	if (vel)
		bodyDesc.linearVelocity += *vel;

	bodyDesc.angularVelocity.set(NxMath::rand(0.0f,10.0f),NxMath::rand(0.0f,10.0f),NxMath::rand(0.0f,10.0f));	//throw up the ball with a random initial angular vel as if to roll dice.
	
	NxBoxShapeDesc boxDesc[6];
	boxDesc[0].dimensions.set(4,4,1);
	boxDesc[0].localPose.t.set(0,0,4);
	boxDesc[0].materialIndex	= defaultMaterialIndex;
	actorDesc.shapes.pushBack(&boxDesc[0]);
	boxDesc[1].dimensions.set(4,4,1);
	boxDesc[1].localPose.t.set(0,0,-4);
	boxDesc[1].materialIndex	= somewhatBouncyMaterialIndex;
	actorDesc.shapes.pushBack(&boxDesc[1]);
	boxDesc[2].dimensions.set(4,1,4);
	boxDesc[2].localPose.t.set(0,4,0);
	boxDesc[3].materialIndex	= veryBouncyMaterialIndex;
	actorDesc.shapes.pushBack(&boxDesc[2]);
	boxDesc[3].dimensions.set(4,1,4);
	boxDesc[3].localPose.t.set(0,-4,0);
	boxDesc[3].materialIndex	= defaultMaterialIndex;
	actorDesc.shapes.pushBack(&boxDesc[3]);
	boxDesc[4].dimensions.set(1,4,4);
	boxDesc[4].localPose.t.set(4,0,0);
	boxDesc[4].materialIndex	= frictionlessMaterialIndex;
	actorDesc.shapes.pushBack(&boxDesc[4]);
	boxDesc[5].dimensions.set(1,4,4);
	boxDesc[5].localPose.t.set(-4,0,0);
	boxDesc[5].materialIndex	= highFrictionMaterialIndex;
	actorDesc.shapes.pushBack(&boxDesc[5]);

	
	
	actorDesc.body			= &bodyDesc;
	actorDesc.density		= 10.0f;
	actorDesc.globalPose.t  = pos;
	gScene->createActor(actorDesc);
	}
Пример #4
0
static bool SweepBoxMesh(const SweepTest* sweep_test, const SweptVolume* volume, const TouchedGeom* geom, const NxExtendedVec3& center, const NxVec3& dir, SweptContact& impact)
{
	ASSERT(volume->GetType()==SWEPT_BOX);
	ASSERT(geom->mType==TOUCHED_MESH);
	const SweptBox* SB = static_cast<const SweptBox*>(volume);
	const TouchedMesh* TM = static_cast<const TouchedMesh*>(geom);

	NxU32 NbTris = TM->mNbTris;
	if(!NbTris)	return false;

	// Fetch triangle data for current mesh (the stream may contain triangles from multiple meshes)
	const NxTriangle* T		= &sweep_test->mWorldTriangles[TM->mIndexWorldTriangles];
	const NxTriangle* ET	= &sweep_test->mWorldEdgeNormals[TM->mIndexWorldEdgeNormals];
	const NxU32* EdgeFlags	= &sweep_test->mEdgeFlags[TM->mIndexEdgeFlags];

	NxBounds3 Box;
	Box.setCenterExtents(NxVec3(float(center.x - TM->mOffset.x), float(center.y - TM->mOffset.y), float(center.z - TM->mOffset.z)), SB->mExtents);	// Precompute

	// PT: this only really works when the CCT collides with a single mesh, but that's the most common case. When it doesn't, there's just no speedup but it still works.
	NxU32 CachedIndex = sweep_test->mCachedTriIndex[sweep_test->mCachedTriIndexIndex];
	if(CachedIndex>=NbTris)	CachedIndex=0;

	NxVec3 Hit, Normal;
	float t;
	NxU32 Index;
	if(gUtilLib->NxSweepBoxTriangles(NbTris, T, ET, EdgeFlags, Box, dir, impact.mDistance, Hit, Normal, t, Index, &CachedIndex))
	{
		if(t>=impact.mDistance)			return false;

		impact.mDistance	= t;
		impact.mWorldNormal	= Normal;
		impact.mWorldPos.x	= Hit.x + TM->mOffset.x;
		impact.mWorldPos.y	= Hit.y + TM->mOffset.y;
		impact.mWorldPos.z	= Hit.z + TM->mOffset.z;

		// Returned index is only between 0 and NbTris, i.e. it indexes the array of cached triangles, not the original mesh.
		assert(Index<NbTris);
		sweep_test->mCachedTriIndex[sweep_test->mCachedTriIndexIndex] = Index;

		// The CCT loop will use the index from the start of the cache...
		impact.mIndex = Index + TM->mIndexWorldTriangles;
		return true;
	}
	return false;
}
bool UpdateCharacterExtents(NxU32 index, bool& increase)
{
	if(index&1)
	{
		NxBoxController* c = static_cast<NxBoxController*>(gManager->getController(index));
		NxVec3 extents = c->getExtents();
		NxF32 inc = 1.0f;
		NxExtendedVec3 pos = GetCharacterPos(index);
		if (increase)
		{
			extents.y += inc;
			pos.y += inc;
		} 
		else 
		{ 
			extents.y -= inc;
			pos.y -= inc;
		}

		if(1)
		{
			NxBounds3 worldBounds;
			worldBounds.setCenterExtents(NxVec3(pos.x, pos.y, pos.z), extents);
			c->setCollision(false);	// Avoid checking overlap with ourself
			bool Status = gScene->checkOverlapAABB(worldBounds);
			c->setCollision(true);
			if(Status)
			{
				printf("Can not resize box!\n");
				return false;
			}
		}

		increase = !increase;	// Increase or decrease height each time we're called

		// WARNING: the SDK currently doesn't check for collisions when changing extents, so if you're close
		// to a wall you might end up penetrating it. In some cases you might also fall through the level.
		// A more advanced implementation will take care of that later.
		c->setPosition(pos);
		return c->setExtents(extents);
	}
	else
	{
		NxCapsuleController* c = static_cast<NxCapsuleController*>(gManager->getController(index));
		NxF32 height = c->getHeight();
		NxF32 radius = c->getRadius();
		NxF32 inc = 1.0f;
		NxExtendedVec3 pos = GetCharacterPos(index);
		if (increase)
		{
			height += inc;
			pos.y += inc*0.5f;
		} 
		else 
		{ 
			height -= inc;
			pos.y -= inc*0.5f;
		}

		if(1)
		{
			NxCapsule worldCapsule;
			worldCapsule.p0.x = worldCapsule.p1.x = pos.x;
			worldCapsule.p0.y = worldCapsule.p1.y = pos.y;
			worldCapsule.p0.z = worldCapsule.p1.z = pos.z;
			worldCapsule.p0.y -= height*0.5f;
			worldCapsule.p1.y += height*0.5f;
			worldCapsule.radius = radius;
			c->setCollision(false);	// Avoid checking overlap with ourself
			bool Status = gScene->checkOverlapCapsule(worldCapsule);
			c->setCollision(true);
			if(Status)
			{
				printf("Can not resize capsule!\n");
				return false;
			}
		}

		increase = !increase;	// Increase or decrease height each time we're called

		// WARNING: the SDK currently doesn't check for collisions when changing height, so if you're close
		// to a wall you might end up penetrating it. In some cases you might also fall through the level.
		// A more advanced implementation will take care of that later.
		c->setPosition(NxExtendedVec3(pos.x, pos.y, pos.z));
		return c->setHeight(height);
	}
}