137 lines
3.1 KiB
C++
137 lines
3.1 KiB
C++
// 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)
|
|
);
|
|
} |