/** @brief @date 2013-12-03 */ void CEvc::pickup() { PxU32 width; PxU32 height; mApplication.getPlatform()->getWindowSize(width, height); mPicking->moveCursor(width/2,height/2); mPicking->lazyPick(); PxActor *actor = mPicking->letGo(); //PxRigidDynamic *rigidActor = static_cast<PxRigidDynamic*>(actor->is<PxRigidDynamic>()); PxRigidDynamic *rigidActor = (PxRigidDynamic*)actor; if (rigidActor) { const PxVec3 pos = getCamera().getPos() + (getCamera().getViewDir()*10.f); const PxVec3 vel = getCamera().getViewDir() * 20.f; rigidActor->addForce( getCamera().getViewDir()*g_pDbgConfig->force ); PxU32 nbShapes = rigidActor->getNbShapes(); if(!nbShapes) return; PxShape** shapes = (PxShape**)SAMPLE_ALLOC(sizeof(PxShape*)*nbShapes); PxU32 nb = rigidActor->getShapes(shapes, nbShapes); PX_ASSERT(nb==nbShapes); for(PxU32 i=0;i<nbShapes;i++) { RenderBaseActor *renderActor = getRenderActor(rigidActor, shapes[i]); if (renderActor) { renderActor->setRenderMaterial(mManagedMaterials[ 1]); } } SAMPLE_FREE(shapes); } }
void SetupShapesUserData(const VehicleDescriptor &vd) { PxRigidDynamic *a = vd.vehicle->mActor; if (!a) return; PxU32 numShapes = a->getNbShapes(); r3d_assert(numShapes <= vd.numWheels + vd.numHullParts); for (PxU32 i = 0; i < numShapes; ++i) { PxShape *s = 0; a->getShapes(&s, 1, i); if (!s) continue; if (i < vd.numWheels) { s->userData = reinterpret_cast<void*>(vd.wheelBonesRemapIndices[i]); } else { s->userData = reinterpret_cast<void*>(vd.hullBonesRemapIndices[i - vd.numWheels]); } } }
static PxRigidDynamic* canDoCCD(PxShape* shape) { PxActor& actor = shape->getActor(); PxRigidDynamic* dyna = actor.is<PxRigidDynamic>(); if(!dyna) return NULL; // PT: no need to do it for statics const PxU32 nbShapes = dyna->getNbShapes(); if(nbShapes!=1) return NULL; // PT: only works with simple actors for now if(dyna->getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC) return NULL; // PT: no need to do it for kinematics return dyna; }
void FBXActor::createCollisionShapes(PhysicsDemoScene *a_app) { float density = 300; //pole PxBoxGeometry box = PxBoxGeometry(0.1f,4,0.1f); PxTransform transform(*((PxMat44*)(&m_world))); //cast from glm to PhysX matrices PxRigidDynamic* dynamicActor = PxCreateDynamic(*a_app->g_Physics, transform, box, *a_app->g_PhysicsMaterial, density); dynamicActor->userData = this; //set the user data to point at this FBXActor class //offset int nShapes = dynamicActor->getNbShapes(); PxShape* shapes; dynamicActor->getShapes(&shapes, nShapes); PxTransform relativePose = PxTransform(PxVec3(0.0f,4.0f,0.0f)); shapes->setLocalPose(relativePose); //head box = PxBoxGeometry(0.8f,0.5f,0.3f); relativePose = PxTransform(PxVec3(0.0f,2.0f,0.0f)); PxShape* shape = dynamicActor->createShape(box, *a_app->g_PhysicsMaterial); if (shape) { shape->setLocalPose(relativePose); } PxRigidBodyExt::updateMassAndInertia(*dynamicActor, (PxReal)density); //add to scene a_app->g_PhysicsScene->addActor(*dynamicActor); a_app->g_PhysXActors.push_back(dynamicActor); }
PxController* ControlledActor::init(const ControlledActorDesc& desc, PxControllerManager* manager) { const float radius = desc.mRadius; float height = desc.mHeight; float crouchHeight = desc.mCrouchHeight; PxControllerDesc* cDesc; PxBoxControllerDesc boxDesc; PxCapsuleControllerDesc capsuleDesc; if(desc.mType==PxControllerShapeType::eBOX) { height *= 0.5f; height += radius; crouchHeight *= 0.5f; crouchHeight += radius; boxDesc.halfHeight = height; boxDesc.halfSideExtent = radius; boxDesc.halfForwardExtent = radius; cDesc = &boxDesc; } else { PX_ASSERT(desc.mType==PxControllerShapeType::eCAPSULE); capsuleDesc.height = height; capsuleDesc.radius = radius; capsuleDesc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED; cDesc = &capsuleDesc; } cDesc->density = desc.mProxyDensity; cDesc->scaleCoeff = desc.mProxyScale; cDesc->material = &mOwner.getDefaultMaterial(); cDesc->position = desc.mPosition; cDesc->slopeLimit = desc.mSlopeLimit; cDesc->contactOffset = desc.mContactOffset; cDesc->stepOffset = desc.mStepOffset; cDesc->invisibleWallHeight = desc.mInvisibleWallHeight; cDesc->maxJumpHeight = desc.mMaxJumpHeight; // cDesc->nonWalkableMode = PxControllerNonWalkableMode::ePREVENT_CLIMBING_AND_FORCE_SLIDING; cDesc->reportCallback = desc.mReportCallback; cDesc->behaviorCallback = desc.mBehaviorCallback; cDesc->volumeGrowth = desc.mVolumeGrowth; mType = desc.mType; mInitialPosition = desc.mPosition; mStandingSize = height; mCrouchingSize = crouchHeight; mControllerRadius = radius; PxController* ctrl = static_cast<PxBoxController*>(manager->createController(*cDesc)); PX_ASSERT(ctrl); // remove controller shape from scene query for standup overlap test PxRigidDynamic* actor = ctrl->getActor(); if(actor) { if(actor->getNbShapes()) { PxShape* ctrlShape; actor->getShapes(&ctrlShape,1); ctrlShape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, false); Renderer* renderer = mOwner.getRenderer(); if(desc.mType==PxControllerShapeType::eBOX) { const PxVec3 standingExtents(radius, height, radius); const PxVec3 crouchingExtents(radius, crouchHeight, radius); mRenderActorStanding = SAMPLE_NEW(RenderBoxActor)(*renderer, standingExtents); mRenderActorCrouching = SAMPLE_NEW(RenderBoxActor)(*renderer, crouchingExtents); } else if(desc.mType==PxControllerShapeType::eCAPSULE) { mRenderActorStanding = SAMPLE_NEW(RenderCapsuleActor)(*renderer, radius, height*0.5f); mRenderActorCrouching = SAMPLE_NEW(RenderCapsuleActor)(*renderer, radius, crouchHeight*0.5f); } } } mController = ctrl; return ctrl; }
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; } }
PxCapsuleController* SampleCustomGravity::createCharacter(const PxExtendedVec3& position) #endif { const float height = 2.0f; // const float height = 1e-6f; // PT: TODO: make it work with 0? #ifdef USE_BOX_CONTROLLER PxBoxControllerDesc cDesc; cDesc.halfHeight = height; cDesc.halfSideExtent = mControllerRadius; cDesc.halfForwardExtent = mControllerRadius; #else PxCapsuleControllerDesc cDesc; cDesc.height = height; cDesc.radius = mControllerRadius; #endif cDesc.material = &getDefaultMaterial(); cDesc.position = position; cDesc.slopeLimit = SLOPE_LIMIT; cDesc.contactOffset = CONTACT_OFFSET; cDesc.stepOffset = STEP_OFFSET; cDesc.invisibleWallHeight = INVISIBLE_WALLS_HEIGHT; cDesc.maxJumpHeight = MAX_JUMP_HEIGHT; cDesc.callback = this; mControllerInitialPosition = cDesc.position; #ifdef USE_BOX_CONTROLLER PxBoxController* ctrl = static_cast<PxBoxController*>(mControllerManager->createController(getPhysics(), &getActiveScene(), cDesc)); #else PxCapsuleController* ctrl = static_cast<PxCapsuleController*>(mControllerManager->createController(getPhysics(), &getActiveScene(), cDesc)); #endif // remove controller shape from scene query for standup overlap test PxRigidDynamic* actor = ctrl->getActor(); if(actor) { if(actor->getNbShapes()) { PxShape* ctrlShape; actor->getShapes(&ctrlShape,1); ctrlShape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, false); #ifdef USE_BOX_CONTROLLER const PxVec3 standingExtents(mControllerRadius, height, mControllerRadius); mRenderActor = SAMPLE_NEW(RenderBoxActor)(*getRenderer(), standingExtents); #else mRenderActor = SAMPLE_NEW(RenderCapsuleActor)(*getRenderer(), mControllerRadius, height*0.5f); #endif if(mRenderActor) mRenderActors.push_back(mRenderActor); } else fatalError("character actor has no shape"); } else fatalError("character could not create actor"); // uncomment the next line to render the character //createRenderObjectsFromActor(ctrl->getActor()); return ctrl; }
/** * 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); }