summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-05-28 17:40:45 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-05-28 17:40:45 -0400
commitdfd1776e1af9b8da86005a294e4b086fbe6e7f4e (patch)
tree7271607e2a56343200df38341043584771350d1a
parent3a81898eed7eed7b220d280a8acc9c9cdceac7c0 (diff)
pke: camera: replace BucketContainer -> pk_bkt_arr
-rw-r--r--editor/editor.cpp111
-rw-r--r--src/camera.cpp111
-rw-r--r--src/camera.hpp7
-rw-r--r--src/serialization.cpp18
-rw-r--r--tests/pke-test-serialization.cpp3
5 files changed, 119 insertions, 131 deletions
diff --git a/editor/editor.cpp b/editor/editor.cpp
index 9e2f938..38e2828 100644
--- a/editor/editor.cpp
+++ b/editor/editor.cpp
@@ -1105,6 +1105,8 @@ void RecordImGuiAssets() {
}
void RecordImGuiCameras() {
+ using CamIterFn = pk_tmpln_1<void, PkeCamera*, void*>;
+ static CamIterFn cam_iter_cb{};
CompInstance *active_inst = nullptr;
if (!ImGui::Begin("Cameras")) {
ImGui::End();
@@ -1145,63 +1147,62 @@ void RecordImGuiCameras() {
ImGui::TableSetupColumn("Controls");
ImGui::TableHeadersRow();
- pk_handle_bucket_index_T cameraBucketCount = PkeCamera_GetBucketCount();
- for (pk_handle_bucket_index_T b = 0; b < cameraBucketCount; ++b) {
- pk_handle_item_index_T count;
- auto *cameras = PkeCamera_GetCameras(b, count);
- ImGui::PushID(b);
- for (pk_handle_item_index_T i = 0; i < count; ++i) {
- const auto &cam = cameras[i];
- if (cam.handle == CameraHandle_MAX)
- continue;
- ImGui::PushID(i);
- ImGui::TableNextRow();
- ImGui::TableSetColumnIndex(0);
- ImGui::BeginDisabled(selectedCamera == cam.handle);
- if (ImGui::Button("Show")) {
- selectedCamera = cam.camHandle;
- ActiveCamera = const_cast<PkeCamera *>(&cam);
- ActiveCamera->stale = PKE_CAMERA_STALE_ALL;
- }
- ImGui::SameLine();
- if (ImGui::Button("Select")) {
- selectedEntity = ECS_GetInstance(cam.phys.instHandle);
- }
- ImGui::EndDisabled();
- ImGui::TableSetColumnIndex(1);
- ImGui::Text("0x%08X 0x%08X", cam.handle.bucketIndex, cam.handle.itemIndex);
- ImGui::TableSetColumnIndex(2);
- ImGui::Text(pk_uuid_printf_format, pk_uuid_printf_var(cam.phys.target_inst_uuid));
- ImGui::TableSetColumnIndex(3);
- ImGui::Text("%hhu", (unsigned char)cam.type);
- ImGui::TableSetColumnIndex(4);
- ImGui::Text("%hhu", (unsigned char)cam.view);
- ImGui::TableSetColumnIndex(5);
- ImGui::Text("%hhu", (unsigned char)cam.stale);
- ImGui::TableSetColumnIndex(6);
- ImGui::Text("%i", cam.isPrimary);
- ImGui::TableSetColumnIndex(7);
- if (ImGui::Button("Update Position")) {
- InstPos instPos{};
- instPos.mass = 1.f;
- if (active_inst == nullptr) {
- NullCameraInstance.bt.motionState->getWorldTransform(instPos.posRot);
- instPos.scale = NullCameraInstance.bt.rigidBody->getCollisionShape()->getLocalScaling();
- } else {
- active_inst->bt.motionState->getWorldTransform(instPos.posRot);
- instPos.scale = active_inst->bt.rigidBody->getCollisionShape()->getLocalScaling();
- }
- CompInstance *camInst = ECS_GetInstance(cam.phys.instHandle);
- ECS_UpdateInstance(camInst, instPos, true);
- }
- ImGui::SameLine();
- if (ImGui::Button("Make Primary")) {
- PkeCamera_SetPrimary(cam.camHandle);
+ size_t cam_counter = 0;
+ cam_iter_cb.func = [&cam_counter, &active_inst](PkeCamera *cam_ptr) {
+ const auto &cam = *cam_ptr;
+ /* 2025-05-28 JCB delete me if you see me, i wasn't needed
+ if (cam.camHandle.b == CameraHandle_MAX.b && cam.camHandle.i == CameraHandle_MAX.i) {
+ return;
+ }
+ */
+ ImGui::PushID(cam_counter);
+ ImGui::TableNextRow();
+ ImGui::TableSetColumnIndex(0);
+ ImGui::BeginDisabled(selectedCamera.b == cam.camHandle.b && selectedCamera.i == cam.camHandle.i);
+ if (ImGui::Button("Show")) {
+ selectedCamera = cam.camHandle;
+ ActiveCamera = const_cast<PkeCamera *>(&cam);
+ ActiveCamera->stale = PKE_CAMERA_STALE_ALL;
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("Select")) {
+ selectedEntity = ECS_GetInstance(cam.phys.instHandle);
+ }
+ ImGui::EndDisabled();
+ ImGui::TableSetColumnIndex(1);
+ ImGui::Text("0x%08X 0x%08X", cam.handle.bucketIndex, cam.handle.itemIndex);
+ ImGui::TableSetColumnIndex(2);
+ ImGui::Text(pk_uuid_printf_format, pk_uuid_printf_var(cam.phys.target_inst_uuid));
+ ImGui::TableSetColumnIndex(3);
+ ImGui::Text("%hhu", (unsigned char)cam.type);
+ ImGui::TableSetColumnIndex(4);
+ ImGui::Text("%hhu", (unsigned char)cam.view);
+ ImGui::TableSetColumnIndex(5);
+ ImGui::Text("%hhu", (unsigned char)cam.stale);
+ ImGui::TableSetColumnIndex(6);
+ ImGui::Text("%i", cam.isPrimary);
+ ImGui::TableSetColumnIndex(7);
+ if (ImGui::Button("Update Position")) {
+ InstPos instPos{};
+ instPos.mass = 1.f;
+ if (active_inst == nullptr) {
+ NullCameraInstance.bt.motionState->getWorldTransform(instPos.posRot);
+ instPos.scale = NullCameraInstance.bt.rigidBody->getCollisionShape()->getLocalScaling();
+ } else {
+ active_inst->bt.motionState->getWorldTransform(instPos.posRot);
+ instPos.scale = active_inst->bt.rigidBody->getCollisionShape()->getLocalScaling();
}
- ImGui::PopID();
+ CompInstance *camInst = ECS_GetInstance(cam.phys.instHandle);
+ ECS_UpdateInstance(camInst, instPos, true);
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("Make Primary")) {
+ PkeCamera_SetPrimary(cam.camHandle);
}
ImGui::PopID();
- }
+ cam_counter += 1;
+ };
+ pk_bkt_arr_iterate(&PkeCamera_GetPkBktArr(), &CamIterFn::invoke, &cam_iter_cb);
ImGui::EndTable();
}
@@ -1236,8 +1237,6 @@ void RecordImGuiCameras() {
cam->view = PKE_CAMERA_VIEW_FREE;
}
ImGui::EndDisabled();
-
-
}
}
diff --git a/src/camera.cpp b/src/camera.cpp
index e734994..14f6694 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -6,14 +6,14 @@
#include "ecs.hpp"
#include "math-helpers.hpp"
#include "physics.hpp"
+#include "pk.h"
#include "vendor-glm-include.hpp"
PkeCamera NullCamera {};
CompInstance NullCameraInstance{};
PkeCamera *ActiveCamera = &NullCamera;
-const pk_handle_item_index_T MAX_CAMERAS_PER_BUCKET = 32;
-BucketContainer<PkeCamera, CameraHandle> Camera_BucketContainer{};
+pk_bkt_arr_t<PkeCamera> bktc_cameras{};
btSphereShape CameraShape{1.f};
@@ -46,10 +46,10 @@ PkeCamera &PkeCamera_Register_Inner(PkeCamera &cam, CompInstance &inst, const In
}
PkeCamera &PkeCamera_Register(pk_uuid uuid, const InstPos &instPos) {
- CameraHandle cameraHandle{Buckets_NewHandle(Camera_BucketContainer)};
+ CameraHandle cameraHandle{pk_bkt_arr_new_handle(&bktc_cameras)};
CompInstance *inst;
- auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
+ auto &cam = bktc_cameras[cameraHandle];
new (&cam) PkeCamera{};
cam.uuid = uuid;
@@ -62,26 +62,27 @@ PkeCamera &PkeCamera_Register(pk_uuid uuid, const InstPos &instPos) {
PkeCamera *PkeCamera_Get(CameraHandle cameraHandle) {
assert(cameraHandle != CameraHandle_MAX);
- return &Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
+ return &bktc_cameras[cameraHandle];
}
PkeCamera *PkeCamera_Get(EntityHandle handle) {
- assert(handle != EntityHandle_MAX);
- for (pk_handle_bucket_index_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 (pk_handle_item_index_T i = 0; i < itemCount; ++i) {
- auto &cam = bkt[i];
- if (cam.handle == handle)
- return &Camera_BucketContainer.buckets[cam.camHandle.bucketIndex][cam.camHandle.itemIndex];
- }
+ using CamFindFn = pk_tmpln_2<bool, const PkeCamera*, const PkeCamera*, const void*, const void*>;
+ CamFindFn cam_find_cb{};
+
+ cam_find_cb.func = [handle](const PkeCamera *user_obj_data, const PkeCamera *arr_obj_data) {
+ (void)user_obj_data;
+ return arr_obj_data->handle == handle;
+ };
+ pk_bkt_arr_handle cam_handle = pk_bkt_arr_find_first_handle(&bktc_cameras, &CamFindFn::invoke, &cam_find_cb, NULL);
+ if (cam_handle == CameraHandle_MAX) {
+ return nullptr;
}
- return nullptr;
+ return &bktc_cameras[cam_handle];
}
void PkeCamera_TargetInstance(CameraHandle cameraHandle, CompInstance *inst) {
assert(cameraHandle != CameraHandle_MAX);
- auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
+ auto &cam = bktc_cameras[cameraHandle];
CompInstance *selfInstance = ECS_GetInstance(cam.phys.instHandle);
if (cam.phys.constraint != nullptr && cam.phys.constraint != CAFE_BABE(btTypedConstraint)) {
@@ -131,7 +132,7 @@ void PkeCamera_TargetInstance(CameraHandle cameraHandle, CompInstance *inst) {
void PkeCamera_UntargetInstance(CameraHandle cameraHandle) {
assert(cameraHandle != CameraHandle_MAX);
- auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
+ auto &cam = bktc_cameras[cameraHandle];
BtDynamicsWorld->removeConstraint(cam.phys.constraint);
pk_delete<btTypedConstraint>(cam.phys.constraint, MemBkt_Bullet);
cam.phys.constraint = CAFE_BABE(btTypedConstraint);
@@ -140,23 +141,22 @@ void PkeCamera_UntargetInstance(CameraHandle cameraHandle) {
void PkeCamera_SetPrimary(CameraHandle cameraHandle) {
assert(cameraHandle != CameraHandle_MAX);
- auto &primaryCam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
- for (pk_handle_bucket_index_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 (pk_handle_item_index_T i = 0; i < itemCount; ++i) {
- auto *cam = &bkt[i];
- if (cam->parentHandle != primaryCam.parentHandle) {
- continue;
- }
- cam->isPrimary = cam->camHandle == cameraHandle;
- }
- }
+ auto check_stale = [](void *user_data, void *cam_ptr) {
+ CameraHandle handle = *reinterpret_cast<CameraHandle*>(user_data);
+ auto &cam = *reinterpret_cast<PkeCamera*>(cam_ptr);
+ // TODO 2025-05-28 JCB
+ // There was some speculative scene filtering happening here.
+ // I removed it because it was comparing entity parents and I don't
+ // think that is accurate.
+ // Instead, should be a per-viewport or per-world check?
+ cam.isPrimary = (cam.camHandle == handle);
+ };
+ pk_bkt_arr_iterate(&bktc_cameras, check_stale, &cameraHandle);
}
void PkeCamera_Destroy(CameraHandle cameraHandle) {
assert(cameraHandle != CameraHandle_MAX);
- auto *camPtr = &Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
+ auto *camPtr = &bktc_cameras[cameraHandle];
auto &cam = *camPtr;
if (cam.phys.constraint != nullptr && cam.phys.constraint != CAFE_BABE(btTypedConstraint)) {
@@ -175,21 +175,12 @@ void PkeCamera_Destroy(CameraHandle cameraHandle) {
cam.phys.constraint = CAFE_BABE(btTypedConstraint);
}
-int64_t PkeCamera_GetBucketCount() {
- return Camera_BucketContainer.pkeHandle.bucketIndex + 1;
-}
-
-PkeCamera *PkeCamera_GetCameras(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &count) {
- if (Camera_BucketContainer.pkeHandle.bucketIndex == bucketIndex) {
- count = Camera_BucketContainer.pkeHandle.itemIndex;
- } else {
- count = MAX_CAMERAS_PER_BUCKET;
- }
- return Camera_BucketContainer.buckets[bucketIndex];
+pk_bkt_arr &PkeCamera_GetPkBktArr() {
+ return bktc_cameras;
}
void PkeCamera_Init() {
- Buckets_Init(Camera_BucketContainer, MAX_CAMERAS_PER_BUCKET);
+ new (&bktc_cameras) pk_bkt_arr_t<PkeCamera>{};
NullCamera.type = PKE_CAMERA_TYPE_ORTHOGONAL;
NullCamera.view = PKE_CAMERA_VIEW_TARGET;
NullCamera.stale = PKE_CAMERA_STALE_ALL;
@@ -207,7 +198,7 @@ void PkeCamera_Teardown() {
pk_delete<btRigidBody>(NullCameraInstance.bt.rigidBody, MemBkt_Bullet);
NullCameraInstance.bt.motionState = CAFE_BABE(btDefaultMotionState);
NullCameraInstance.bt.rigidBody = CAFE_BABE(btRigidBody);
- Buckets_Destroy(Camera_BucketContainer);
+ bktc_cameras.~pk_bkt_arr_t<PkeCamera>();
}
void PkeCamera_Tick(double delta) {
@@ -222,23 +213,25 @@ void PkeCamera_Tick(double delta) {
* See the camera serializer for more.
*/
(void)delta;
- for (pk_handle_bucket_index_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 (pk_handle_item_index_T i = 0; i < itemCount; ++i) {
- auto &cam = bkt[i];
- if (cam.handle == EntityHandle_MAX || cam.phys.instHandle == InstanceHandle_MAX) {
- continue;
- }
- CompInstance *inst = ECS_GetInstance(cam.phys.instHandle);
- assert(inst != nullptr);
- if (inst->isNeedingUpdated == true) {
- cam.stale = cam.stale | PKE_CAMERA_STALE_POSROT;
- inst->isNeedingUpdated = false;
- }
- if (cam.phys.target_inst_uuid == pk_uuid_zed) continue;
+ auto check_stale = [](void *user_data, void *cam_ptr) {
+ (void)user_data;
+ auto &cam = *reinterpret_cast<PkeCamera*>(cam_ptr);
+ /* 2025-05-28 JCB - if you see me, delete me, i wasn't needed
+ if (cam.handle == EntityHandle_MAX || cam.phys.instHandle == InstanceHandle_MAX) {
+ return;
+ }
+ */
+ CompInstance *inst = ECS_GetInstance(cam.phys.instHandle);
+ assert(inst != nullptr);
+ if (inst->isNeedingUpdated == true) {
cam.stale = cam.stale | PKE_CAMERA_STALE_POSROT;
+ inst->isNeedingUpdated = false;
}
- }
+ if (cam.phys.target_inst_uuid == pk_uuid_zed) {
+ return;
+ }
+ cam.stale = cam.stale | PKE_CAMERA_STALE_POSROT;
+ };
+ pk_bkt_arr_iterate(&bktc_cameras, check_stale, NULL);
}
diff --git a/src/camera.hpp b/src/camera.hpp
index cef3c12..9486c84 100644
--- a/src/camera.hpp
+++ b/src/camera.hpp
@@ -10,9 +10,9 @@ TypeSafeInt_constexpr(PkeCameraType, uint8_t, 0xFF);
TypeSafeInt_constexpr(PkeCameraView, uint8_t, 0xFF);
TypeSafeInt_constexpr(PkeCameraStaleFlags, uint8_t, 0xFF);
-struct CameraHandle : public pk_handle {};
+struct CameraHandle : public pk_bkt_arr_handle {};
-constexpr CameraHandle CameraHandle_MAX = CameraHandle{ pk_handle_MAX_constexpr };
+constexpr CameraHandle CameraHandle_MAX = CameraHandle{ PK_BKT_ARR_HANDLE_B_MAX, PK_BKT_ARR_HANDLE_I_MAX };
constexpr PkeCameraType PKE_CAMERA_TYPE_PERSPECTIVE = PkeCameraType{1 << 0};
constexpr PkeCameraType PKE_CAMERA_TYPE_ORTHOGONAL = PkeCameraType{1 << 1};
@@ -49,8 +49,7 @@ PkeCamera *PkeCamera_Get(CameraHandle handle);
PkeCamera *PkeCamera_Get(EntityHandle handle);
void PkeCamera_TargetInstance(CameraHandle cameraHandle, CompInstance *inst);
void PkeCamera_UntargetInstance(CameraHandle cameraHandle);
-int64_t PkeCamera_GetBucketCount();
-PkeCamera *PkeCamera_GetCameras(pk_handle_bucket_index_T bucketIndex, pk_handle_item_index_T &count);
+pk_bkt_arr &PkeCamera_GetPkBktArr();
void PkeCamera_SetPrimary(CameraHandle handle);
void PkeCamera_Destroy(CameraHandle handle);
void PkeCamera_Teardown();
diff --git a/src/serialization.cpp b/src/serialization.cpp
index 66a0f4b..b7691fd 100644
--- a/src/serialization.cpp
+++ b/src/serialization.cpp
@@ -64,6 +64,8 @@ void pke_deserialize_project_from_stream(std::istream &i, srlztn_deserialize_hel
}
void pke_serialize_scene(srlztn_serialize_helper *h) {
+ using CamIterFn = pk_tmpln_1<void, PkeCamera*, void*>;
+ CamIterFn cam_iter_cb{};
FontTypeIndex font_type_count;
FontType *fonts = FontType_GetFonts(font_type_count);
for (FontTypeIndex_T b = 0; b < (FontTypeIndex_T)font_type_count; ++b) {
@@ -95,17 +97,13 @@ void pke_serialize_scene(srlztn_serialize_helper *h) {
}
}
- pk_handle_bucket_index_T cameraBucketCount = PkeCamera_GetBucketCount();
- for (pk_handle_bucket_index_T b = 0; b < cameraBucketCount; ++b) {
- pk_handle_item_index_T count;
- auto *cameras = PkeCamera_GetCameras(b, count);
- for (pk_handle_item_index_T i = 0; i < count; ++i) {
- const auto &cam = cameras[i];
- if (cam.handle == CameraHandle_MAX)
- continue;
- pke_serialize_camera(h, &cam);
+ cam_iter_cb.func = [&h](PkeCamera *cam_ptr) {
+ if (cam_ptr->camHandle == CameraHandle_MAX) {
+ return;
}
- }
+ pke_serialize_camera(h, cam_ptr);
+ };
+ pk_bkt_arr_iterate(&PkeCamera_GetPkBktArr(), &CamIterFn::invoke, &cam_iter_cb);
}
void pke_deserialize_scene(srlztn_deserialize_helper *h) {
uint32_t i;
diff --git a/tests/pke-test-serialization.cpp b/tests/pke-test-serialization.cpp
index 724ccae..536d6c1 100644
--- a/tests/pke-test-serialization.cpp
+++ b/tests/pke-test-serialization.cpp
@@ -366,8 +366,7 @@ int pke_test_deserialization_102() {
pke_deserialize_scene(h);
- pk_handle_item_index_T item_index;
- PkeCamera *des_cam = &PkeCamera_GetCameras(0, item_index)[0];
+ PkeCamera *des_cam = PkeCamera_Get(CameraHandle{0,0});
// 57
PKE_TEST_ASSERT(des_cam != nullptr, err_index);
PKE_TEST_ASSERT(des_cam->uuid == uuid_n[2], err_index);