Controller::Controller(const ControllerResource* cr, SceneGraph& sg, UnitId id, PxPhysics* physics, PxControllerManager* manager) : m_resource(cr) , m_scene_graph(sg) , _unit_id(id) , m_manager(manager) , m_controller(NULL) { TransformInstance ti = sg.get(id); const Vector3 pos = sg.world_position(ti); PxCapsuleControllerDesc desc; desc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED; desc.nonWalkableMode = PxCCTNonWalkableMode::eFORCE_SLIDING; desc.radius = cr->radius; desc.height = cr->height; desc.slopeLimit = cos(cr->slope_limit); desc.stepOffset = cr->step_offset; desc.contactOffset = cr->contact_offset; desc.upDirection = PxVec3(0.0, 1.0, 0.0); desc.material = physics->createMaterial(0.5f, 0.5f, 0.5f); desc.position = PxExtendedVec3(pos.x, pos.y, pos.z); desc.reportCallback = &m_callback; CE_ASSERT(desc.isValid(), "Capsule is not valid"); m_controller = manager->createController(desc); CE_ASSERT(m_controller, "Failed to create controller"); }
CharacterPhysicsComponent::CharacterPhysicsComponent( World* world, const Vector3& position, const Real height, const Real radius ): mPosition( position ), mController( nullptr ), mMaterial( nullptr ), mWorld( world ), mHeight( height ), mRadius( radius ) { mScene = mWorld->getPhysics()->getScene(); mMaterial = mScene->getPhysics().createMaterial( 0.5f, 0.5f, 0.1f ); PxCapsuleControllerDesc descriptor; descriptor.setToDefault(); descriptor.position = Math::ogreVec3ToPxExt( mPosition ); descriptor.height = mHeight; descriptor.radius = mRadius; descriptor.contactOffset = 0.0125f; descriptor.stepOffset = 0.125f; descriptor.slopeLimit = 0.0f; descriptor.climbingMode = PxCapsuleClimbingMode::eEASY; descriptor.density = 10.0f; descriptor.behaviorCallback = nullptr; descriptor.reportCallback = nullptr; descriptor.material = mMaterial; descriptor.userData = nullptr; if ( !descriptor.isValid() ) ENGINE_EXCEPT( "Invalid character controller descriptor" ); mController = static_cast<PxCapsuleController*>( mWorld->getPhysics()->getControllerManager()->createController( descriptor ) ); if ( !mController ) ENGINE_EXCEPT( "Could not create character controller" ); }
bool CharacterController::Init(PxControllerManager* manager, float height, float radius, const Vector3& offset) { bool ret = false; mOffset = offset; const Vector3& pos = mOwner.GetTransform().position + mOffset; PxCapsuleControllerDesc desc; desc.height = height; desc.radius = radius; desc.position = PxExtendedVec3(pos.x, pos.y, pos.z); desc.material = gPhysics->createMaterial(0.5f, 0.5f, 0.1f); CHECK(desc.isValid()); mController = manager->createController(desc); CHECK(mController); mController->getActor()->userData = &mOwner; mGizmo = new Gizmo(mOwner.GetTransform()); mGizmo->SetMesh(ShapeMesh::CreateCapsule(height * 0.5f, radius)); mOwner.GetScene().AddGizmo(mGizmo); mGizmo->GetLocal().position = mOffset; mGizmo->SetColor(Color(0, 1, 0, 1)); ret = true; Exit0: return ret; }
/// Let's check if actors are okay void PhysicsSystemPhysX::syncActors() { for (std::size_t i = 0; i < mWorld->actors.size(); ++i) { Actor* actor = mWorld->actors[i]; for (std::size_t j = 0; j < actor->components.size(); ++j) { ACharacterComponent* chr = dynamic_cast<ACharacterComponent*>(actor->components[j]); if (chr) { // We have a character controller in this actor, needs to be handled if (chr->userData) { PxController* cc = (PxController*)chr->userData; chr->t.position.x = cc->getPosition().x; chr->t.position.y = cc->getPosition().y; chr->t.position.z = cc->getPosition().z; //Log("Updated actor"); } else { PxMaterial* mat = mPhysics->createMaterial(0.1, 0.1, 0.1); PxCapsuleControllerDesc* desc = new PxCapsuleControllerDesc; desc->height = 5; desc->radius = 5; desc->position = PxExtendedVec3(0, 0, 0); desc->material = mat; Log("BOX VALID: %d", desc->isValid()); PxController* c = manager->createController(*desc); if (!c) { Log("Failed to instance a controller"); } if (c) { chr->userData = c; chr->moving.connect(sigc::mem_fun(this, &PhysicsSystemPhysX::TestCharacterMove)); Log("PhysX validated an actor's character controller"); } } } } } }