diff options
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | editor/editor.cpp | 129 | ||||
| -rw-r--r-- | src/arg-handler.cpp | 1 | ||||
| -rw-r--r-- | src/array.hpp | 8 | ||||
| -rw-r--r-- | src/camera.cpp | 77 | ||||
| -rw-r--r-- | src/camera.hpp | 5 | ||||
| -rw-r--r-- | src/components.hpp | 6 | ||||
| -rw-r--r-- | src/entities.cpp | 1 | ||||
| -rw-r--r-- | src/game.cpp | 276 | ||||
| -rw-r--r-- | src/plugin-types.hpp | 25 | ||||
| -rw-r--r-- | src/plugins.hpp | 19 | ||||
| -rw-r--r-- | src/project.cpp | 1 | ||||
| -rw-r--r-- | src/window.cpp | 20 |
13 files changed, 319 insertions, 250 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7582f10..bbeec90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ set(PKE_SOURCE_FILES src/player-input.cpp src/plugins.hpp src/plugins.cpp + src/plugin-types.hpp src/project.hpp src/project.cpp src/project-settings.hpp diff --git a/editor/editor.cpp b/editor/editor.cpp index f22c3dd..e0ac795 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -12,6 +12,7 @@ #include "level.hpp" #include "math-helpers.hpp" #include "player-input.hpp" +#include "plugins.hpp" #include "project.hpp" #include "thread_pool.hpp" #include "vendor/glm_include.hpp" @@ -47,15 +48,6 @@ const char* const dbgCtrl_DeleteSelectedItem = "debug-delete-selected-item"; ThreadPoolHandle threadPoolHandle = ThreadPoolHandle_MAX; -PkeCamera cameraDbg { - .pos = glm::vec3(4.f, 4.f, 4.f), - .rot = glm::quat(1.f, 0.f, 0.f, 0.f), - .target = glm::vec3(0.f), - .type = PKE_CAMERA_TYPE_PERSPECTIVE, - .view = PKE_CAMERA_VIEW_FREE, - .stale = PKE_CAMERA_STALE_ALL, -}; - InputActionSetHandle debugControlsHandle = InputActionSetHandle_MAX; bool shouldSetupEditor = true; bool shouldDisableEditor = false; @@ -290,15 +282,17 @@ void PkeEditor_Tick(double delta) { pkeSettings.editorSettings.isUsingDebugCamera = true; glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); selectedCamera = CameraHandle_MAX; - if (ActiveCamera != &cameraDbg) { - cameraDbg.pos = ActiveCamera->pos; - if (ActiveCamera->view == cameraDbg.view) { - cameraDbg.rot = ActiveCamera->rot; - } else { - cameraDbg.rot = glm::quat(UBO.view); - } - cameraDbg.stale = PKE_CAMERA_STALE_ALL; - ActiveCamera = &cameraDbg; + if (ActiveCamera != &NullCamera) { + btTransform btfm; + ActiveCamera->phys.inst->bt.motionState->getWorldTransform(btfm); + NullCamera.phys.inst->bt.motionState->setWorldTransform(btfm); + NullCamera.phys.inst->bt.rigidBody->setWorldTransform(btfm); + NullCamera.phys.inst->bt.rigidBody->activate(); + NullCamera.phys.targetInst = ActiveCamera->phys.targetInst; + NullCamera.type = ActiveCamera->type; + NullCamera.view = ActiveCamera->view; + NullCamera.stale = PKE_CAMERA_STALE_ALL; + ActiveCamera = &NullCamera; } } else if (toggleCameraMovement->isPressed && pkeSettings.editorSettings.isUsingDebugCamera == true) { pkeSettings.editorSettings.isUsingDebugCamera = false; @@ -307,19 +301,29 @@ void PkeEditor_Tick(double delta) { } } - if (pkeSettings.editorSettings.isUsingDebugCamera && ActiveCamera == &cameraDbg) { + if (pkeSettings.editorSettings.isUsingDebugCamera && ActiveCamera == &NullCamera) { holder = PkeInput_Query(dbgCtrl_CameraRot); + + btTransform trfm; + NullCamera.phys.inst->bt.motionState->getWorldTransform(trfm); + if (holder.type != InputEventHash{0}) { const PkeCursorPosEvent *posEvent = static_cast<PkeCursorPosEvent *>(holder.ptr); if (posEvent->xMotion || posEvent->yMotion) { - glm::vec3 axis1Heading = glm::conjugate(cameraDbg.rot) * glm::vec3(1.f, 0.f, 0.f); - glm::vec3 axis2Heading = glm::conjugate(cameraDbg.rot) * glm::vec3(0.f, 1.f, 0.f); + glm::quat gRot; + BulletToGlm(trfm.getRotation(), gRot); + + glm::vec3 axis1Heading = glm::conjugate(gRot) * glm::vec3(1.f, 0.f, 0.f); + glm::vec3 axis2Heading = glm::conjugate(gRot) * glm::vec3(0.f, 1.f, 0.f); glm::quat pitch = glm::angleAxis(float(posEvent->yMotion) * 0.01f, glm::normalize(axis1Heading)); glm::quat yaw = glm::angleAxis(float(posEvent->xMotion) * 0.01f, glm::normalize(axis2Heading)); - glm::quat rot = cameraDbg.rot * pitch * yaw; + glm::quat rot = gRot * pitch * yaw; auto eul = glm::eulerAngles(rot); - cameraDbg.rot = glm::quat(eul); - cameraDbg.stale = cameraDbg.stale | PKE_CAMERA_STALE_ROT; + gRot = glm::quat(eul); + btQuaternion bRot; + GlmToBullet(gRot, bRot); + trfm.setRotation(bRot); + NullCamera.stale = NullCamera.stale | PKE_CAMERA_STALE_ROT; } } @@ -393,18 +397,31 @@ void PkeEditor_Tick(double delta) { double axis2 = (forwardCount * accelerated) + -(backCount * accelerated); double axis3 = -(upCount * accelerated) + (downCount * accelerated); if (axis1 != 0 || axis2 != 0 || axis3 != 0) { - glm::vec3 axis1Heading = glm::conjugate(cameraDbg.rot) * glm::vec3(-axis1, 0.f, 0.f); - glm::vec3 axis2Heading = glm::conjugate(cameraDbg.rot) * glm::vec3(0.f, 0.f, axis2); - glm::vec3 axis3Heading = glm::conjugate(cameraDbg.rot) * glm::vec3(0.f, axis3, 0.f); - cameraDbg.pos += glm::vec3(axis1Heading + axis2Heading + axis3Heading); - cameraDbg.stale = cameraDbg.stale | PKE_CAMERA_STALE_POS; + glm::quat gRot; + BulletToGlm(trfm.getRotation(), gRot); + glm::vec3 axis1Heading = glm::conjugate(gRot) * glm::vec3(-axis1, 0.f, 0.f); + glm::vec3 axis2Heading = glm::conjugate(gRot) * glm::vec3(0.f, 0.f, axis2); + glm::vec3 axis3Heading = glm::conjugate(gRot) * glm::vec3(0.f, axis3, 0.f); + glm::vec3 gPos; + BulletToGlm(trfm.getOrigin(), gPos); + gPos += glm::vec3(axis1Heading + axis2Heading + axis3Heading); + btVector3 bPos; + GlmToBullet(gPos, bPos); + trfm.setOrigin(bPos); + NullCamera.stale = NullCamera.stale | PKE_CAMERA_STALE_POS; } double axis4 = -(rotCCCount * delta) + (rotCCount * delta); if (axis4 != 0.0) { - cameraDbg.rot = glm::quat(glm::vec3(0.f, 0.f, axis4)) * cameraDbg.rot; - cameraDbg.stale = cameraDbg.stale | PKE_CAMERA_STALE_ROT; + glm::quat gRot; + BulletToGlm(trfm.getRotation(), gRot); + gRot = glm::quat(glm::vec3(0.f, 0.f, axis4)) * gRot; + NullCamera.stale = NullCamera.stale | PKE_CAMERA_STALE_ROT; } + + NullCamera.phys.inst->bt.motionState->setWorldTransform(trfm); + NullCamera.phys.inst->bt.rigidBody->setWorldTransform(trfm); + NullCamera.phys.inst->bt.rigidBody->activate(); } holder = PkeInput_Query(dbgCtrl_DeleteSelectedItem); @@ -682,18 +699,15 @@ void RecordImGuiCameras() { } if (ImGui::Button("Create")) { InstPos instPos{}; - btVector3 pos; - btQuaternion quat; - GlmToBullet(ActiveCamera->pos, pos); - GlmToBullet(ActiveCamera->rot, quat); instPos.mass = 1.f; - instPos.posRot.setOrigin(pos); - instPos.posRot.setRotation(quat); + ActiveCamera->phys.inst->bt.motionState->getWorldTransform(instPos.posRot); + instPos.scale = ActiveCamera->phys.inst->bt.rigidBody->getCollisionShape()->getLocalScaling(); auto &cam = PkeCamera_Register(instPos); - cam.target = ActiveCamera->target; + cam.phys.targetInst = ActiveCamera->phys.targetInst; cam.type = ActiveCamera->type; cam.view = ActiveCamera->view; cam.isPrimary = false; + PkeLevel_RegisterCamera(pkeSettings.rt.activeLevel, cam.camHandle); } static ImGuiTableFlags tableFlags{ @@ -703,11 +717,9 @@ void RecordImGuiCameras() { if (ImGui::BeginTable("Entities", 9, tableFlags)) { ImGui::TableSetupColumn("Interact"); ImGui::TableSetupColumn("CameraHandle"); - ImGui::TableSetupColumn("Pos"); - ImGui::TableSetupColumn("Rot"); ImGui::TableSetupColumn("Target"); ImGui::TableSetupColumn("Type"); - ImGui::TableSetupColumn("Orientation"); + ImGui::TableSetupColumn("View"); ImGui::TableSetupColumn("Stale"); ImGui::TableSetupColumn("IsPrimary"); ImGui::TableHeadersRow(); @@ -738,18 +750,14 @@ void RecordImGuiCameras() { ImGui::TableSetColumnIndex(1); ImGui::Text("0x%016lX", cam.handle.hash); ImGui::TableSetColumnIndex(2); - ImGui::Text("%4.2f,%4.2f,%4.2f", cam.pos[0], cam.pos[1], cam.pos[2]); + ImGui::Text("0x%p", cam.phys.targetInst); ImGui::TableSetColumnIndex(3); - ImGui::Text("%4.2f,%4.2f,%4.2f,%4.2f", cam.rot[0], cam.rot[1], cam.rot[2], cam.rot[3]); - ImGui::TableSetColumnIndex(4); - ImGui::Text("%4.2f,%4.2f,%4.2f", cam.target[0], cam.target[1], cam.target[2]); - ImGui::TableSetColumnIndex(5); ImGui::Text("%hhu", cam.type); - ImGui::TableSetColumnIndex(6); + ImGui::TableSetColumnIndex(4); ImGui::Text("%hhu", cam.view); - ImGui::TableSetColumnIndex(7); + ImGui::TableSetColumnIndex(5); ImGui::Text("%hhu", cam.stale); - ImGui::TableSetColumnIndex(8); + ImGui::TableSetColumnIndex(6); ImGui::Text("%i", cam.isPrimary); ImGui::PopID(); } @@ -764,13 +772,6 @@ void RecordImGuiCameras() { if (cam) { bool isOrientTarget{bool(static_cast<PkeCameraView_T>(cam->view & PKE_CAMERA_VIEW_TARGET))}; bool isOrientFree{bool(static_cast<PkeCameraView_T>(cam->view & PKE_CAMERA_VIEW_FREE))}; - if (ImGui::InputScalarN("Pos", ImGuiDataType_Float, &cam->pos, 3, nullptr, nullptr, nullptr)) - cam->stale = cam->stale | PKE_CAMERA_STALE_POS; - if (ImGui::InputScalarN("Rot", ImGuiDataType_Float, &cam->rot, 4, nullptr, nullptr, nullptr, isOrientFree ? 0 : inputTextFlags)) - cam->stale = cam->stale | PKE_CAMERA_STALE_ROT; - if (ImGui::InputScalarN("Target", ImGuiDataType_Float, &cam->target, 3, nullptr, nullptr, nullptr, isOrientTarget ? 0 : inputTextFlags)) - cam->stale = cam->stale | PKE_CAMERA_STALE_ROT; - bool isPerspective{bool(static_cast<PkeCameraType_T>(cam->type & PKE_CAMERA_TYPE_PERSPECTIVE))}; bool isOrthogonal{bool(static_cast<PkeCameraType_T>(cam->type & PKE_CAMERA_TYPE_ORTHOGONAL))}; ImGui::BeginDisabled(isPerspective); @@ -1092,7 +1093,8 @@ void RecordImGui_CompInstPos(bool readonly, CompInstance *component) { ImGui::InputScalar("Phys - Rigid Body", ImGuiDataType_U64, &component->bt.rigidBody, nullptr, nullptr, "0x%016lX", ImGuiInputTextFlags_ReadOnly); ImGui::InputScalar("Phys - Motion State", ImGuiDataType_U64, &component->bt.motionState, nullptr, nullptr, "0x%016lX", ImGuiInputTextFlags_ReadOnly); - ImGui::BeginDisabled(ActiveCamera->handle == component->entHandle || ActiveCamera->phys.inst == nullptr || ActiveCamera->phys.inst == CAFE_BABE(CompInstance)); + // exclude EntityHandle_MAX so you can't attach the NullCamera + ImGui::BeginDisabled(ActiveCamera->handle == component->entHandle || ActiveCamera->handle == EntityHandle_MAX || ActiveCamera->phys.inst == nullptr || ActiveCamera->phys.inst == CAFE_BABE(CompInstance)); if (ImGui::Button("Attach Active Camera")) { PkeCamera_AttachToInstance(ActiveCamera->camHandle, component); } @@ -1389,11 +1391,16 @@ void PkeEditor_Init() { debugControlsHandle = PkeInput_RegisterSet(debugControlsSet); - NullCamera.pos = glm::vec3(-40.f, -40.f, -40.f), - NullCamera.rot = glm::quat(1.f, 0.f, 0.f, 0.f), - NullCamera.target = glm::vec3(0.f), + btTransform trfm{}; + trfm.setIdentity(); + trfm.setOrigin(btVector3(-40.f, -40.f, -40.f)); + trfm.setRotation(btQuaternion(0.f, 0.f, 0.f, 1.f)); + + NullCamera.phys.inst->bt.motionState->setWorldTransform(trfm); + NullCamera.phys.inst->bt.rigidBody->setWorldTransform(trfm); + NullCamera.phys.inst->bt.rigidBody->activate(); NullCamera.type = PKE_CAMERA_TYPE_PERSPECTIVE, - NullCamera.view = PKE_CAMERA_VIEW_TARGET, + NullCamera.view = PKE_CAMERA_VIEW_FREE, NullCamera.stale = PKE_CAMERA_STALE_ALL, threadPoolHandle = PkeThreads_Init(1, 1); diff --git a/src/arg-handler.cpp b/src/arg-handler.cpp index 2183347..3bd1ac3 100644 --- a/src/arg-handler.cpp +++ b/src/arg-handler.cpp @@ -35,7 +35,6 @@ void PkeArgs_Parse(int argc, char *argv[]) { pkeSettings.args.sceneName = optarg; pkeSettings.rt.shouldLoadScene = true; pkeSettings.rt.sceneName = pkeSettings.args.sceneName; - pkeSettings.rt.nextLevel = PkeLevel_Create("transient"); break; default: fprintf(stderr, "Unused parameter: %c\n", c); diff --git a/src/array.hpp b/src/array.hpp index f8aa173..7db2252 100644 --- a/src/array.hpp +++ b/src/array.hpp @@ -61,11 +61,11 @@ inline void PkeArray_Add(PkeArray_Base *arrIn, const D &val, MemBucket *bkt = nu } } -template<typename D, typename F = bool(const D&)> -inline uint32_t PkeArray_FindFirstIndex(PkeArray_Base *arrIn, F fn) { +template<typename D, typename D2, typename F = bool(const D&, const D2&)> +inline int64_t PkeArray_FindFirstIndex(PkeArray_Base *arrIn, F fn, const D2 &d2) { auto *arr = static_cast<PkeArray<D> *>(arrIn); - for (uint32_t i = 0; i < arr->next; ++i) { - if (fn(arr->data[i])) { + for (int64_t i = 0; i < arr->next; ++i) { + if (fn(arr->data[i], d2)) { return i; } } diff --git a/src/camera.cpp b/src/camera.cpp index 984f106..f033824 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -10,14 +10,12 @@ PkeCamera NullCamera { .camHandle = CameraHandle_MAX, - .pos = glm::vec3(3.f, 3.f, 3.f), - .rot = glm::quat(1.f, 0.f, 0.f, 0.f), - .target = glm::vec3(0.f), .type = PKE_CAMERA_TYPE_ORTHOGONAL, .view = PKE_CAMERA_VIEW_TARGET, .stale = PKE_CAMERA_STALE_ALL, .phys = { .inst = nullptr, + .targetInst = nullptr, .constraint = nullptr, }, }; @@ -28,16 +26,7 @@ BucketContainer<PkeCamera, CameraHandle> Camera_BucketContainer{}; btSphereShape CameraShape{1.f}; -PkeCamera &PkeCamera_Register(const InstPos &instPos) { - CameraHandle cameraHandle{Buckets_NewHandle(Camera_BucketContainer)}; - - auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex]; - new (&cam) PkeCamera{}; - - ECS_CreateEntity(&cam, nullptr); - cam.camHandle = cameraHandle; - cam.phys.inst = ECS_CreateInstance(&cam, nullptr); - +PkeCamera &PkeCamera_Register_Inner(PkeCamera &cam, const InstPos &instPos) { btVector3 gravity(0.f, 0.f, 0.f); cam.phys.inst->physicsLayer = PhysicsCollision{0}; @@ -63,11 +52,38 @@ PkeCamera &PkeCamera_Register(const InstPos &instPos) { return cam; } +PkeCamera &PkeCamera_Register(const InstPos &instPos) { + CameraHandle cameraHandle{Buckets_NewHandle(Camera_BucketContainer)}; + + auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex]; + new (&cam) PkeCamera{}; + + ECS_CreateEntity(&cam, nullptr); + cam.camHandle = cameraHandle; + cam.phys.inst = ECS_CreateInstance(&cam, nullptr); + + return PkeCamera_Register_Inner(cam, instPos); +} + PkeCamera *PkeCamera_Get(CameraHandle cameraHandle) { assert(cameraHandle != CameraHandle_MAX); return &Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex]; } +PkeCamera *PkeCamera_Get(EntityHandle handle) { + assert(handle != EntityHandle_MAX); + for (PkeHandleBucketIndex_T b = 0; b <= Camera_BucketContainer.pkeHandle.bucketIndex; ++b) { + auto &bkt = Camera_BucketContainer.buckets[b]; + long itemCount = Camera_BucketContainer.pkeHandle.bucketIndex == b ? Camera_BucketContainer.pkeHandle.itemIndex : Camera_BucketContainer.limits.itemIndex; + for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + auto &cam = bkt[i]; + if (cam.handle == handle) + return &Camera_BucketContainer.buckets[cam.camHandle.bucketIndex][cam.camHandle.itemIndex]; + } + } + return nullptr; +} + void PkeCamera_AttachToInstance(CameraHandle cameraHandle, CompInstance *inst) { assert(cameraHandle != CameraHandle_MAX); auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex]; @@ -81,10 +97,9 @@ void PkeCamera_AttachToInstance(CameraHandle cameraHandle, CompInstance *inst) { btTransform trfm; inst->bt.motionState->getWorldTransform(trfm); - BulletToGlm(trfm.getOrigin(), cam.target); trfm.setOrigin(trfm.getOrigin() + cameraOffset); - BulletToGlm(trfm.getOrigin(), cam.pos); + cam.phys.targetInst = inst; cam.phys.inst->bt.motionState->setWorldTransform(trfm); cam.phys.inst->bt.rigidBody->setWorldTransform(trfm); cam.phys.inst->bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); @@ -93,7 +108,7 @@ void PkeCamera_AttachToInstance(CameraHandle cameraHandle, CompInstance *inst) { assert(cam.phys.constraint == nullptr || cam.phys.constraint == CAFE_BABE(btTypedConstraint)); cam.phys.constraint = Pke_New<btTypedConstraint>(MemBkt_Bullet); - new (cam.phys.constraint) btPoint2PointConstraint(*cam.phys.inst->bt.rigidBody, *inst->bt.rigidBody, btVector3(0.f, 0.f, 0.f), cameraOffset); + new (cam.phys.constraint) btPoint2PointConstraint(*cam.phys.inst->bt.rigidBody, *inst->bt.rigidBody, btVector3(0.f, -1.f, -1.f), cameraOffset); BtDynamicsWorld->addConstraint(cam.phys.constraint); cam.view = PKE_CAMERA_VIEW_TARGET; @@ -122,13 +137,11 @@ void PkeCamera_Destroy(CameraHandle cameraHandle) { ECS_MarkForRemoval(camPtr); cam.camHandle = CameraHandle_MAX; - cam.pos = glm::vec3(0); - cam.rot = glm::quat{}; - cam.target = glm::vec3(0); cam.type = PkeCameraType_MAX; cam.view = PkeCameraView_MAX; cam.stale = PkeCameraStaleFlags_MAX; cam.phys.inst = CAFE_BABE(CompInstance); + cam.phys.targetInst = CAFE_BABE(CompInstance); cam.phys.constraint = CAFE_BABE(btTypedConstraint); } @@ -147,10 +160,23 @@ PkeCamera *PkeCamera_GetCameras(int64_t bucketIndex, int64_t &count) { void PkeCamera_Init() { Buckets_Init(Camera_BucketContainer, MAX_CAMERAS_PER_BUCKET); + NullCamera.phys.inst = Pke_New<CompInstance>(); + InstPos instPos{ + .scale = btVector3(1.f, 1.f, 1.f), + .mass = 1.f, + }; + PkeCamera_Register_Inner(NullCamera, instPos); } void PkeCamera_Teardown() { Buckets_Destroy(Camera_BucketContainer); + BtDynamicsWorld->removeRigidBody(NullCamera.phys.inst->bt.rigidBody); + Pke_Delete<btDefaultMotionState>(NullCamera.phys.inst->bt.motionState, MemBkt_Bullet); + Pke_Delete<btRigidBody>(NullCamera.phys.inst->bt.rigidBody, MemBkt_Bullet); + NullCamera.phys.inst->bt.motionState = CAFE_BABE(btDefaultMotionState); + NullCamera.phys.inst->bt.rigidBody = CAFE_BABE(btRigidBody); + Pke_Delete<CompInstance>(NullCamera.phys.inst); + NullCamera.phys.inst = CAFE_BABE(CompInstance); } void PkeCamera_Tick(double delta) { @@ -172,18 +198,13 @@ void PkeCamera_Tick(double delta) { if (cam.handle == EntityHandle_MAX) { continue; } - btTransform trfm; - if (cam.phys.constraint != nullptr && cam.phys.constraint != CAFE_BABE(btTypedConstraint)) { - cam.phys.constraint->getRigidBodyB().getMotionState()->getWorldTransform(trfm); - BulletToGlm(trfm.getOrigin(), cam.target); - } - if (cam.phys.inst != nullptr && cam.phys.inst != CAFE_BABE(CompInstance)) { - cam.phys.inst->bt.motionState->getWorldTransform(trfm); - BulletToGlm(trfm.getOrigin(), cam.pos); - BulletToGlm(trfm.getRotation(), cam.rot); + if (cam.phys.inst != nullptr && cam.phys.inst != CAFE_BABE(CompInstance) && cam.phys.inst->isNeedingUpdated == true) { cam.stale = cam.stale | PKE_CAMERA_STALE_POSROT; cam.phys.inst->isNeedingUpdated = false; } + if (cam.phys.targetInst != nullptr && cam.phys.targetInst != CAFE_BABE(CompInstance) && cam.phys.targetInst->isNeedingUpdated == true) { + cam.stale = cam.stale | PKE_CAMERA_STALE_POSROT; + } } } } diff --git a/src/camera.hpp b/src/camera.hpp index 19e9da8..a2cce39 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -30,14 +30,12 @@ constexpr PkeCameraStaleFlags PKE_CAMERA_STALE_ALL = PkeCameraStaleFlags struct PkeCamera : public Entity_Base { CameraHandle camHandle = CameraHandle_MAX; - glm::vec3 pos = glm::vec3(0); - glm::quat rot = glm::quat{}; - glm::vec3 target = glm::vec3(0); PkeCameraType type = PkeCameraType_MAX; PkeCameraView view = PkeCameraView_MAX; PkeCameraStaleFlags stale = PkeCameraStaleFlags_MAX; struct Phys { CompInstance *inst = nullptr; + CompInstance *targetInst = nullptr; btTypedConstraint *constraint = nullptr; } phys; bool isPrimary = false; @@ -48,6 +46,7 @@ extern PkeCamera *ActiveCamera; void PkeCamera_Init(); PkeCamera &PkeCamera_Register(const InstPos &instPos); PkeCamera *PkeCamera_Get(CameraHandle handle); +PkeCamera *PkeCamera_Get(EntityHandle handle); void PkeCamera_AttachToInstance(CameraHandle cameraHandle, CompInstance *inst); void PkeCamera_DetachFromInstance(CameraHandle cameraHandle, CompInstance *inst); int64_t PkeCamera_GetBucketCount(); diff --git a/src/components.hpp b/src/components.hpp index 60b4c8e..7d298ec 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -4,7 +4,7 @@ #include "dynamic-array.hpp" #include "macros.hpp" #include "physics.hpp" -#include "plugins.hpp" +#include "plugin-types.hpp" #include <BulletDynamics/Dynamics/btRigidBody.h> #include <LinearMath/btDefaultMotionState.h> @@ -74,8 +74,8 @@ struct InstPos { btScalar mass; }; struct InstBt { - btDefaultMotionState *motionState; - btRigidBody *rigidBody; + btDefaultMotionState *motionState = nullptr; + btRigidBody *rigidBody = nullptr; }; struct CompInstance { EntityHandle entHandle = EntityHandle_MAX; diff --git a/src/entities.cpp b/src/entities.cpp index be0286c..cb66cef 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -8,6 +8,7 @@ #include "math-helpers.hpp" #include "memory.hpp" #include "physics.hpp" +#include "plugins.hpp" #include "static/missing-texture.hpp" #include "window.hpp" diff --git a/src/game.cpp b/src/game.cpp index 4390202..565f1ce 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,9 +1,11 @@ #include "game.hpp" +#include "array.hpp" #include "camera.hpp" #include "components.hpp" #include "dynamic-array.hpp" +#include "ecs.hpp" #include "entities.hpp" #include "game-settings.hpp" #include "helpers.hpp" @@ -32,6 +34,13 @@ const long readLineLength = 128; char readLine[readLineLength]; +struct InstMapping { + InstanceHandle origHandle = InstanceHandle_MAX; + Entity_Base *newEnt = nullptr; + CompInstance *newInst = nullptr; + InstPos newInstance{}; +}; +PkeArray<InstMapping> loadFileInstanceMappings{}; const char *levelName = "demo-level"; @@ -42,6 +51,7 @@ const char *PKE_FILE_OBJ_END = ""; const char *PKE_FILE_OBJ_INSTANCE = "Instance:"; const char *PKE_FILE_OBJ_CAMERA = "Camera:"; +const char *PKE_FILE_INSTANCE_HANDLE = "Inst::InstHandle: "; const char *PKE_FILE_INSTANCE_ENTITY_HANDLE = "EntityHandle: "; const char *PKE_FILE_INSTANCE_ENTITY_TYPE_CODE = "EntityTypeCode: "; const char *PKE_FILE_INSTANCE_POS_POS = "InstPos::Pos: "; @@ -52,61 +62,64 @@ const char *PKE_FILE_INSTANCE_PHYSICS_COLLISION_LAYER = "InstPos::CollisionLayer const char *PKE_FILE_INSTANCE_PHYSICS_COLLISION_MASK = "InstPos::CollisionMask: "; const char *PKE_FILE_INSTANCE_COLLISION_CALLBACK_SIGNATURE = "Inst::CollisionCallbackSignature: "; +const char PKE_FILE_INSTANCE_SPECIAL_ENTITY_TYPE_CODE_CAMERA = 'C'; + const char *PKE_FILE_CAMERA_POS = "Cam::Pos: "; const char *PKE_FILE_CAMERA_ROT = "Cam::Rot: "; const char *PKE_FILE_CAMERA_TARGET = "Cam::Target: "; const char *PKE_FILE_CAMERA_TYPE = "Cam::Type: "; const char *PKE_FILE_CAMERA_ORIENTATION = "Cam::Orientation: "; +const char *PKE_FILE_CAMERA_INSTANCE_HANDLE = "Cam::InstanceHandle: "; +const char *PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE = "Cam::TargetInstanceHandle: "; const char *PKE_FILE_CAMERA_IS_PRIMARY = "Cam::IsPrimary: "; void SerializeCamera(std::ostringstream &stream, const PkeCamera &cam) { + NULL_CHAR_ARR(handleStr, 19); PkeCamera c{}; - if (cam.pos != c.pos) { - stream << PKE_FILE_CAMERA_POS << "[" - << std::setw(10) << cam.pos[0] << "," - << std::setw(10) << cam.pos[1] << "," - << std::setw(10) << cam.pos[2] << "]" << std::endl; - } - if (cam.rot != c.rot) { - stream << PKE_FILE_CAMERA_ROT << "[" - << std::setw(10) << cam.rot[0] << "," - << std::setw(10) << cam.rot[1] << "," - << std::setw(10) << cam.rot[2] << "," - << std::setw(10) << cam.rot[3] << "]" << std::endl; - } - if (cam.target != c.target) { - stream << PKE_FILE_CAMERA_TARGET << "[" - << std::setw(10) << cam.target[0] << "," - << std::setw(10) << cam.target[1] << "," - << std::setw(10) << cam.target[2] << "]" << std::endl; - } if (cam.type != c.type) { stream << PKE_FILE_CAMERA_TYPE << int(static_cast<PkeCameraType_T>(cam.type)) << std::endl; } if (cam.view != c.view) { stream << PKE_FILE_CAMERA_ORIENTATION << int(static_cast<PkeCameraView_T>(cam.view)) << std::endl; } + if (cam.phys.inst != c.phys.inst && cam.phys.inst != CAFE_BABE(CompInstance)) { + snprintf(handleStr, 19, "0x%016lX", cam.phys.inst->instanceHandle.hash); + stream << PKE_FILE_CAMERA_INSTANCE_HANDLE << handleStr << std::endl; + } + if (cam.phys.targetInst != c.phys.targetInst && cam.phys.targetInst != CAFE_BABE(CompInstance)) { + snprintf(handleStr, 19, "0x%016lX", cam.phys.targetInst->instanceHandle.hash); + stream << PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE << handleStr << std::endl; + } if (cam.isPrimary != c.isPrimary) { stream << PKE_FILE_CAMERA_IS_PRIMARY << cam.isPrimary << std::endl; } } void SerializeInstance(std::ostringstream &stream, const CompInstance &comp) { - char handleStr[19] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' }; - snprintf(handleStr, 19, "0x%016lX", comp.entHandle.hash); - assert(comp.grBindsHandle != GrBindsHandle_MAX && "instance exists without a GrBinds"); - CompGrBinds *instGrBinds = ECS_GetGrBinds(comp.grBindsHandle); - EntityType *et = EntityType_FindByEntityHandle(instGrBinds->entHandle); - assert(et != nullptr && "instance had a GrBinds, but no EntityType could be found"); + NULL_CHAR_ARR(handleStr, 19); + EntityType *et = nullptr; + if (comp.grBindsHandle != GrBindsHandle_MAX) { + et = EntityType_FindByEntityHandle(ECS_GetGrBinds(comp.grBindsHandle)->entHandle); + } CompInstance c{}; InstPos baseInst{}; baseInst.posRot = btTransform{}; baseInst.posRot.setIdentity(); baseInst.scale = btVector3(1, 1, 1); baseInst.mass = 1; - if (comp.entHandle != c.entHandle) + if (comp.entHandle != c.entHandle) { + snprintf(handleStr, 19, "0x%016lX", comp.entHandle.hash); stream << PKE_FILE_INSTANCE_ENTITY_HANDLE << handleStr << std::endl; - stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode << std::endl; + } + if (comp.entHandle != c.entHandle) { + snprintf(handleStr, 19, "0x%016lX", comp.instanceHandle.hash); + stream << PKE_FILE_INSTANCE_HANDLE << handleStr << std::endl; + } + if (et != nullptr) { + stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode << std::endl; + } else if (PkeCamera_Get(comp.entHandle)) { + stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << PKE_FILE_INSTANCE_SPECIAL_ENTITY_TYPE_CODE_CAMERA << std::endl; + } btTransform trans; comp.bt.motionState->getWorldTransform(trans); @@ -146,71 +159,46 @@ void SerializeInstance(std::ostringstream &stream, const CompInstance &comp) { } } +bool FindFirstInstanceHandle(const InstMapping &mapping, const InstanceHandle handle) { + return mapping.origHandle == handle; +} void ParseCamera(PkeLevel *level, std::ifstream &stream) { PkeCamera cam{}; + InstanceHandle instanceHandle = InstanceHandle_MAX; + InstanceHandle targetInstanceHandle = InstanceHandle_MAX; while (stream.getline(readLine, readLineLength)) { if (strcmp(readLine, PKE_FILE_OBJ_END) == 0) { - InstPos instPos{}; - btVector3 pos; - btQuaternion quat; - GlmToBullet(cam.pos, pos); - GlmToBullet(cam.rot, quat); - instPos.mass = 1.f; - instPos.posRot.setOrigin(pos); - instPos.posRot.setRotation(quat); + + int64_t instanceIndex = -1, targetInstanceIndex = -1; + + instanceIndex = PkeArray_FindFirstIndex<InstMapping, InstanceHandle>(&loadFileInstanceMappings, FindFirstInstanceHandle, instanceHandle); + + if (targetInstanceHandle != InstanceHandle_MAX) { + targetInstanceIndex = PkeArray_FindFirstIndex<InstMapping, InstanceHandle>(&loadFileInstanceMappings, FindFirstInstanceHandle, targetInstanceHandle); + } + + InstPos instPos; + if (instanceIndex == -1) { + instPos.mass = 1.f; + instPos.posRot.setIdentity(); + instPos.scale = btVector3(1.f, 1.f, 1.f); + fprintf(stdout, "[ParseCamera] Failed to find instance mapping. Is this an outdated parse?"); + } else { + instPos = loadFileInstanceMappings.data[instanceIndex].newInstance; + } auto &rCam = PkeCamera_Register(instPos); - rCam.target = cam.target; rCam.type = cam.type; rCam.view = cam.view; rCam.isPrimary = cam.isPrimary; PkeLevel_RegisterCamera(level->levelHandle, rCam.camHandle); + if (targetInstanceIndex > -1) { + PkeCamera_AttachToInstance(rCam.camHandle, loadFileInstanceMappings.data[targetInstanceIndex].newInst); + } if (rCam.isPrimary == true) { ActiveCamera = &rCam; } return; } - if (strncmp(readLine, PKE_FILE_CAMERA_POS, strlen(PKE_FILE_CAMERA_POS)) == 0) { - uint64_t prefixLen = strlen(PKE_FILE_CAMERA_POS); - char *startingChar = strchr(readLine + prefixLen, '[') + 1; - assert(startingChar != nullptr); - char *pEnd = nullptr; - long index = 0; - do { - assert(index < 3); - STR2NUM_ERROR result = str2num(cam.pos[index], startingChar, pEnd); - assert(result == STR2NUM_ERROR::SUCCESS); - startingChar = pEnd + 1; - ++index; - } while (*pEnd != ']'); - } - if (strncmp(readLine, PKE_FILE_CAMERA_ROT, strlen(PKE_FILE_CAMERA_ROT)) == 0) { - uint64_t prefixLen = strlen(PKE_FILE_CAMERA_ROT); - char *startingChar = strchr(readLine + prefixLen, '[') + 1; - assert(startingChar != nullptr); - char *pEnd = nullptr; - long index = 0; - do { - assert(index < 4); - STR2NUM_ERROR result = str2num(cam.rot[index], startingChar, pEnd); - assert(result == STR2NUM_ERROR::SUCCESS); - startingChar = pEnd + 1; - ++index; - } while (*pEnd != ']'); - } - if (strncmp(readLine, PKE_FILE_CAMERA_TARGET, strlen(PKE_FILE_CAMERA_TARGET)) == 0) { - uint64_t prefixLen = strlen(PKE_FILE_CAMERA_TARGET); - char *startingChar = strchr(readLine + prefixLen, '[') + 1; - assert(startingChar != nullptr); - char *pEnd = nullptr; - long index = 0; - do { - assert(index < 3); - STR2NUM_ERROR result = str2num(cam.target[index], startingChar, pEnd); - assert(result == STR2NUM_ERROR::SUCCESS); - startingChar = pEnd + 1; - ++index; - } while (*pEnd != ']'); - } if (strncmp(readLine, PKE_FILE_CAMERA_TYPE, strlen(PKE_FILE_CAMERA_TYPE)) == 0) { uint64_t prefixLen = strlen(PKE_FILE_CAMERA_TYPE); PkeCameraType_T handle_t; @@ -227,6 +215,18 @@ void ParseCamera(PkeLevel *level, std::ifstream &stream) { cam.view = PkeCameraView{handle_t}; continue; } + if (strstr(readLine, PKE_FILE_CAMERA_INSTANCE_HANDLE)) { + uint64_t prefixLen = strlen(PKE_FILE_CAMERA_INSTANCE_HANDLE); + STR2NUM_ERROR result = str2num(instanceHandle.hash, readLine + prefixLen); + assert(result == STR2NUM_ERROR::SUCCESS); + continue; + } + if (strstr(readLine, PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE)) { + uint64_t prefixLen = strlen(PKE_FILE_CAMERA_TARGET_INSTANCE_HANDLE); + STR2NUM_ERROR result = str2num(targetInstanceHandle.hash, readLine + prefixLen); + assert(result == STR2NUM_ERROR::SUCCESS); + continue; + } if (strncmp(readLine, PKE_FILE_CAMERA_IS_PRIMARY, strlen(PKE_FILE_CAMERA_IS_PRIMARY)) == 0) { uint64_t prefixLen = strlen(PKE_FILE_CAMERA_IS_PRIMARY); uint8_t isPrimary; @@ -240,31 +240,53 @@ void ParseCamera(PkeLevel *level, std::ifstream &stream) { void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) { CompInstance comp{}; - InstPos instPos{}; - instPos.posRot = btTransform{}; - instPos.posRot.setIdentity(); - instPos.scale = btVector3(1, 1, 1); - instPos.mass = 1.f; + InstMapping mapping { + .origHandle = InstanceHandle_MAX, + .newInstance = { + .scale = btVector3(1.f, 1.f, 1.f), + .mass = 1.f, + }, + }; + mapping.newInstance.posRot.setIdentity(); comp.collisionCallback.name[0] = '\0'; NULL_CHAR_ARR(entTypeCode, 21); while (stream.getline(readLine, readLineLength)) { if (strstr(PKE_FILE_OBJ_END, readLine)) { - if (entTypeCode[0] == '\0') { + EntityType *etPtr = nullptr; + bool skipEntCreate = false; + if (strlen(entTypeCode) > 1) { + etPtr = EntityType_FindByTypeCode(entTypeCode); + if (etPtr == nullptr) { + fprintf(stdout, "[Game::ParseInstance] Unknown EntityTypeCode: \"%s\"\n", entTypeCode); + break; + } + } else if (strlen(entTypeCode) == 1) { + // handle internally + if (entTypeCode[0] == PKE_FILE_INSTANCE_SPECIAL_ENTITY_TYPE_CODE_CAMERA) { + skipEntCreate = true; + } + } else { fprintf(stdout, "[Game::ParseInstance] Failed to create instance from save file. No EntTypeCode present.\n"); break; } - auto *etPtr = EntityType_FindByTypeCode(entTypeCode); - if (etPtr == nullptr) { - fprintf(stdout, "[Game::ParseInstance] Failed to create instance from save file. Unknown EntityTypeCode: \"%s\"\n", entTypeCode); - break; - } - if (etPtr->createInstanceCallback.func != nullptr) { - reinterpret_cast<void(*)()>(etPtr->createInstanceCallback.func)(); - } else { - EntityType_CreateGenericInstance(etPtr, parentEntity, &comp, &instPos); - fprintf(stdout ,"[Game::ParseInstance] No callback func to create instance."); + if (skipEntCreate == false) { + if (etPtr != nullptr && etPtr->createInstanceCallback.func != nullptr) { + typedef Entity_Base *CreateInst(); + mapping.newEnt = reinterpret_cast<CreateInst*>(etPtr->createInstanceCallback.func)(); + } else { + mapping.newEnt = EntityType_CreateGenericInstance(etPtr, parentEntity, &comp, &mapping.newInstance); + fprintf(stdout ,"[Game::ParseInstance] No callback func to create instance."); + } } + if (mapping.newEnt != nullptr) { + // TODO this is messy + PkeArray<CompInstance *> instances{}; + ECS_GetInstances(mapping.newEnt, instances); + assert(instances.next > 0); + mapping.newInst = instances.data[0]; + } + PkeArray_Add(&loadFileInstanceMappings, mapping); break; } if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_HANDLE)) { @@ -273,6 +295,12 @@ void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) { assert(result == STR2NUM_ERROR::SUCCESS); continue; } + if (strstr(readLine, PKE_FILE_INSTANCE_HANDLE)) { + uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_HANDLE); + STR2NUM_ERROR result = str2num(mapping.origHandle.hash, readLine + prefixLen); + assert(result == STR2NUM_ERROR::SUCCESS); + continue; + } if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_TYPE_CODE)) { uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_ENTITY_TYPE_CODE); strncpy(entTypeCode, readLine + prefixLen, 21); @@ -292,7 +320,7 @@ void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) { startingChar = pEnd + 1; ++index; } while (*pEnd != ']'); - instPos.posRot.setOrigin(pos); + mapping.newInstance.posRot.setOrigin(pos); continue; } if (strstr(readLine, PKE_FILE_INSTANCE_POS_ROT)) { @@ -309,7 +337,7 @@ void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) { startingChar = pEnd + 1; ++index; } while (*pEnd != ']'); - instPos.posRot.setRotation(rot); + mapping.newInstance.posRot.setRotation(rot); continue; } if (strstr(readLine, PKE_FILE_INSTANCE_POS_SCALE)) { @@ -320,7 +348,7 @@ void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) { long index = 0; do { assert(index < 3); - STR2NUM_ERROR result = str2num(instPos.scale[index], startingChar, pEnd); + STR2NUM_ERROR result = str2num(mapping.newInstance.scale[index], startingChar, pEnd); assert(result == STR2NUM_ERROR::SUCCESS); startingChar = pEnd + 1; ++index; @@ -329,7 +357,7 @@ void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) { } if (strstr(readLine, PKE_FILE_INSTANCE_PHYSICS_MASS)) { uint64_t prefixLen = strlen(PKE_FILE_INSTANCE_PHYSICS_MASS); - STR2NUM_ERROR result = str2num(instPos.mass, readLine + prefixLen); + STR2NUM_ERROR result = str2num(mapping.newInstance.mass, readLine + prefixLen); assert(result == STR2NUM_ERROR::SUCCESS); continue; } @@ -366,20 +394,6 @@ void Game_SaveSceneFile(const char *sceneFilePath) { stream << PKE_FILE_VERSION << std::endl; stream << "" << std::endl; - int64_t cameraBucketCount = PkeCamera_GetBucketCount(); - for (long b = 0; b < cameraBucketCount; ++b) { - int64_t count; - auto *cameras = PkeCamera_GetCameras(b, count); - for (long i = 0; i < count; ++i) { - const auto &cam = cameras[i]; - if (cam.handle == CameraHandle_MAX) - continue; - stream << PKE_FILE_OBJ_CAMERA << std::endl; - SerializeCamera(stream, cam); - stream << PKE_FILE_OBJ_END << std::endl; - } - } - int64_t instanceBucketCount = ECS_GetInstances_BucketCount(); for (long b = 0; b < instanceBucketCount; ++b) { uint64_t count; @@ -388,23 +402,26 @@ void Game_SaveSceneFile(const char *sceneFilePath) { const auto &instance = instances[i]; if (instance.entHandle == EntityHandle_MAX) continue; - /* 2024-01-16 - JCB - TODO Checking the GRBinds is currently - * set so that we don't serialize cameras. There's probably - * a better way to do this - or cameras should be refactored - * to rely on the instance position? - * I expect this to become an issue later, but I'm not aware - * of any use-cases at the moment. Leaving this as-is until - * we know what those use-cases are so we can write a valid - * story to handle the task. - */ - if (instance.grBindsHandle == GrBindsHandle_MAX) - continue; stream << PKE_FILE_OBJ_INSTANCE << std::endl; SerializeInstance(stream, instance); stream << PKE_FILE_OBJ_END << std::endl; } } + int64_t cameraBucketCount = PkeCamera_GetBucketCount(); + for (long b = 0; b < cameraBucketCount; ++b) { + int64_t count; + auto *cameras = PkeCamera_GetCameras(b, count); + for (long i = 0; i < count; ++i) { + const auto &cam = cameras[i]; + if (cam.handle == CameraHandle_MAX) + continue; + stream << PKE_FILE_OBJ_CAMERA << std::endl; + SerializeCamera(stream, cam); + stream << PKE_FILE_OBJ_END << std::endl; + } + } + stream << PKE_FILE_END << std::endl; } catch (...) { @@ -448,17 +465,18 @@ void Game_LoadSceneFile(PkeLevel *level, const char *sceneFilePath) { memset(readLine, '\0', readLineLength); while (f.getline(readLine, readLineLength)) { - if (strcmp(PKE_FILE_OBJ_CAMERA, readLine) == 0) { - ParseCamera(level, f); - continue; - } if (strcmp(PKE_FILE_OBJ_INSTANCE, readLine) == 0) { ParseInstance(level, f); continue; } + if (strcmp(PKE_FILE_OBJ_CAMERA, readLine) == 0) { + ParseCamera(level, f); + continue; + } } f.close(); + PkeArray_SoftReset(&loadFileInstanceMappings); } const uint64_t consoleBufferCount = 30; @@ -665,12 +683,12 @@ void Game_Main(PKEWindowProperties windowProps, const char *executablePath) { Event_Teardown(); EntityType_Teardown(); PkeInput_Teardown(); + PkeCamera_Teardown(); Physics_Teardown(); ECS_Teardown(); - PkeCamera_Teardown(); + DestroyWindow(); AM_DebugPrint(); AM_Teardown(); - DestroyWindow(); PkeThreads_Teardown(); Pke_DebugPrint(); fprintf(stdout, "Game_Main Exiting\n"); diff --git a/src/plugin-types.hpp b/src/plugin-types.hpp new file mode 100644 index 0000000..22f9707 --- /dev/null +++ b/src/plugin-types.hpp @@ -0,0 +1,25 @@ +#ifndef PKE_PLUGIN_TYPES_HPP +#define PKE_PLUGIN_TYPES_HPP + +#include <cstdint> + +struct PKEPluginInterface { + // for internal use only + void *pluginHandle = nullptr; + void (*OnInit)() = nullptr; + void (*OnTick)(double delta) = nullptr; + void (*OnTeardown)() = nullptr; + void (*OnImGuiRender)() = nullptr; +}; + +constexpr int64_t CallbackSignatureLength = 16; +using CallbackSignature = char[CallbackSignatureLength]; + +struct PkeCallback { + // the 16 char signature(name) of a function + CallbackSignature name = {'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'}; + // the address of the function to call - populated on startup + void *func = nullptr; +}; + +#endif /* PKE_PLUGIN_TYPES_HPP */ diff --git a/src/plugins.hpp b/src/plugins.hpp index a474750..697fbf1 100644 --- a/src/plugins.hpp +++ b/src/plugins.hpp @@ -3,24 +3,7 @@ #include "array.hpp" #include "dynamic-array.hpp" - -struct PKEPluginInterface { - // for internal use only - void *pluginHandle = nullptr; - void (*OnInit)() = nullptr; - void (*OnTick)(double delta) = nullptr; - void (*OnTeardown)() = nullptr; - void (*OnImGuiRender)() = nullptr; -}; - -constexpr int64_t CallbackSignatureLength = 16; -using CallbackSignature = char[CallbackSignatureLength]; -struct PkeCallback { - // the 16 char signature(name) of a function - CallbackSignature name = {'\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0'}; - // the address of the function to call - populated on startup - void *func = nullptr; -}; +#include "plugin-types.hpp" extern DynArray<PKEPluginInterface> LoadedPkePlugins; extern PkeArray<PkeCallback> pkePluginCallbacks; diff --git a/src/project.cpp b/src/project.cpp index 0f08859..4412522 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -1,6 +1,7 @@ #include "project.hpp" +#include "plugins.hpp" #include "entities.hpp" #include "helpers.hpp" diff --git a/src/window.cpp b/src/window.cpp index 1d27664..db817e6 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1,3 +1,4 @@ +#include "math-helpers.hpp" #include "static/missing-texture.hpp" #define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_VULKAN @@ -907,14 +908,27 @@ void UpdatePresentDescriptorSets() { } void UpdateCamera() { + if (ActiveCamera->stale == PkeCameraStaleFlags{0}) return; + glm::vec3 gPos; + glm::quat gRot; + btTransform trfm; + ActiveCamera->phys.inst->bt.motionState->getWorldTransform(trfm); + BulletToGlm(trfm.getOrigin(), gPos); + BulletToGlm(trfm.getRotation(), gRot); if (bool(ActiveCamera->stale & PKE_CAMERA_STALE_POS)) { - UBO.model = glm::translate(glm::mat4(1.f), ActiveCamera->pos); + UBO.model = glm::translate(glm::mat4(1.f), gPos); } if (bool(ActiveCamera->stale & PKE_CAMERA_STALE_ROT)) { if (bool(ActiveCamera->view == PKE_CAMERA_VIEW_FREE)) { - UBO.view = glm::mat4_cast(ActiveCamera->rot); + UBO.view = glm::mat4_cast(gRot); } else if (bool(ActiveCamera->view == PKE_CAMERA_VIEW_TARGET)) { - UBO.view = glm::lookAt(glm::vec3(0), ActiveCamera->pos - ActiveCamera->target, glm::vec3(0.f, 1.f, 0.f)); + glm::vec3 gTargetPos{0.f, 0.f, 0.f}; + if (ActiveCamera->phys.targetInst != nullptr && ActiveCamera->phys.targetInst != CAFE_BABE(CompInstance)) { + btTransform targetTrfm; + ActiveCamera->phys.targetInst->bt.motionState->getWorldTransform(targetTrfm); + BulletToGlm(trfm.getOrigin(), gTargetPos); + } + UBO.view = glm::lookAt(glm::vec3(0), gPos - gTargetPos, glm::vec3(0.f, 1.f, 0.f)); } } if (bool(ActiveCamera->stale & PKE_CAMERA_STALE_PERSPECTIVE)) { |
