| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "Components/BsCCharacterController.h"
- #include "Scene/BsSceneObject.h"
- #include "Physics/BsCollider.h"
- #include "RTTI/BsCCharacterControllerRTTI.h"
- using namespace std::placeholders;
- namespace bs
- {
- CCharacterController::CCharacterController(const HSceneObject& parent)
- : Component(parent)
- {
- setName("CharacterController");
- mNotifyFlags = TCF_Transform;
- }
- CharacterCollisionFlags CCharacterController::move(const Vector3& displacement)
- {
- CharacterCollisionFlags output;
- if (mInternal == nullptr)
- return output;
- output = mInternal->move(displacement);
- updatePositionFromController();
- return output;
- }
- Vector3 CCharacterController::getFootPosition() const
- {
- if (mInternal == nullptr)
- return Vector3::ZERO;
- return mInternal->getFootPosition();
- }
- void CCharacterController::setFootPosition(const Vector3& position)
- {
- if (mInternal == nullptr)
- return;
- mInternal->setFootPosition(position);
- updatePositionFromController();
- }
- void CCharacterController::setRadius(float radius)
- {
- mDesc.radius = radius;
- if (mInternal != nullptr)
- updateDimensions();
- }
- void CCharacterController::setHeight(float height)
- {
- mDesc.height = height;
- if (mInternal != nullptr)
- updateDimensions();
- }
- void CCharacterController::setUp(const Vector3& up)
- {
- mDesc.up = up;
- if (mInternal != nullptr)
- mInternal->setUp(up);
- }
- void CCharacterController::setClimbingMode(CharacterClimbingMode mode)
- {
- mDesc.climbingMode = mode;
- if (mInternal != nullptr)
- mInternal->setClimbingMode(mode);
- }
- void CCharacterController::setNonWalkableMode(CharacterNonWalkableMode mode)
- {
- mDesc.nonWalkableMode = mode;
- if (mInternal != nullptr)
- mInternal->setNonWalkableMode(mode);
- }
- void CCharacterController::setMinMoveDistance(float value)
- {
- mDesc.minMoveDistance = value;
- if (mInternal != nullptr)
- mInternal->setMinMoveDistance(value);
- }
- void CCharacterController::setContactOffset(float value)
- {
- mDesc.contactOffset = value;
- if (mInternal != nullptr)
- mInternal->setContactOffset(value);
- }
- void CCharacterController::setStepOffset(float value)
- {
- mDesc.stepOffset = value;
- if (mInternal != nullptr)
- mInternal->setStepOffset(value);
- }
- void CCharacterController::setSlopeLimit(Radian value)
- {
- mDesc.slopeLimit = value;
- if (mInternal != nullptr)
- mInternal->setSlopeLimit(value);
- }
- void CCharacterController::setLayer(UINT64 layer)
- {
- mLayer = layer;
- if (mInternal != nullptr)
- mInternal->setLayer(layer);
- }
- void CCharacterController::onInitialized()
- {
- }
- void CCharacterController::onDestroyed()
- {
- destroyInternal();
- }
- void CCharacterController::onDisabled()
- {
- destroyInternal();
- }
- void CCharacterController::onEnabled()
- {
- mDesc.position = SO()->getTransform().getPosition();
- mInternal = CharacterController::create(mDesc);
- mInternal->_setOwner(PhysicsOwnerType::Component, this);
- mInternal->onColliderHit.connect(std::bind(&CCharacterController::triggerOnColliderHit, this, _1));
- mInternal->onControllerHit.connect(std::bind(&CCharacterController::triggerOnControllerHit, this, _1));
- mInternal->setLayer(mLayer);
- updateDimensions();
- }
- void CCharacterController::onTransformChanged(TransformChangedFlags flags)
- {
- if (!SO()->getActive() || mInternal == nullptr)
- return;
- mInternal->setPosition(SO()->getTransform().getPosition());
- }
- void CCharacterController::updatePositionFromController()
- {
- mNotifyFlags = (TransformChangedFlags)0;
- SO()->setWorldPosition(mInternal->getPosition());
- mNotifyFlags = TCF_Transform;
- }
- void CCharacterController::updateDimensions()
- {
- Vector3 scale = SO()->getTransform().getScale();
- float height = mDesc.height * Math::abs(scale.y);
- float radius = mDesc.radius * Math::abs(std::max(scale.x, scale.z));
- mInternal->setHeight(height);
- mInternal->setRadius(radius);
- }
- void CCharacterController::destroyInternal()
- {
- // This should release the last reference and destroy the internal controller
- mInternal->_setOwner(PhysicsOwnerType::None, nullptr);
- mInternal = nullptr;
- }
- void CCharacterController::triggerOnColliderHit(const ControllerColliderCollision& value)
- {
- // Const-cast and modify is okay because we're the only object receiving this event
- ControllerColliderCollision& hit = const_cast<ControllerColliderCollision&>(value);
- hit.collider = mThisHandle;
- onColliderHit(hit);
- }
- void CCharacterController::triggerOnControllerHit(const ControllerControllerCollision& value)
- {
- // Const-cast and modify is okay because we're the only object receiving this event
- ControllerControllerCollision& hit = const_cast<ControllerControllerCollision&>(value);
- hit.controller = mThisHandle;
- onControllerHit(hit);
- }
- RTTITypeBase* CCharacterController::getRTTIStatic()
- {
- return CCharacterControllerRTTI::instance();
- }
- RTTITypeBase* CCharacterController::getRTTI() const
- {
- return CCharacterController::getRTTIStatic();
- }
- }
|