diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-10-20 21:30:40 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-11-15 13:11:07 -0500 |
| commit | b9693565a4ccbf8767ab5fba931f4efa89082c83 (patch) | |
| tree | e1fcc2abc7ac469168b7cb7bf04cc549507f7dd1 | |
| parent | 5ec6a1a0e36a4a035c0adcf2993f2c435c59db27 (diff) | |
checkpoint - physics is working but messy
| -rw-r--r-- | src/components.hpp | 9 | ||||
| -rw-r--r-- | src/ecs.cpp | 62 | ||||
| -rw-r--r-- | src/ecs.hpp | 3 | ||||
| -rw-r--r-- | src/game-settings.hpp | 1 | ||||
| -rw-r--r-- | src/game.cpp | 6 |
5 files changed, 77 insertions, 4 deletions
diff --git a/src/components.hpp b/src/components.hpp index 4d52e39..3e7521f 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -4,6 +4,9 @@ #include "macros.hpp" #include "dynamic-array.hpp" +#include <BulletCollision/CollisionShapes/btCollisionShape.h> +#include <LinearMath/btDefaultMotionState.h> +#include <BulletDynamics/Dynamics/btRigidBody.h> #include <glm/gtc/quaternion.hpp> #include <vulkan/vulkan_core.h> @@ -63,6 +66,12 @@ struct CompInstance { InstanceHandle instanceHandle = InstanceHandle_MAX; uint64_t index = ECS_UNSET_VAL; InstPos instPos; + struct { + btVector3 localInertia; + btCollisionShape *collisionShape; + btDefaultMotionState defaultMotionState; + btRigidBody *rigidBody; + } bt; bool isNeedingUpdated = false; }; diff --git a/src/ecs.cpp b/src/ecs.cpp index 3c5cbdb..831adfb 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -1,12 +1,18 @@ #include "ecs.hpp" +#include "game-settings.hpp" #include "memory.hpp" #include "vendor/glm_include.hpp" #include "window.hpp" #include <btBulletDynamicsCommon.h> +#define GLM_TO_BULLET_VEC_3(vec) btVector3(vec.x, vec.y, vec.z) +#define GLM_TO_BULLET_QUAT(quat) btQuaternion(quat.x, quat.y, quat.z, quat.w) +#define BULLET_TO_GLM_VEC_3(vec) glm::vec3(vec.getX(), vec.getY(), vec.getZ()) +#define BULLET_TO_GLM_QUAT(qt) glm::quat(qt.getW(), qt.getX(), qt.getY(), qt.getZ()) + TypeSafeInt_B(EntityHandle); const uint64_t maxBucketItemCount = 256; @@ -178,6 +184,29 @@ void ECS_Tick_Early(double delta) { entitiesMarkedForRemoval.Resize(0); } +void ECS_Tick(double delta) { + if (btDynamicsWorld && pkeSettings.isSimulationPaused == false) { + auto physicsTickCount = btDynamicsWorld->stepSimulation(delta, 0); + if (physicsTickCount != 0) { + for (long b = 0; b <= Comp_Instance_BucketContainer.bucketCounter; ++b) { + auto &bkt = Comp_Instance_BucketContainer.buckets[b]; + long count = Comp_Instance_BucketContainer.bucketCounter == b ? Comp_Instance_BucketContainer.itemCounter >> 32 : maxBucketItemCount; + for (uint32_t i = 0; i < count; ++i) { + auto &inst = bkt.instances[i]; + btTransform trans; + inst.bt.defaultMotionState.getWorldTransform(trans); + + InstPos instPos = inst.instPos; + instPos.pos = BULLET_TO_GLM_VEC_3(trans.getOrigin()); + instPos.rot = BULLET_TO_GLM_QUAT(trans.getRotation()); + // TODO add an _INNER since we have a reference to the object that this looks up + ECS_UpdateInstance(inst.entHandle, instPos, false); + } + } + } + } +} + struct InstanceBufferCopyChunk { uint64_t startingIndex; uint64_t endingIndex; @@ -374,6 +403,22 @@ CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityType if (grBinds->instanceCounter > grBinds->instanceBufferMaxCount) { EntitiesWithExcessInstances.Push(grBinds->entHandle); } + + if (btDynamicsWorld) { + comp->bt.localInertia = btVector3(0, 0, 0); + comp->bt.collisionShape = Pke_New<btBoxShape>(bulletBucket); + new (comp->bt.collisionShape) btBoxShape(GLM_TO_BULLET_VEC_3(comp->instPos.scale)); + comp->bt.collisionShape->calculateLocalInertia(btScalar(1.f), comp->bt.localInertia); + btTransform transform; + transform.setIdentity(); + transform.setOrigin(GLM_TO_BULLET_VEC_3(comp->instPos.pos)); + comp->bt.defaultMotionState = btDefaultMotionState(transform); + comp->bt.rigidBody = Pke_New<btRigidBody>(bulletBucket); + new (comp->bt.rigidBody) btRigidBody(btScalar(1.f), &comp->bt.defaultMotionState, comp->bt.collisionShape, comp->bt.localInertia); + btDynamicsWorld->addRigidBody(comp->bt.rigidBody); + comp->bt.rigidBody->setUserPointer(reinterpret_cast<void *>(comp->entHandle)); + } + return *comp; } @@ -392,7 +437,7 @@ CompInstance *ECS_GetInstance(EntityHandle entHandle) { return inst; } -void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos) { +void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos, bool overridePhysics) { Entity *ent = nullptr; ECS_GetEntity_Inner(entHandle, ent); @@ -404,10 +449,25 @@ void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos) { auto i = Buckets_GetItemIndex(instanceHandle_t); auto *inst = &Comp_Instance_BucketContainer.buckets[b].instances[i]; + if (overridePhysics == false + && instPos.pos == inst->instPos.pos + && instPos.rot == inst->instPos.rot + && instPos.scale == inst->instPos.scale) { + return; + } + inst->instPos.pos = instPos.pos; inst->instPos.rot = instPos.rot; inst->instPos.scale = instPos.scale; inst->isNeedingUpdated = true; + + if (overridePhysics == true && btDynamicsWorld) { + btTransform transform; + transform.setIdentity(); + transform.setOrigin(GLM_TO_BULLET_VEC_3(inst->instPos.pos)); + transform.setRotation(GLM_TO_BULLET_QUAT(inst->instPos.rot)); + inst->bt.rigidBody->setWorldTransform(transform); + } } uint64_t ECS_GetInstances_BucketCount() { diff --git a/src/ecs.hpp b/src/ecs.hpp index 49d947c..480ba0c 100644 --- a/src/ecs.hpp +++ b/src/ecs.hpp @@ -20,6 +20,7 @@ static struct { void ECS_Init(); void ECS_Teardown(); void ECS_Tick_Early(double delta); +void ECS_Tick(double delta); void ECS_Tick_Late(double delta); EntityHandle ECS_CreateEntity(EntityHandle parentEntHandle = EntityHandle{EntityHandle_T{0xFFFFFFFFFFFFFFFF}}); void ECS_MarkForRemoval(EntityHandle entHandle); @@ -33,7 +34,7 @@ CompGrBinds *ECS_GetGrBinds(uint64_t bucketIndex, uint64_t &itemCount); CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityTypeEntityHandle); CompInstance *ECS_GetInstance(EntityHandle entHandle); -void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos); +void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos, bool overridePhysics = false); uint64_t ECS_GetInstances_BucketCount(); CompInstance *ECS_GetInstances(uint64_t bucketIndex, uint64_t &itemCount); diff --git a/src/game-settings.hpp b/src/game-settings.hpp index c42b917..1131e6d 100644 --- a/src/game-settings.hpp +++ b/src/game-settings.hpp @@ -9,6 +9,7 @@ struct GameSettings { bool isGamePaused = false; bool isShowingEditor = true; bool isRenderingDebug = false; + bool isSimulationPaused = false; std::chrono::steady_clock steadyClock; int64_t targetFPS = 144; int64_t minFPS = 20; diff --git a/src/game.cpp b/src/game.cpp index e921b2f..a1ba28b 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -247,7 +247,7 @@ void ParseInstance(std::ifstream &stream) { const auto &et = GlobalEntityTypes[existingEntityTypeIndex]; auto entityHandle = ECS_CreateEntity(); ECS_CreateInstance(entityHandle, et.entityHandle); - ECS_UpdateInstance(entityHandle, comp.instPos); + ECS_UpdateInstance(entityHandle, comp.instPos, true); break; } if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_HANDLE)) { @@ -422,6 +422,7 @@ void Game_Tick(double delta) { EntityHandle newEntity = ECS_CreateEntity(); ECS_CreateInstance(newEntity, createInfo.entityTypeEntityHandle); } + PkeInput_Tick(delta); PkeInputEventHolder holder = PkeInput_Query(dbgCtrl_UnlockCamera); if (holder.type != InputEventHash{0}) { @@ -573,6 +574,7 @@ void RecordImGuiEditorWrapper() { } if (ImGui::BeginMenu("Debug")) { ImGui::Checkbox("Show Debug Hitboxes", &pkeSettings.isRenderingDebug); + ImGui::Checkbox("Pause Physics Simulation", &pkeSettings.isSimulationPaused); if (ImGui::Checkbox("Uncap Framerate", &pkeSettings.graphicsSettings.isFramerateUnlocked)) { shouldRecreateSwapchain = true; } @@ -815,7 +817,7 @@ void RecordImGui_CompInstPos(bool readonly, CompInstance *component) { changed = ImGui::InputScalarN("scale", ImGuiDataType_Float, &component->instPos.scale, 3, nullptr, nullptr, nullptr, inputTextFlags) || changed; if (changed) { - ECS_UpdateInstance(component->entHandle, component->instPos); + ECS_UpdateInstance(component->entHandle, component->instPos, true); } ImGui::Spacing(); |
