// Copyright (c) 2024 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #include "Collider.hpp" #include "assert/assert.hpp" #include "game/Game.hpp" using namespace Dawn; using namespace JPH; using namespace JPH::literals; EMotionType Collider::getMotionType(const ColliderType colliderType) { EMotionType motionType; switch(colliderType) { case ColliderType::DYNAMIC: return EMotionType::Dynamic; break; case ColliderType::STATIC: return EMotionType::Static; break; case ColliderType::KINEMATIC: return EMotionType::Kinematic; break; } assertUnreachable("Invalid ColliderType"); return EMotionType::Kinematic; } // void Collider::onInit() { assertNull(this->body, "Body is not NULL?"); auto settings = this->getShapeSettings(); auto shapeResult = settings->Create(); auto shape = shapeResult.Get(); auto pos = getItem()->getLocalPosition(); BodyCreationSettings bodySettings( shape, RVec3(pos.x, pos.y, pos.z), Quat::sIdentity(), Collider::getMotionType(this->colliderType), layer ); this->body = getBodyInterface().CreateBody(bodySettings); assertNotNull(this->body, "Body failed to create?"); this->bodyId = this->body->GetID(); getBodyInterface().AddBody(this->bodyId, EActivation::Activate); } void Collider::onDispose() { getBodyInterface().RemoveBody(this->bodyId); getBodyInterface().DestroyBody(this->bodyId); } void Collider::notifyShapeChanged() { if(!this->isColliderReady()) return; auto settings = this->getShapeSettings(); auto shapeResult = settings->Create(); auto shape = shapeResult.Get(); getBodyInterface().SetShape( this->bodyId, shape, // TODO: I may not always need to re-activate the body here. true, EActivation::Activate ); } bool_t Collider::isColliderReady() { return this->body != nullptr; } BodyInterface & Collider::getBodyInterface() { return getGame()->physicsManager->getBodyInterface(); } ColliderType Collider::getColliderType() { return colliderType; } BodyID Collider::getBodyId() { return bodyId; } glm::vec3 Collider::getVelocity() { if(!this->isColliderReady()) return glm::vec3(0.0f, 0.0f, 0.0f); auto vel = getBodyInterface().GetLinearVelocity(this->bodyId); return glm::vec3(vel.GetX(), vel.GetY(), vel.GetZ()); } void Collider::setVelocity(const glm::vec3 velocity) { if(!this->isColliderReady()) { assertUnreachable("Collider is not ready."); } getBodyInterface().SetLinearVelocity( this->bodyId, RVec3(velocity.x, velocity.y, velocity.z) ); } void Collider::setColliderType(const ColliderType type) { this->colliderType = type; if(!this->isColliderReady()) return; getBodyInterface().SetMotionType( this->bodyId, Collider::getMotionType(type), EActivation::Activate// TODO: Should be false on kinematics ); } void Collider::addForce( const glm::vec3 force, const glm::vec3 inPoint ) { if(!this->isColliderReady()) assertUnreachable("Collider is not ready."); getBodyInterface().AddForce( this->bodyId, RVec3(force.x, force.y, force.z), RVec3(0, 0, 0) ); }