Skip to content

Commit

Permalink
add Collider prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
C6H5-NO2 committed Nov 11, 2019
1 parent af7ecaf commit 6828bda
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 135 deletions.
41 changes: 9 additions & 32 deletions Mx/Component/RigidBody/MxRigidBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,55 +7,33 @@
namespace Mix {
MX_IMPLEMENT_RTTI(RigidBody, Behaviour)

struct RigidBody::LifeTimeManager {
~LifeTimeManager() {
for(auto* shape : shapes)
delete shape;
}

void addShape(btCollisionShape* _shape) {
if(!_shape) return;
if(_shape->isCompound()) {
auto cs = static_cast<btCompoundShape*>(_shape);
for(auto idx = cs->getNumChildShapes() - 1; idx >= 0; --idx)
addShape(cs->getChildShape(idx));
}
shapes.insert(_shape);
}

//btAlignedObjectArray<btCollisionShape*> shapes;
std::set<btCollisionShape*> shapes;
};

RigidBody::LifeTimeManager RigidBody::ltm;

RigidBody::RigidBody() : mMass(.0),
mShape(nullptr),
mRigidBody(nullptr),
mFilter(false, 0, 0),
mWorld(nullptr) {}

RigidBody::RigidBody(const btScalar _mass, const Transform& _startTrans, btCollisionShape* _shape)
: RigidBody(Physics::RigidBodyConstructionInfo(_mass, Physics::mx_bt_cast(_startTrans), _shape)) {}
RigidBody::RigidBody(const btScalar _mass, const Transform& _startTrans, const std::shared_ptr<btCollisionShape>& _shape)
: RigidBody(Physics::RigidBodyConstructionInfo(_mass, Physics::mx_bt_cast(_startTrans), _shape.get())) {
mShape = _shape;
}

RigidBody::RigidBody(const Physics::RigidBodyConstructionInfo& _info) : mMass(_info.mass),
mShape(_info.shape),
mShape(nullptr),
mRigidBody(nullptr),
mFilter(false, 0, 0),
mWorld(nullptr) {
ltm.addShape(mShape);
mRigidBody = CreateBtRb(_info);
mRigidBody->setUserPointer(&mThisHandle);
}

RigidBody::RigidBody(const Physics::RigidBodyConstructionInfo& _info,
const int _group,
const int _mask) : mMass(_info.mass),
mShape(_info.shape),
mShape(nullptr),
mRigidBody(nullptr),
mFilter(true, _group, _mask),
mWorld(nullptr) {
ltm.addShape(mShape);
mRigidBody = CreateBtRb(_info);
mRigidBody->setUserPointer(&mThisHandle);
}
Expand Down Expand Up @@ -90,7 +68,7 @@ namespace Mix {
mass = 0;
else {
mass = mMass;
mShape->calculateLocalInertia(mass, inertia);
mRigidBody->getCollisionShape()->calculateLocalInertia(mass, inertia);
}
mRigidBody->setMassProps(mass, inertia);
mRigidBody->updateInertiaTensor();
Expand Down Expand Up @@ -187,14 +165,13 @@ namespace Mix {

void RigidBody::update() {
auto ms = static_cast<Physics::MotionState*>(mRigidBody->getMotionState());
if(ms->interpolation() == Physics::RigidbodyInterpolation::NONE)
if(ms->interpolation() == Physics::RigidbodyInterpolation::None)
return;
// todo: sync by Transform
Physics::bt_mx_cast(ms->interpolatedTransform(), mGameObject->transform());
}

void RigidBody::fixedUpdate() {
// Should be Physics::MotionState
// should be Physics::MotionState
Physics::bt_mx_cast(static_cast<Physics::MotionState*>(mRigidBody->getMotionState())
->getWorldTransform(), mGameObject->transform());
}
Expand Down
24 changes: 13 additions & 11 deletions Mx/Component/RigidBody/MxRigidBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Mix {
struct RigidBodyConstructionInfo;
}

/** Bug: RigidBody on a child GameObject whose parent has one might not be altered correctly. */
/** Bug: RigidBody on a child GameObject might not behave correctly. */
class RigidBody final : public Behaviour {
MX_DECLARE_RTTI;

Expand All @@ -32,8 +32,12 @@ namespace Mix {

/** @note Default ctor is for RTTI. DO NOT use this ctor. */
RigidBody();
/** @note Refer to Physics::RigidBodyConstructionInfo for param info. */
RigidBody(const btScalar _mass, const Transform& _startTrans, btCollisionShape* _shape);
/**
* @param _mass Mass. 0 creates a static rigid body i.e. btCollisionObject::CF_STATIC_OBJECT
* @param _startTrans Start transform.
* @param _shape Collision shape / Collider. DO NOT use std::make_shared on btCollisionShape in case of which align problems may occur.
*/
RigidBody(const btScalar _mass, const Transform& _startTrans, const std::shared_ptr<btCollisionShape>& _shape);
RigidBody(const Physics::RigidBodyConstructionInfo& _info);
/**
* @param _group Filter group.
Expand All @@ -48,7 +52,7 @@ namespace Mix {
const auto& get() const noexcept { return *mRigidBody; }

// ----- dirty codes -----
// todo: move to an utility class
// todo: use Event system

/**
* @brief Register call back functions of onTriggerEnter()
Expand Down Expand Up @@ -82,6 +86,7 @@ namespace Mix {
bool isTrigger() const { return !mRigidBody->hasContactResponse(); }
void setTrigger(const bool _flag) const;

/** @brief Disable deactivation of the rigid body thus it can be controlled by user input. */
void disableDeactivation() const { mRigidBody->setActivationState(DISABLE_DEACTIVATION); }
void enableDeactivation() const { mRigidBody->forceActivationState(ACTIVE_TAG); }

Expand Down Expand Up @@ -118,20 +123,17 @@ namespace Mix {
// todo: other interfaces

private:
struct LifeTimeManager;
static LifeTimeManager ltm;

btScalar mMass;
btCollisionShape* mShape;
std::shared_ptr<btCollisionShape> mShape;
btRigidBody* mRigidBody;
std::tuple<bool, int, int> mFilter;
btDiscreteDynamicsWorld* mWorld;

Signal mEnterSignal, mExitSignal;
void onTriggerEnter(HRigidBody _other) { mEnterSignal(_other); }
void onTriggerExit(HRigidBody _other) { mExitSignal(_other); }
void onTriggerEnter(HRigidBody _other) { mEnterSignal(std::move(_other)); }
void onTriggerExit(HRigidBody _other) { mExitSignal(std::move(_other)); }

/** @brief A utility function to create btRigidBody from RigidBodyConstructionInfo */
/** @brief A utility function that creates btRigidBody from RigidBodyConstructionInfo */
static btRigidBody* CreateBtRb(const Physics::RigidBodyConstructionInfo& _info);

void _forceReload() const {
Expand Down
10 changes: 0 additions & 10 deletions Mx/Exceptions/MxExceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@ namespace Mix {
std::string mWhat;
};

MX_DECLARE_RUNTIME_ERROR(ComponentCastingError, [ERROR] Cannot cast type to Component)

class IndependentComponentError final : public std::runtime_error {
public:
explicit IndependentComponentError(const std::string& _name)
: std::runtime_error("[ERROR] Component [" + _name + "] is not attached to a GameObject") {}
};

class ThirdPartyLibInitError final : public std::runtime_error {
public:
explicit ThirdPartyLibInitError(const std::string& _libName)
Expand All @@ -49,8 +41,6 @@ namespace Mix {

MX_DECLARE_RUNTIME_ERROR(WindowCreationError, [ERROR] Failed to create window)

MX_DECLARE_RUNTIME_ERROR(WindowIconLoadingError, [ERROR] Failed to load icon image)

#ifndef MX_EXCEPT
#define MX_EXCEPT(desc) \
{\
Expand Down
36 changes: 36 additions & 0 deletions Mx/Physics/MxColliderUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "MxColliderUtils.h"
#include "MxPhysicsUtils.hpp"
#include "../Resource/MxResourceLoader.h"
#include "../Resource/Model/MxModel.h"

namespace Mix::Physics {
CompoundCollider createColliderFromFile(const std::string& _path,
std::vector<ConvexHullCollider>& _children) {
auto model = ResourceLoader::Get()->load<Model>(_path);
if(!model)
return nullptr;

auto& meshes = model->getMeshes();

CompoundCollider collider(new btCompoundShape(true, meshes.size()));

_children.clear();
_children.reserve(meshes.size());

btTransform identityTrans(btTransform::getIdentity());

for(const auto& mesh : meshes) {
const auto& vertices = mesh->getPositions();

ConvexHullCollider childShape(new btConvexHullShape);
for(const auto& v : vertices)
childShape->addPoint(Physics::mx_bt_cast(v), false);
childShape->recalcLocalAabb();
_children.emplace_back(childShape);

collider->addChildShape(identityTrans, childShape.get());
}

return collider;
}
}
31 changes: 31 additions & 0 deletions Mx/Physics/MxColliderUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#ifndef MX_COLLIDER_UTILS_H_
#define MX_COLLIDER_UTILS_H_

#include <bullet3/btBulletCollisionCommon.h>
#include <vector>

namespace Mix::Physics {
using Collider = std::shared_ptr<btCollisionShape>;

using BoxCollider = std::shared_ptr<btBoxShape>;
using CapsuleColliderX = std::shared_ptr<btCapsuleShapeX>;
using CapsuleColliderY = std::shared_ptr<btCapsuleShape>;
using CapsuleColliderZ = std::shared_ptr<btCapsuleShapeZ>;
using CompoundCollider = std::shared_ptr<btCompoundShape>;
using ConvexHullCollider = std::shared_ptr<btConvexHullShape>;
using SphereCollider = std::shared_ptr<btSphereShape>;

/**
* @brief Create a collider according to a model file.
* @param[in] _path Path to the file.
* @param[out] _children Children shapes of the compound shape.
* @return The collider built from the file. @code nullptr @endcode if file not found.
* @attention CompoundCollider does NOT manage the lifetime of its children shapes internally.
*/
CompoundCollider createColliderFromFile(const std::string& _path,
std::vector<ConvexHullCollider>& _children);
}

#endif
4 changes: 2 additions & 2 deletions Mx/Physics/MxPhysicsDebugDraw.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ namespace Mix::Physics {
void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) override;

/** @note Not implemented yet */
void reportErrorWarning(const char* warningString) override { puts(warningString); }
void reportErrorWarning(const char* warningString) override {}

/** @note Not implemented yet */
void draw3dText(const btVector3& location, const char* textString) override { puts(textString); }
void draw3dText(const btVector3& location, const char* textString) override {}

/** @note See btIDebugDraw::DebugDrawModes */
void setDebugMode(int debugMode) override { mDebugMode = debugMode; }
Expand Down
26 changes: 12 additions & 14 deletions Mx/Physics/MxPhysicsDebugDrawImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
#ifndef MX_PHYSICS_DEBUG_DRAW_IMPL_H_
#define MX_PHYSICS_DEBUG_DRAW_IMPL_H_

// todo: delete debug code
#include "../Scene/MxSceneManager.h"
#include "../Component/Camera/MxCamera.h"
#include "../Window/MxWindow.h"
// -----

#ifdef MX_ENABLE_PHYSICS_DEBUG_DRAW_

#include "../Math/MxMatrix4.h"
#include "../Window/MxWindow.h"
#include "../Component/Camera/MxCamera.h"
#include "../Scene/MxSceneManager.h"

#include <SDL2/SDL_video.h>
#include <glad/glad.h>
Expand Down Expand Up @@ -264,15 +261,13 @@ namespace Mix::Physics::DebugDrawImpl {

mProgram->useSelf();

// todo: pass from Camera
// todo: set camera according to PhysicsScene
static auto camera = SceneManager::Get()->getActiveScene()->getMainCamera();
{
auto model = Matrix4(1);
model[2][2] = -1;
mProgram->setUniform("model", model);
mProgram->setUniform("view", camera->getViewMat());
mProgram->setUniform("projection", camera->getProjMat());
}
auto model = Matrix4(1);
model[2][2] = -1;
mProgram->setUniform("model", model);
mProgram->setUniform("view", camera->getViewMat());
mProgram->setUniform("projection", camera->getProjMat());

mVAO->bind();
mVBO->fillData(mNewData, GL_DYNAMIC_DRAW);
Expand All @@ -294,6 +289,9 @@ namespace Mix::Physics::DebugDrawImpl {
std::unique_ptr<glUtils::VertexBuffer> mVBO;

std::vector<float> mNewData;

// todo
//HCamera mActiveCamera;
};
}

Expand Down
31 changes: 1 addition & 30 deletions Mx/Physics/MxPhysicsUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace Mix::Physics {
inline Transform& bt_mx_cast(const btTransform& _btTrans, Transform& _mxTrans, const bool _switchHandness = true) noexcept {
_mxTrans.setPosition(bt_mx_cast(_btTrans.getOrigin(), _switchHandness));
_mxTrans.setRotation(bt_mx_cast(_btTrans.getRotation(), _switchHandness));
return _mxTrans; // code symmetric
return _mxTrans; // for code symmetry
}

inline btVector3 mx_bt_cast(const Vector3f& _mxVec, const bool _switchHandness = true) noexcept {
Expand All @@ -51,35 +51,6 @@ namespace Mix::Physics {
return btTransform(mx_bt_cast(_mxTrans.getRotation(), _switchHandness),
mx_bt_cast(_mxTrans.getPosition(), _switchHandness));
}

//inline Transform& bt_mx_cast(const btTransform& _btTrans, Transform& _mxTrans) noexcept {
// _mxTrans.setPosition({
// -_btTrans.getOrigin().x(),
// _btTrans.getOrigin().y(),
// _btTrans.getOrigin().z()
// });
// _mxTrans.setRotation({
// -_btTrans.getRotation().w(),
// -_btTrans.getRotation().x(),
// _btTrans.getRotation().y(),
// _btTrans.getRotation().z()
// });
// return _mxTrans; // code symmetric
//}

//inline btTransform mx_bt_cast(const Transform& _mxTrans) noexcept {
// return btTransform({
// -_mxTrans.getRotation().x,
// _mxTrans.getRotation().y,
// _mxTrans.getRotation().z,
// -_mxTrans.getRotation().w
// },
// {
// -_mxTrans.getPosition().x,
// _mxTrans.getPosition().y,
// _mxTrans.getPosition().z
// });
//}
}

#endif
11 changes: 2 additions & 9 deletions Mx/Physics/MxPhysicsWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ namespace Mix::Physics {
auto colObj = mWorld->getCollisionObjectArray()[i];
auto rb = btRigidBody::upcast(colObj);
if(rb) {
// PLEASE use Physics::MotionState PLEASE
// Should be Physics::MotionState
auto motionState = static_cast<MotionState*>(rb->getMotionState());
motionState->calculateInterpolatedTransform(_fixedDeltaTime, _smoothing);
}
Expand Down Expand Up @@ -161,17 +161,10 @@ namespace Mix::Physics {
auto colObj0 = manifold->getBody0();
auto colObj1 = manifold->getBody1();

// make colObj0 < colObj1
// swap manually in case std::swap be specialized
//if(colObj0 > colObj1) {
// auto temp = colObj0;
// colObj0 = colObj1;
// colObj1 = temp;
//}

auto rb0 = static_scene_object_cast<RigidBody>(*static_cast<HComponent*>(colObj0->getUserPointer()));
auto rb1 = static_scene_object_cast<RigidBody>(*static_cast<HComponent*>(colObj1->getUserPointer()));

// make rb0 < rb1
if(rb0->getInstanceId() > rb1->getInstanceId()) {
auto temp = rb0;
rb0 = rb1;
Expand Down
4 changes: 4 additions & 0 deletions Mx/Physics/MxPhysicsWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ namespace Mix {
void render() const;
#endif

/**
* @brief 「ザ・ワールド」
* @note Easter egg interface. NOT suggested to use in release.
*/
void theWorld() noexcept { mIsPaused = !mIsPaused; }

RaycastHit raycast(const Vector3<float>& _origin,
Expand Down
Loading

0 comments on commit 6828bda

Please sign in to comment.