//------------------------------------------------------------------------------------------------- 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); }
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); }
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); } }