diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-10 19:24:12 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2024-01-10 19:24:12 -0500 |
| commit | f07294ca65143fac8b1b426d1854212403721226 (patch) | |
| tree | 2edeb8f2c9beea1cbb065f69910d53957ebda0ce /src | |
| parent | 294c85f91ac5b2ff9e4ad3d99588ed0d1a72e6b7 (diff) | |
checkpoint - handle breaking ECS changes - compiles
Diffstat (limited to 'src')
| -rw-r--r-- | src/ecs.cpp | 78 | ||||
| -rw-r--r-- | src/ecs.hpp | 6 | ||||
| -rw-r--r-- | src/entities.cpp | 286 | ||||
| -rw-r--r-- | src/entities.hpp | 26 | ||||
| -rw-r--r-- | src/game.cpp | 75 | ||||
| -rw-r--r-- | src/game.hpp | 2 | ||||
| -rw-r--r-- | src/level-types.hpp | 6 | ||||
| -rw-r--r-- | src/level.cpp | 28 | ||||
| -rw-r--r-- | src/level.hpp | 1 | ||||
| -rw-r--r-- | src/physics.cpp | 10 | ||||
| -rw-r--r-- | src/project.cpp | 77 |
11 files changed, 341 insertions, 254 deletions
diff --git a/src/ecs.cpp b/src/ecs.cpp index 02f00d3..f499835 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -1,6 +1,7 @@ #include "ecs.hpp" +#include "array.hpp" #include "bucketed-array.hpp" #include "game-settings.hpp" #include "math-helpers.hpp" @@ -39,7 +40,8 @@ DynArray<Entity_Base *> entitiesYetToBeRemoved{0, nullptr}; DynArray<Entity_Base *> EntitiesWithExcessInstances{16}; -BucketContainer<Entity_Base *, GrBindsHandle> Entities_BucketContainer{}; +BucketContainer<Entity_Base, PkeHandle> Entities_GenericsBC{}; +BucketContainer<Entity_Base *, EntityHandle> Entities_BucketContainer{}; BucketContainer<CompGrBinds, GrBindsHandle> Comp_GrBinds_BucketContainer{}; BucketContainer<CompInstance, InstanceHandle> Comp_Instance_BucketContainer{}; @@ -54,8 +56,14 @@ void ECS_Init() { Buckets_Init(Comp_Instance_BucketContainer, maxBucketItemCount); } +Entity_Base *ECS_CreateGenericEntity() { + PkeHandle newHandle{Buckets_NewHandle(Entities_GenericsBC)}; + return &Entities_GenericsBC.buckets[newHandle.bucketIndex][newHandle.itemIndex]; +} + EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEntity) { assert(entity != nullptr); + assert(entity->handle == EntityHandle_MAX && "Entity already created!"); EntityHandle entityHandle{Buckets_NewHandle(Entities_BucketContainer)}; entity->handle = entityHandle; entity->parentHandle = parentEntity->handle; @@ -63,6 +71,11 @@ EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEntity) { return entityHandle; } +Entity_Base *ECS_GetEntity(EntityHandle handle) { + ValidateHandle(handle, Entities_BucketContainer.pkeHandle, Entities_BucketContainer.limits.itemIndex); + return Entities_BucketContainer.buckets[handle.bucketIndex][handle.itemIndex]; +} + void ECS_MarkForRemoval(Entity_Base *entity) { assert(entity->isMarkedForRemoval == false && "Entity already marked for removal"); entitiesMarkedForRemoval.Push(entity); @@ -327,41 +340,35 @@ void ECS_Tick_Late(double delta) { } } -void ECS_HandleCollision(InstanceHandle lhs, InstanceHandle rhs) { - CompInstance *lhsInst = ECS_GetInstance(lhs); - CompGrBinds *lhsGrBinds = nullptr; - if (lhsInst != nullptr) { - lhsGrBinds = ECS_GetGrBinds(lhsInst->grBindsHandle); - } +void ECS_HandleCollision(CompInstance *lhsInst, CompInstance *rhsInst) { + assert(lhsInst != nullptr); + assert(rhsInst != nullptr); - CompInstance *rhsInst = ECS_GetInstance(rhs); - CompGrBinds *rhsGrBinds = nullptr; - if (rhsInst != nullptr) { - rhsGrBinds = ECS_GetGrBinds(rhsInst->grBindsHandle); - } + CompGrBinds *lhsGrBinds = ECS_GetGrBinds(lhsInst->grBindsHandle); + CompGrBinds *rhsGrBinds = ECS_GetGrBinds(rhsInst->grBindsHandle); - void (*lhsColFunc)(InstanceHandle, InstanceHandle) = nullptr; - void (*rhsColFunc)(InstanceHandle, InstanceHandle) = nullptr; + void (*lhsColFunc)(CompInstance*, CompInstance*) = nullptr; + void (*rhsColFunc)(CompInstance*, CompInstance*) = nullptr; if (lhsInst && lhsInst->collisionCallback.func != nullptr) { - lhsColFunc = reinterpret_cast<void (*)(InstanceHandle, InstanceHandle)>(lhsInst->collisionCallback.func); + lhsColFunc = reinterpret_cast<void (*)(CompInstance *, CompInstance *)>(lhsInst->collisionCallback.func); } if (lhsColFunc == nullptr && lhsGrBinds && lhsGrBinds->collisionCallback.func) { - lhsColFunc = reinterpret_cast<void (*)(InstanceHandle, InstanceHandle)>(lhsGrBinds->collisionCallback.func); + lhsColFunc = reinterpret_cast<void (*)(CompInstance *, CompInstance *)>(lhsGrBinds->collisionCallback.func); } if (rhsInst && rhsInst->collisionCallback.func != nullptr) { - rhsColFunc = reinterpret_cast<void (*)(InstanceHandle, InstanceHandle)>(rhsInst->collisionCallback.func); + rhsColFunc = reinterpret_cast<void (*)(CompInstance *, CompInstance *)>(rhsInst->collisionCallback.func); } if (rhsColFunc == nullptr && rhsGrBinds && rhsGrBinds->collisionCallback.func) { - rhsColFunc = reinterpret_cast<void (*)(InstanceHandle, InstanceHandle)>(rhsGrBinds->collisionCallback.func); + rhsColFunc = reinterpret_cast<void (*)(CompInstance *, CompInstance *)>(rhsGrBinds->collisionCallback.func); } if (lhsColFunc) { - lhsColFunc(lhs, rhs); + lhsColFunc(lhsInst, rhsInst); } if (rhsColFunc) { - rhsColFunc(lhs, rhs); + rhsColFunc(lhsInst, rhsInst); } } @@ -383,6 +390,19 @@ CompGrBinds *ECS_GetGrBinds(GrBindsHandle grBindsHandle) { return &Comp_GrBinds_BucketContainer.buckets[grBindsHandle.bucketIndex][grBindsHandle.itemIndex]; } +void ECS_GetGrBinds(Entity_Base *entity, PkeArray<CompGrBinds *> &arr) { + for (PkeHandleBucketIndex_T b = 0; b <= Comp_GrBinds_BucketContainer.pkeHandle.bucketIndex; ++b) { + auto &bkt = Comp_GrBinds_BucketContainer.buckets[b]; + long itemCount = Comp_GrBinds_BucketContainer.pkeHandle.bucketIndex == b ? Comp_GrBinds_BucketContainer.pkeHandle.itemIndex : Comp_GrBinds_BucketContainer.limits.itemIndex; + for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + auto &grBinds = bkt[i]; + if (grBinds.entHandle == entity->handle) { + PkeArray_Add(&arr, &grBinds); + } + } + } +} + uint64_t ECS_GetGrBinds_BucketCount() { return Comp_GrBinds_BucketContainer.pkeHandle.bucketIndex + 1; } @@ -427,6 +447,19 @@ CompInstance *ECS_GetInstance(InstanceHandle instanceHandle ) { return inst; } +void ECS_GetInstances(Entity_Base *entity, PkeArray<CompInstance *> &arr) { + for (PkeHandleBucketIndex_T b = 0; b <= Comp_Instance_BucketContainer.pkeHandle.bucketIndex; ++b) { + auto &bkt = Comp_Instance_BucketContainer.buckets[b]; + long itemCount = Comp_Instance_BucketContainer.pkeHandle.bucketIndex == b ? Comp_Instance_BucketContainer.pkeHandle.itemIndex : Comp_Instance_BucketContainer.limits.itemIndex; + for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + auto &inst = bkt[i]; + if (inst.entHandle == entity->handle) { + PkeArray_Add(&arr, &inst); + } + } + } +} + void ECS_UpdateInstance(CompInstance *instance, const InstPos &instPos, bool overridePhysics) { if (BtDynamicsWorld && overridePhysics) { btVector3 localInertia(0, 0, 0); @@ -460,7 +493,8 @@ void ECS_Teardown() { entitiesYetToBeRemoved.~DynArray(); EntitiesToBeRemoved.~DynArray(); entitiesMarkedForRemoval.~DynArray(); - Buckets_Destroy(Entities_BucketContainer); - Buckets_Destroy(Comp_GrBinds_BucketContainer); Buckets_Destroy(Comp_Instance_BucketContainer); + Buckets_Destroy(Comp_GrBinds_BucketContainer); + Buckets_Destroy(Entities_BucketContainer); + Buckets_Destroy(Entities_GenericsBC); } diff --git a/src/ecs.hpp b/src/ecs.hpp index 567f6df..4ddf232 100644 --- a/src/ecs.hpp +++ b/src/ecs.hpp @@ -1,6 +1,7 @@ #ifndef PKE_ECS_HPP #define PKE_ECS_HPP +#include "array.hpp" #include "dynamic-array.hpp" #include "macros.hpp" #include "memory.hpp" @@ -23,19 +24,22 @@ void ECS_Tick_Early(double delta); void ECS_Tick(double delta); void ECS_Tick_Late(double delta); +Entity_Base *ECS_CreateGenericEntity(); EntityHandle ECS_CreateEntity(Entity_Base *entity, Entity_Base *parentEnt = nullptr); Entity_Base *ECS_GetEntity(EntityHandle handle); void ECS_MarkForRemoval(Entity_Base *entity); -void ECS_HandleCollision(Entity_Base *lhs, Entity_Base *rhs); +void ECS_HandleCollision(CompInstance *lhs, CompInstance *rhs); CompGrBinds *ECS_CreateGrBinds(Entity_Base *); CompGrBinds *ECS_GetGrBinds(GrBindsHandle grBindsHandle); +void ECS_GetGrBinds(Entity_Base *entity, PkeArray<CompGrBinds *> &arr); uint64_t ECS_GetGrBinds_BucketCount(); CompGrBinds *ECS_GetGrBinds(uint64_t bucketIndex, uint64_t &itemCount); CompInstance *ECS_CreateInstance(Entity_Base *entity, CompGrBinds *entityTypeGrBinds); CompInstance *ECS_GetInstance(InstanceHandle instanceHandle); +void ECS_GetInstances(Entity_Base *entity, PkeArray<CompInstance *> &arr); void ECS_UpdateInstance(CompInstance *instance, const InstPos &instPos, bool overridePhysics = false); uint64_t ECS_GetInstances_BucketCount(); CompInstance *ECS_GetInstances(uint64_t bucketIndex, uint64_t &itemCount); diff --git a/src/entities.cpp b/src/entities.cpp index 91c94d8..bd24830 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -1,7 +1,10 @@ #include "entities.hpp" +#include "bucketed-array.hpp" #include "ecs.hpp" +#include "game-settings.hpp" +#include "level.hpp" #include "math-helpers.hpp" #include "memory.hpp" #include "physics.hpp" @@ -14,7 +17,8 @@ #include <type_traits> #include <vulkan/vulkan_core.h> -DynArray<EntityType> GlobalEntityTypes{16}; +BucketContainer<EntityType> EntityType_BC{}; + struct EntToTeardown { EntityHandle handle = EntityHandle_MAX; CompGrBinds *grBinds[1] = {nullptr}; @@ -23,37 +27,85 @@ struct EntToTeardown { DynArray<EntToTeardown> EntityTypesToTeardown{16}; void EntityType_Init() { - long entityTypeCount = GlobalEntityTypes.Count(); - for (long i = 0; i < entityTypeCount; ++i) { - EntityType_Load(GlobalEntityTypes[i]); - } + Buckets_Init(EntityType_BC); } -int64_t EntityType_FindByTypeCode(const char *typeCode) { - for (int64_t i = 0; i < GlobalEntityTypes.Count(); ++i) { - if (strcmp(typeCode, GlobalEntityTypes[i].entityTypeCode) == 0) { - return i; +EntityType *EntityType_Create() { + EntityTypeHandle entTypeHandle{Buckets_NewHandle(EntityType_BC)}; + EntityType &entityType = EntityType_BC.buckets[entTypeHandle.bucketIndex][entTypeHandle.itemIndex]; + new (&entityType) EntityType{}; + ECS_CreateEntity(&entityType); + return &entityType; +} + +Entity_Base *EntityType_CreateGenericInstance(EntityType *et, CompInstance *srcInstance) { + assert(et != nullptr); + Entity_Base *genericEntity = ECS_CreateGenericEntity(); + auto *level = PkeLevel_Get(pkeSettings.rt.activeLevel); + ECS_CreateEntity(genericEntity, level); + + for (size_t i = 0; i < et->detailsCount; ++i) { + auto &etd = et->details[i]; + auto *compInst = ECS_CreateInstance(genericEntity, etd.grBinds); + + if (srcInstance != nullptr) { + if (srcInstance->collisionCallback.name[0] != '\0') { + strncpy(compInst->collisionCallback.name, srcInstance->collisionCallback.name, CallbackSignatureLength); + PkePlugin_SetSignatureFunc(&compInst->collisionCallback); + } + compInst->physicsLayer = srcInstance->physicsLayer; + compInst->physicsMask = srcInstance->physicsMask; + } else { + compInst->physicsLayer = etd.bt.startingCollisionLayer; + compInst->physicsMask = etd.bt.startingCollisionMask; } + btVector3 localInertia(0, 0, 0); + etd.bt.shape->calculateLocalInertia(etd.bt.startingMass, localInertia); + btTransform posRot{}; + posRot.setIdentity(); + compInst->bt.motionState = Pke_New<btDefaultMotionState>(MemBkt_Bullet); + new (compInst->bt.motionState) btDefaultMotionState(posRot); + compInst->bt.rigidBody = Pke_New<btRigidBody>(MemBkt_Bullet); + new (compInst->bt.rigidBody) btRigidBody(etd.bt.startingMass, compInst->bt.motionState, etd.bt.shape, localInertia); + compInst->bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); + compInst->bt.rigidBody->setAngularVelocity(btVector3(0,0,0)); + compInst->bt.rigidBody->getCollisionShape()->setLocalScaling(btVector3(1, 1, 1)); + BtDynamicsWorld->addRigidBody(compInst->bt.rigidBody); + compInst->bt.rigidBody->getBroadphaseProxy()->m_collisionFilterGroup = static_cast<PhysicsCollision_T>(compInst->physicsLayer); + compInst->bt.rigidBody->getBroadphaseProxy()->m_collisionFilterMask = static_cast<PhysicsCollision_T>(compInst->physicsMask); + compInst->bt.rigidBody->setUserPointer(reinterpret_cast<void *>(compInst->entHandle.hash)); } - return -1; + return genericEntity; } -int64_t EntityType_FindByEntity(Entity_Base *entity, int64_t &detailIndex) { - assert(entity != nullptr); - for (int64_t i = 0; i < GlobalEntityTypes.Count(); ++i) { - for (int64_t k = 0; k < GlobalEntityTypes[i].detailsCount; ++k) { - if (GlobalEntityTypes[i].details[k].entityHandle == entity->handle) { - detailIndex = k; - return i; +EntityType *EntityType_FindByTypeCode(const char *typeCode) { + for (PkeHandleBucketIndex_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { + auto &bkt = EntityType_BC.buckets[b]; + long itemCount = EntityType_BC.pkeHandle.bucketIndex == b ? EntityType_BC.pkeHandle.itemIndex : EntityType_BC.limits.itemIndex; + for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + auto &entityType = bkt[i]; + if (entityType.handle == EntityHandle_MAX) continue; + if (strcmp(typeCode, entityType.entityTypeCode) == 0) { + return &entityType; } } - if (GlobalEntityTypes[i].entityHandle == entity->handle) { - detailIndex = -1; - return i; + } + return nullptr; +} + +EntityType *EntityType_FindByEntityHandle(EntityHandle handle) { + if (handle == EntityHandle_MAX) return nullptr; + for (PkeHandleBucketIndex_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { + auto &bkt = EntityType_BC.buckets[b]; + long itemCount = EntityType_BC.pkeHandle.bucketIndex == b ? EntityType_BC.pkeHandle.itemIndex : EntityType_BC.limits.itemIndex; + for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + auto &entityType = bkt[i]; + if (entityType.handle == handle) { + return &entityType; + } } } - detailIndex = -1; - return -1; + return nullptr; } void CalculateCombinedMemReqs(uint64_t memReqsCount, VkMemoryRequirements *memReqs, VkMemoryRequirements &combinedMemReqs) { @@ -94,7 +146,6 @@ struct EntityTypeDetails_LoadHelperStruct { EntityTypeDetails *etd = nullptr; AssetHandle textureAssetHandle = AssetHandle_MAX; const Asset *textureAsset = nullptr; - CompGrBinds *grBinds = nullptr; struct { DynArray<glm::vec3> *vertexes = nullptr; DynArray<glm::vec3> *normals = nullptr; @@ -155,10 +206,7 @@ void EntityType_PreLoad(EntityType_LoadHelperStruct &helper) { EntityTypeDetails &etd = helper.et.details[i]; EntityTypeDetails_LoadHelperStruct &etdHelper = helper.etdHelpers->Push(); etdHelper.etd = &etd; - etd.entityHandle = ECS_CreateEntity(helper.et.entityHandle); - auto &grBinds = ECS_CreateGrBinds(etd.entityHandle); - etdHelper.grBinds = &grBinds; - etd.grBindsHandle = grBinds.grBindsHandle; + etd.grBinds = ECS_CreateGrBinds(&helper.et);; etdHelper.physDbg.vertexes = reinterpret_cast<DynArray<glm::vec3> *>(Pke_New(sizeof(DynArray<glm::vec3>), 64, helper.bkt)); etdHelper.physDbg.normals = reinterpret_cast<DynArray<glm::vec3> *>(Pke_New(sizeof(DynArray<glm::vec3>), 64, helper.bkt)); etdHelper.physDbg.uv = reinterpret_cast<DynArray<glm::vec2> *>(Pke_New(sizeof(DynArray<glm::vec2>), 64, helper.bkt)); @@ -580,11 +628,11 @@ void EntityType_LoadTexture(EntityType_LoadHelperStruct &helper, const int64_t i vkDescriptorSetAllocateInfo.descriptorSetCount = MAX_FRAMES_IN_FLIGHT; vkDescriptorSetAllocateInfo.pSetLayouts = descriptorSets; - etdHelper.grBinds->vkDescriptorSets = Pke_New<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT); + etdHelper.etd->grBinds->vkDescriptorSets = Pke_New<VkDescriptorSet>(MAX_FRAMES_IN_FLIGHT); for (long i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) { - etdHelper.grBinds->vkDescriptorSets[i] = VkDescriptorSet{}; + etdHelper.etd->grBinds->vkDescriptorSets[i] = VkDescriptorSet{}; } - vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, etdHelper.grBinds->vkDescriptorSets); + vkResult = vkAllocateDescriptorSets(vkDevice, &vkDescriptorSetAllocateInfo, etdHelper.etd->grBinds->vkDescriptorSets); assert(vkResult == VK_SUCCESS); VkWriteDescriptorSet writeDescriptorSets[2 * MAX_FRAMES_IN_FLIGHT]; @@ -618,10 +666,10 @@ void EntityType_LoadTexture(EntityType_LoadHelperStruct &helper, const int64_t i long samplerIndex = uboIndex + 1; writeDescriptorSets[uboIndex].pBufferInfo = &vkDescriptorBufferInfo[i]; - writeDescriptorSets[uboIndex].dstSet = etdHelper.grBinds->vkDescriptorSets[i]; + writeDescriptorSets[uboIndex].dstSet = etdHelper.etd->grBinds->vkDescriptorSets[i]; writeDescriptorSets[samplerIndex].pImageInfo = &textureDescriptorInfo; - writeDescriptorSets[samplerIndex].dstSet = etdHelper.grBinds->vkDescriptorSets[i]; + writeDescriptorSets[samplerIndex].dstSet = etdHelper.etd->grBinds->vkDescriptorSets[i]; } vkUpdateDescriptorSets(vkDevice, 2 * MAX_FRAMES_IN_FLIGHT, writeDescriptorSets, 0, nullptr); @@ -656,15 +704,15 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh const auto &accVert = helper.gltfData->accessors[accessorIndexVertex]; uint32_t offsetVert = runningOffset; uint32_t sizeVert = accVert.buffer_view->size; - etdHelper.grBinds->vertexFirstBinding = index; - etdHelper.grBinds->vertexBindingCount = 1; + etdHelper.etd->grBinds->vertexFirstBinding = index; + etdHelper.etd->grBinds->vertexBindingCount = 1; alignmentPadding = sizeVert % helper.vertMemoryRequirementsCombined.alignment; alignmentPadding = alignmentPadding == 0 ? 0 : helper.vertMemoryRequirementsCombined.alignment - alignmentPadding; sizeVert += alignmentPadding; bufferCI.size = sizeVert; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->vertexBuffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->vertexBuffer, helper.et.deviceMemoryVert, offsetVert); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->vertexBuffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->vertexBuffer, helper.et.deviceMemoryVert, offsetVert); runningOffset += sizeVert; index += 1; @@ -672,14 +720,14 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh const auto &accNorm = helper.gltfData->accessors[accessorIndexNormal]; uint32_t offsetNorm = runningOffset; uint32_t sizeNorm = accNorm.buffer_view->size; - etdHelper.grBinds->normalsFirstBinding = index; - etdHelper.grBinds->normalsBindingCount = 1; + etdHelper.etd->grBinds->normalsFirstBinding = index; + etdHelper.etd->grBinds->normalsBindingCount = 1; alignmentPadding = sizeNorm % helper.vertMemoryRequirementsCombined.alignment; alignmentPadding = alignmentPadding == 0 ? 0 : helper.vertMemoryRequirementsCombined.alignment - alignmentPadding; sizeNorm += alignmentPadding; bufferCI.size = sizeNorm; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->normalsBuffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->normalsBuffer, helper.et.deviceMemoryVert, offsetNorm); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->normalsBuffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->normalsBuffer, helper.et.deviceMemoryVert, offsetNorm); runningOffset += sizeNorm; index += 1; @@ -687,21 +735,21 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh const auto &accUV = helper.gltfData->accessors[accessorIndexUV]; uint32_t offsetUV = runningOffset; uint32_t sizeUV = accUV.buffer_view->size; - etdHelper.grBinds->uvFirstBinding = index; - etdHelper.grBinds->uvBindingCount = 1; + etdHelper.etd->grBinds->uvFirstBinding = index; + etdHelper.etd->grBinds->uvBindingCount = 1; alignmentPadding = sizeUV % helper.vertMemoryRequirementsCombined.alignment; alignmentPadding = alignmentPadding == 0 ? 0 : helper.vertMemoryRequirementsCombined.alignment - alignmentPadding; sizeUV += alignmentPadding; bufferCI.size = sizeUV; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->uvBuffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->uvBuffer , helper.et.deviceMemoryVert, offsetUV); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->uvBuffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->uvBuffer , helper.et.deviceMemoryVert, offsetUV); runningOffset += sizeUV; index += 1; // 2023-09-27 - JCB // I don't know where else to put this - etdHelper.grBinds->instanceFirstBinding = index; - etdHelper.grBinds->instanceBindingCount = 1; + etdHelper.etd->grBinds->instanceFirstBinding = index; + etdHelper.etd->grBinds->instanceBindingCount = 1; // no index += 1 because index just happens to be the right value here for // the binding index, whereas binding the IndexBuffer doesn't need a binding index. @@ -709,15 +757,15 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh const auto &accIndex = helper.gltfData->accessors[accessorIndexIndex]; uint32_t offsetIndex = runningOffset; uint32_t sizeIndex = accIndex.buffer_view->size; - etdHelper.grBinds->indexBindingCount = 1; - etdHelper.grBinds->indexCount = accIndex.count; + etdHelper.etd->grBinds->indexBindingCount = 1; + etdHelper.etd->grBinds->indexCount = accIndex.count; alignmentPadding = sizeIndex % helper.vertMemoryRequirementsCombined.alignment; alignmentPadding = alignmentPadding == 0 ? 0 : helper.vertMemoryRequirementsCombined.alignment - alignmentPadding; sizeIndex += alignmentPadding; bufferCI.size = sizeIndex; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->indexBuffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->indexBuffer, helper.et.deviceMemoryVert, offsetIndex); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->indexBuffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->indexBuffer, helper.et.deviceMemoryVert, offsetIndex); runningOffset += sizeIndex; // index += 1; @@ -764,22 +812,22 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh index = 0; bufferCopys[index].srcOffset = offsetVert; bufferCopys[index].size = sizeVert; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->vertexBuffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.etd->grBinds->vertexBuffer, 1, &bufferCopys[index]); index+=1; bufferCopys[index].srcOffset = offsetNorm; bufferCopys[index].size = sizeNorm; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->normalsBuffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.etd->grBinds->normalsBuffer, 1, &bufferCopys[index]); index+=1; bufferCopys[index].srcOffset = offsetUV; bufferCopys[index].size = sizeUV; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->uvBuffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.etd->grBinds->uvBuffer, 1, &bufferCopys[index]); index+=1; bufferCopys[index].srcOffset = offsetIndex; bufferCopys[index].size = sizeIndex; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->indexBuffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.etd->grBinds->indexBuffer, 1, &bufferCopys[index]); // index+=1; vkEndCommandBuffer(transferCommandBuffer); @@ -801,12 +849,12 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh } // set up instance buffer - etdHelper.grBinds->instanceBufferMaxCount = etdHelper.etd->startingInstanceCount; - etdHelper.grBinds->instanceBufferMaxCount = etdHelper.grBinds->instanceBufferMaxCount < 1 ? 1 : etdHelper.grBinds->instanceBufferMaxCount; - bufferCI.size = sizeof(glm::mat4) * etdHelper.grBinds->instanceBufferMaxCount; + etdHelper.etd->grBinds->instanceBufferMaxCount = etdHelper.etd->startingInstanceCount; + etdHelper.etd->grBinds->instanceBufferMaxCount = etdHelper.etd->grBinds->instanceBufferMaxCount < 1 ? 1 : etdHelper.etd->grBinds->instanceBufferMaxCount; + bufferCI.size = sizeof(glm::mat4) * etdHelper.etd->grBinds->instanceBufferMaxCount; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->instanceBuffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->instanceBuffer, helper.et.deviceMemoryInst, 0); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->instanceBuffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->instanceBuffer, helper.et.deviceMemoryInst, 0); // bullet @@ -818,60 +866,60 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh // vertex offsetVert = runningOffset; sizeVert = sizeof(glm::vec3) * etdHelper.physDbg.vertexes->Count(); - etdHelper.grBinds->physVertBD.firstBinding = index; - etdHelper.grBinds->physVertBD.bindingCount = 1; + etdHelper.etd->grBinds->physVertBD.firstBinding = index; + etdHelper.etd->grBinds->physVertBD.bindingCount = 1; alignmentPadding = sizeVert % helper.physVertMemoryRequirementsCombined.alignment; alignmentPadding = alignmentPadding == 0 ? 0 : helper.physVertMemoryRequirementsCombined.alignment - alignmentPadding; sizeVert += alignmentPadding; bufferCI.size = sizeVert; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->physVertBD.buffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->physVertBD.buffer, helper.et.deviceMemoryPhysVert, offsetVert); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->physVertBD.buffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->physVertBD.buffer, helper.et.deviceMemoryPhysVert, offsetVert); runningOffset += sizeVert; // norm index = 1; offsetNorm = runningOffset; sizeNorm = sizeof(glm::vec3) * etdHelper.physDbg.normals->Count(); - etdHelper.grBinds->physNormBD.firstBinding = index; - etdHelper.grBinds->physNormBD.bindingCount = 1; + etdHelper.etd->grBinds->physNormBD.firstBinding = index; + etdHelper.etd->grBinds->physNormBD.bindingCount = 1; alignmentPadding = sizeNorm % helper.physVertMemoryRequirementsCombined.alignment; alignmentPadding = alignmentPadding == 0 ? 0 : helper.physVertMemoryRequirementsCombined.alignment - alignmentPadding; sizeNorm += alignmentPadding; bufferCI.size = sizeNorm; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->physNormBD.buffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->physNormBD.buffer, helper.et.deviceMemoryPhysVert, offsetNorm); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->physNormBD.buffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->physNormBD.buffer, helper.et.deviceMemoryPhysVert, offsetNorm); runningOffset += sizeNorm; // uv index = 2; offsetUV = runningOffset; sizeUV = sizeof(glm::vec2) * etdHelper.physDbg.uv->Count(); - etdHelper.grBinds->physUvBD.firstBinding = index; - etdHelper.grBinds->physUvBD.bindingCount = 1; + etdHelper.etd->grBinds->physUvBD.firstBinding = index; + etdHelper.etd->grBinds->physUvBD.bindingCount = 1; alignmentPadding = sizeUV % helper.physVertMemoryRequirementsCombined.alignment; alignmentPadding = alignmentPadding == 0 ? 0 : helper.physVertMemoryRequirementsCombined.alignment - alignmentPadding; sizeUV += alignmentPadding; bufferCI.size = sizeUV; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->physUvBD.buffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->physUvBD.buffer, helper.et.deviceMemoryPhysVert, offsetUV); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->physUvBD.buffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->physUvBD.buffer, helper.et.deviceMemoryPhysVert, offsetUV); runningOffset += sizeUV; // index index = 3; offsetIndex = runningOffset; sizeIndex = sizeof(uint16_t) * etdHelper.physDbg.indexes->Count(); - etdHelper.grBinds->physIndxBD.firstBinding = index; - etdHelper.grBinds->physIndxBD.bindingCount = 1; + etdHelper.etd->grBinds->physIndxBD.firstBinding = index; + etdHelper.etd->grBinds->physIndxBD.bindingCount = 1; alignmentPadding = sizeIndex % helper.physVertMemoryRequirementsCombined.alignment; alignmentPadding = alignmentPadding == 0 ? 0 : helper.physVertMemoryRequirementsCombined.alignment - alignmentPadding; sizeIndex += alignmentPadding; bufferCI.size = sizeIndex; bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.grBinds->physIndxBD.buffer); - vkBindBufferMemory(vkDevice, etdHelper.grBinds->physIndxBD.buffer, helper.et.deviceMemoryPhysVert, offsetIndex); + vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &etdHelper.etd->grBinds->physIndxBD.buffer); + vkBindBufferMemory(vkDevice, etdHelper.etd->grBinds->physIndxBD.buffer, helper.et.deviceMemoryPhysVert, offsetIndex); runningOffset += sizeIndex; assert(runningOffset == helper.physVertMemoryRequirementsCombined.size); @@ -922,25 +970,25 @@ void EntityType_LoadMesh(EntityType_LoadHelperStruct &helper, const int64_t mesh runningOffset = 0; bufferCopys[index].srcOffset = runningOffset; bufferCopys[index].size = sizeVert; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->physVertBD.buffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.etd->grBinds->physVertBD.buffer, 1, &bufferCopys[index]); runningOffset += sizeVert; index+=1; bufferCopys[index].srcOffset = runningOffset; bufferCopys[index].size = sizeNorm; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->physNormBD.buffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.etd->grBinds->physNormBD.buffer, 1, &bufferCopys[index]); runningOffset += sizeNorm; index+=1; bufferCopys[index].srcOffset = runningOffset; bufferCopys[index].size = sizeUV; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->physUvBD.buffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.etd->grBinds->physUvBD.buffer, 1, &bufferCopys[index]); runningOffset += sizeUV; index+=1; bufferCopys[index].srcOffset = runningOffset; bufferCopys[index].size = sizeIndex; - vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.grBinds->physIndxBD.buffer, 1, &bufferCopys[index]); + vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, etdHelper.etd->grBinds->physIndxBD.buffer, 1, &bufferCopys[index]); // runningOffset += sizeIndex; // index+=1; @@ -1012,14 +1060,14 @@ void EntityType_Load(EntityType &et) { EntityType_PreLoad(helper); for (int64_t i = 0; i < et.detailsCount; ++i) { - EntityTypeDetails_LoadHelperStruct &etd = (*helper.etdHelpers)[i]; + EntityTypeDetails_LoadHelperStruct &etdHelper = (*helper.etdHelpers)[i]; /* * 2023-09-13 - JCB * I don't like that we're just copying this. * This should be moved to window.cpp. */ - etd.grBinds->vkPipelineLayout = pkePipelines.vkPipelineLayout_Texture; - etd.grBinds->graphicsPipeline = pkePipelines.pipelines.Texture; + etdHelper.etd->grBinds->vkPipelineLayout = pkePipelines.vkPipelineLayout_Texture; + etdHelper.etd->grBinds->graphicsPipeline = pkePipelines.pipelines.Texture; // handle texture EntityType_LoadTexture(helper, i); @@ -1151,17 +1199,15 @@ void EntityType_Unload(EntityType &et, CompGrBinds *grBindsArr[1]) { void EntityType_Tick(double delta) { const auto count = EntitiesToBeRemoved.Count(); - int64_t detailIndex = -1; for (long i = 0; i < count; ++i) { - if (auto index = EntityType_FindByEntity(EntitiesToBeRemoved[i], detailIndex); index > -1) { - auto &entType = GlobalEntityTypes[index]; - if (auto *grBinds = ECS_GetGrBinds(entType.details[detailIndex].grBindsHandle); grBinds != nullptr) { - auto &td = EntityTypesToTeardown.Push(); - td.handle = EntitiesToBeRemoved[i]->handle; - td.ticksToWait = 1; - for (long k = 0; k < GlobalEntityTypes[index].detailsCount; ++k) { - td.grBinds[k] = grBinds; - } + auto *entTypePtr = EntityType_FindByEntityHandle(EntitiesToBeRemoved[i]->handle); + if (entTypePtr != nullptr) { + auto &entType = *entTypePtr; + auto &td = EntityTypesToTeardown.Push(); + td.handle = EntitiesToBeRemoved[i]->handle; + td.ticksToWait = 1; + for (long k = 0; k < entType.detailsCount; ++k) { + td.grBinds[k] = entType.details[k].grBinds; } } } @@ -1170,21 +1216,22 @@ void EntityType_Tick(double delta) { void EntityType_Tick_Late(double delta) { while (EntitiesWithExcessInstances.Count() != 0) { auto *entity = EntitiesWithExcessInstances.Pop(); - int64_t detailIndex = 0; - auto index = EntityType_FindByEntity(entity, detailIndex); - auto &et = GlobalEntityTypes[index]; - auto &etd = GlobalEntityTypes[index].details[detailIndex]; - auto *grBinds = ECS_GetGrBinds(etd.grBindsHandle); - EntityType_RolloverInstances(et, *grBinds); + auto *etPtr = EntityType_FindByEntityHandle(entity->handle); + assert(etPtr != nullptr); + auto &et = *etPtr; + for (int64_t i = 0; i < et.detailsCount; ++i) { + auto &etd = et.details[i]; + assert(etd.grBinds != nullptr); + EntityType_RolloverInstances(et, *etd.grBinds); + } } for (int64_t i = EntityTypesToTeardown.Count() - 1; i >= 0; --i) { auto &td = EntityTypesToTeardown[i]; td.ticksToWait -= 1; if (td.ticksToWait == 0) { - int64_t detailIndex = -1; - auto index = EntityType_FindByEntityHandle(td.handle, detailIndex); - EntityType_Unload(GlobalEntityTypes[index], td.grBinds); - GlobalEntityTypes.Remove(index); + auto *entityType = EntityType_FindByEntityHandle(td.handle); + assert(entityType != nullptr); + EntityType_Unload(*entityType, td.grBinds); EntityTypesToTeardown.Remove(i); } } @@ -1286,18 +1333,33 @@ void EntityType_RolloverInstances(EntityType &et, CompGrBinds &grBinds) { vkFreeMemory(vkDevice, oldMemory, vkAllocator); } +PkeHandleBucketIndex_T EntityType_GetBucketCount() { + return EntityType_BC.pkeHandle.bucketIndex + 1; +} + +EntityType *EntityType_GetEntityTypes(PkeHandleBucketIndex_T bucketIndex, PkeHandleItemIndex_T &itemCount) { + assert(bucketIndex <= EntityType_BC.pkeHandle.bucketIndex); + if (bucketIndex == EntityType_BC.pkeHandle.bucketIndex) itemCount = EntityType_BC.pkeHandle.itemIndex; + itemCount = EntityType_BC.limits.itemIndex; + return EntityType_BC.buckets[bucketIndex]; +} + void EntityType_Teardown() { - for (int64_t i = GlobalEntityTypes.Count() - 1; i >= 0; --i) { - if (GlobalEntityTypes[i].modelAssetKey[0] == '\0') continue; - EntityType &et = GlobalEntityTypes[i]; - CompGrBinds *grBindsArr[1] = {nullptr}; - - for (long k = 0; k < et.detailsCount; ++k) { - const EntityTypeDetails &etd = et.details[k]; - grBindsArr[k] = ECS_GetGrBinds(etd.entityHandle); + + for (PkeHandleBucketIndex_T b = 0; b <= EntityType_BC.pkeHandle.bucketIndex; ++b) { + auto &bkt = EntityType_BC.buckets[b]; + long itemCount = EntityType_BC.pkeHandle.bucketIndex == b ? EntityType_BC.pkeHandle.itemIndex : EntityType_BC.limits.itemIndex; + for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + auto &et = bkt[i]; + if (et.modelAssetKey[0] == '\0') continue; + CompGrBinds *grBindsArr[EntityTypeDetails_MAX] = {nullptr}; + for (long k = 0; k < et.detailsCount; ++k) { + const EntityTypeDetails &etd = et.details[k]; + grBindsArr[k] = etd.grBinds; + } + EntityType_Unload(et, grBindsArr); } - EntityType_Unload(et, grBindsArr); } - GlobalEntityTypes.~DynArray(); + Buckets_Destroy(EntityType_BC); EntityTypesToTeardown.~DynArray(); } diff --git a/src/entities.hpp b/src/entities.hpp index cbb8e15..ce680e0 100644 --- a/src/entities.hpp +++ b/src/entities.hpp @@ -1,6 +1,7 @@ #ifndef PKE_ENTITIES_HPP #define PKE_ENTITIES_HPP +#include "memory-type-defs.hpp" #include "vendor/cgltf-include.hpp" #include "vendor/stb_image_include.hpp" #include "ecs.hpp" @@ -12,10 +13,10 @@ #include <BulletCollision/CollisionShapes/btCollisionShape.h> #include <vulkan/vulkan_core.h> +const size_t EntityTypeDetails_MAX = 1; struct EntityTypeDetails { AssetKey textureAssetKey; - EntityHandle entityHandle = EntityHandle_MAX; - GrBindsHandle grBindsHandle = GrBindsHandle_MAX; + CompGrBinds *grBinds = nullptr; VkImage textureImage = VK_NULL_HANDLE; VkImageView textureImageView = VK_NULL_HANDLE; VkDescriptorPool vkDescriptorPool = VK_NULL_HANDLE; @@ -27,26 +28,33 @@ struct EntityTypeDetails { } bt; uint32_t startingInstanceCount = 1024; }; -struct EntityType { +struct EntityType : public Entity_Base { AssetKey modelAssetKey; const char *entityTypeCode = nullptr; - EntityHandle entityHandle = EntityHandle_MAX; VkDeviceMemory deviceMemoryVert = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryInst = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryPhysVert = VK_NULL_HANDLE; VkDeviceMemory deviceMemoryTexture = VK_NULL_HANDLE; - int64_t detailsCount = 1; - EntityTypeDetails details[1]; + int64_t detailsCount = 0; + EntityTypeDetails details[EntityTypeDetails_MAX]; + PkeCallback createInstanceCallback; + // PkeCallback serializeInstanceCallback; // TODO + // PkeCallback parseInstanceCallback; // TODO }; -extern DynArray<EntityType> GlobalEntityTypes; +struct EntityTypeHandle : PkeHandle {}; +constexpr EntityTypeHandle EntityTypeHandle_MAX = EntityTypeHandle{}; void EntityType_Init(); -int64_t EntityType_FindByTypeCode(const char *typeCode); -int64_t EntityType_FindByEntityHandle(EntityHandle handle, int64_t &detailIndex); +EntityType *EntityType_FindByTypeCode(const char *typeCode); +EntityType *EntityType_FindByEntityHandle(EntityHandle handle); +EntityType *EntityType_Create(); +Entity_Base *EntityType_CreateGenericInstance(EntityType *et, CompInstance *srcInstance = nullptr); void EntityType_Load(EntityType &et); void EntityType_Tick(double delta); void EntityType_Tick_Late(double delta); void EntityType_RolloverInstances(EntityType &et, CompGrBinds &grBinds); +PkeHandleBucketIndex_T EntityType_GetBucketCount(); +EntityType *EntityType_GetEntityTypes(PkeHandleBucketIndex_T bucketIndex, PkeHandleItemIndex_T &itemCount); void EntityType_Teardown(); #endif /* PKE_ENTITIES_HPP */ diff --git a/src/game.cpp b/src/game.cpp index dc32b2a..97bc247 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -91,17 +91,7 @@ void SerializeCamera(std::ofstream &stream, const PkeCamera &cam) { void SerializeInstance(std::ofstream &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); - EntityType *et = nullptr; - // EntityTypeDetails *etd = nullptr; - for (long i = 0; i < GlobalEntityTypes.Count(); ++i) { - for (int64_t k = 0; k < GlobalEntityTypes[i].detailsCount; ++k) { - if (GlobalEntityTypes[i].details[k].grBindsHandle == comp.grBindsHandle) { - et = &GlobalEntityTypes[i]; - // etd = &GlobalEntityTypes[i].details[k]; - break; - } - } - } + EntityType *et = EntityType_FindByEntityHandle(comp.entHandle); assert(et != nullptr); CompInstance c{}; InstPos baseInst{}; @@ -151,7 +141,7 @@ void SerializeInstance(std::ofstream &stream, const CompInstance &comp) { } } -void ParseCamera(LevelHandle levelHandle, std::ifstream &stream) { +void ParseCamera(PkeLevel *level, std::ifstream &stream) { PkeCamera cam{}; while (stream.getline(readLine, readLineLength)) { if (strcmp(readLine, PKE_FILE_OBJ_END) == 0) { @@ -162,9 +152,7 @@ void ParseCamera(LevelHandle levelHandle, std::ifstream &stream) { rCam.type = cam.type; rCam.orientation = cam.orientation; rCam.isPrimary = cam.isPrimary; - if (levelHandle != LevelHandle_MAX) { - PkeLevel_RegisterCamera(levelHandle, rCam.handle); - } + PkeLevel_RegisterCamera(level->levelHandle, rCam.handle); if (rCam.isPrimary == true) { ActiveCamera = &rCam; } @@ -239,7 +227,7 @@ void ParseCamera(LevelHandle levelHandle, std::ifstream &stream) { } } -void ParseInstance(EntityHandle parentEntHandle, std::ifstream &stream) { +void ParseInstance(Entity_Base *parentEntity, std::ifstream &stream) { CompInstance comp{}; InstPos instPos{}; instPos.posRot = btTransform{}; @@ -252,39 +240,20 @@ void ParseInstance(EntityHandle parentEntHandle, std::ifstream &stream) { while (stream.getline(readLine, readLineLength)) { if (strstr(PKE_FILE_OBJ_END, readLine)) { if (entTypeCode[0] == '\0') { - printf("[Game::ParseInstance] Failed to create instance from save file. No EntTypeCode present.\n"); + fprintf(stdout, "[Game::ParseInstance] Failed to create instance from save file. No EntTypeCode present.\n"); break; } - int64_t existingEntityTypeIndex = EntityType_FindByTypeCode(entTypeCode); - if (existingEntityTypeIndex == -1) { - printf("[Game::ParseInstance] Failed to create instance from save file. Unknown EntityTypeCode: \"%s\"\n", entTypeCode); + 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; } - const auto &et = GlobalEntityTypes[existingEntityTypeIndex]; - for (int64_t i = 0; i < et.detailsCount; ++i) { - auto &etd = et.details[i]; - auto entHandle = ECS_CreateEntity(parentEntHandle); - auto &compInst = ECS_CreateInstance(entHandle, etd.entityHandle); - - strncpy(compInst.collisionCallback.name, comp.collisionCallback.name, 16); - PkePlugin_SetSignatureFunc(&compInst.collisionCallback); - - compInst.physicsLayer = comp.physicsLayer; - compInst.physicsMask = comp.physicsMask; - btVector3 localInertia(0, 0, 0); - etd.bt.shape->calculateLocalInertia(instPos.mass, localInertia); - compInst.bt.motionState = Pke_New<btDefaultMotionState>(MemBkt_Bullet); - new (compInst.bt.motionState) btDefaultMotionState(instPos.posRot); - compInst.bt.rigidBody = Pke_New<btRigidBody>(MemBkt_Bullet); - new (compInst.bt.rigidBody) btRigidBody(instPos.mass, compInst.bt.motionState, etd.bt.shape, localInertia); - compInst.bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); - compInst.bt.rigidBody->setAngularVelocity(btVector3(0,0,0)); - compInst.bt.rigidBody->getCollisionShape()->setLocalScaling(instPos.scale); - BtDynamicsWorld->addRigidBody(compInst.bt.rigidBody); - auto *broadphaseProxy = compInst.bt.rigidBody->getBroadphaseProxy(); - broadphaseProxy->m_collisionFilterGroup = static_cast<PhysicsCollision_T>(comp.physicsLayer); - broadphaseProxy->m_collisionFilterMask = static_cast<PhysicsCollision_T>(comp.physicsMask); - compInst.bt.rigidBody->setUserPointer(reinterpret_cast<void *>(compInst.entHandle.hash)); + + if (etPtr->createInstanceCallback.func != nullptr) { + reinterpret_cast<void(*)()>(etPtr->createInstanceCallback.func)(); + } else { + EntityType_CreateGenericInstance(etPtr, &comp); + fprintf(stdout ,"[Game::ParseInstance] No callback func to create instance."); } break; } @@ -421,26 +390,22 @@ void Game_SaveSceneFile(const char *sceneFilePath) { f.close(); } -void Game_LoadSceneFile(LevelHandle levelHandle, const char *sceneFilePath) { +void Game_LoadSceneFile(PkeLevel *level, const char *sceneFilePath) { std::ifstream f(sceneFilePath); if (!f.is_open()) { fprintf(stderr, "Failed to load requested scene file: %s\n", sceneFilePath); return; } memset(readLine, '\0', readLineLength); - EntityHandle parentEntHandle = EntityHandle_MAX; - if (levelHandle != LevelHandle_MAX) { - parentEntHandle = ECS_CreateEntity(); - PkeLevel_RegisterWrappingEntity(levelHandle, parentEntHandle); - } + ECS_CreateEntity(level); while (f.getline(readLine, readLineLength)) { if (strcmp(PKE_FILE_OBJ_CAMERA, readLine) == 0) { - ParseCamera(levelHandle, f); + ParseCamera(level, f); continue; } if (strcmp(PKE_FILE_OBJ_INSTANCE, readLine) == 0) { - ParseInstance(parentEntHandle, f); + ParseInstance(level, f); continue; } } @@ -498,7 +463,7 @@ void Game_Tick(double delta) { } if (pkeSettings.rt.nextLevel != LevelHandle_MAX) { // TODO async this - Game_LoadSceneFile(pkeSettings.rt.nextLevel, pkeSettings.rt.sceneName); + Game_LoadSceneFile(PkeLevel_Get(pkeSettings.rt.nextLevel), pkeSettings.rt.sceneName); pkeSettings.rt.activeLevel = pkeSettings.rt.nextLevel; pkeSettings.rt.nextLevel = LevelHandle_MAX; } @@ -537,10 +502,10 @@ void Game_Main(PKEWindowProperties windowProps, const char *executablePath) { Physics_Init(); Game_Init(); ECS_Init(); + EntityType_Init(); PkeProject_Load(pkeSettings.args.projectPath); CreateWindow(windowProps); PkeInput_Init(); - EntityType_Init(); if (pkeSettings.args.pluginPath != nullptr) { PkePlugin_Load(pkeSettings.args.pluginPath); } diff --git a/src/game.hpp b/src/game.hpp index 3912f0a..b575376 100644 --- a/src/game.hpp +++ b/src/game.hpp @@ -11,6 +11,6 @@ void Game_Tick(double delta); void Game_Teardown(); void Game_RecordImGui(); void Game_SaveSceneFile(const char *); -void Game_LoadSceneFile(LevelHandle levelHandle, const char *); +void Game_LoadSceneFile(PkeLevel *level, const char *); #endif /* PKE_GAME_HPP */ diff --git a/src/level-types.hpp b/src/level-types.hpp index 64eef32..0809572 100644 --- a/src/level-types.hpp +++ b/src/level-types.hpp @@ -9,14 +9,12 @@ TypeSafeInt_Const_Expr(LevelHandle, uint16_t, 0xFFFF); -struct LvlEntHandleArr : public PkeArray<EntityHandle> { }; struct LvlCamArr : public PkeArray<CameraHandle> { }; -struct PkeLevel { +struct PkeLevel : public Entity_Base { MemBucket *bkt = nullptr; char name[16] = {}; - LevelHandle handle = LevelHandle_MAX; - LvlEntHandleArr wrappingEntities; + LevelHandle levelHandle = LevelHandle_MAX; LvlCamArr cameras; }; diff --git a/src/level.cpp b/src/level.cpp index 123d5e2..d4e4075 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -11,7 +11,7 @@ PkeLevel LEVELS[MAX_LEVEL_COUNT]; PkeLevel *PkeLevel_Get_Inner(LevelHandle handle) { for (long i = 0; i < MAX_LEVEL_COUNT; ++i) { - if (LEVELS[i].handle == handle) { + if (LEVELS[i].levelHandle == handle) { return &LEVELS[i]; } } @@ -28,13 +28,13 @@ LevelHandle PkeLevel_Create(const char *levelName) { if (lvl->bkt == nullptr) { lvl->bkt = Pke_BeginTransientBucket(); } - lvl->handle = nextHandle; + lvl->levelHandle = nextHandle; ++nextHandle; auto len = strlen(levelName); auto start = len <= (LEVEL_NAME_LENGTH - 1) ? 0 : len - (LEVEL_NAME_LENGTH - 1); strncpy(lvl->name, levelName + start, LEVEL_NAME_LENGTH); - return lvl->handle; + return lvl->levelHandle; } PkeLevel *PkeLevel_Get(LevelHandle handle) { @@ -47,23 +47,15 @@ LevelHandle PkeLevel_GetHandle(const char *levelName) { auto start = len <= (LEVEL_NAME_LENGTH - 1) ? 0 : len - (LEVEL_NAME_LENGTH - 1); strncpy(safeName, levelName + start, LEVEL_NAME_LENGTH); for (long i = 0; i < MAX_LEVEL_COUNT; ++i) { - if (LEVELS[i].handle != LevelHandle_MAX) { + if (LEVELS[i].levelHandle != LevelHandle_MAX) { if (strcmp(safeName, LEVELS[i].name)) { - return LEVELS[i].handle; + return LEVELS[i].levelHandle; } } } return LevelHandle_MAX; } -void PkeLevel_RegisterWrappingEntity(LevelHandle levelHandle, EntityHandle entityHandle) { - assert(levelHandle != LevelHandle_MAX); - assert(entityHandle != EntityHandle_MAX); - PkeLevel *lvl = PkeLevel_Get_Inner(levelHandle); - assert(lvl != nullptr && "Failed to find level by requested LevelHandle"); - PkeArray_Add(&lvl->wrappingEntities, entityHandle, lvl->bkt); -} - void PkeLevel_RegisterCamera(LevelHandle levelHandle, CameraHandle cameraHandle) { assert(levelHandle != LevelHandle_MAX); assert(cameraHandle != CameraHandle_MAX); @@ -76,17 +68,11 @@ void PkeLevel_Remove(LevelHandle handle) { PkeLevel *lvl = PkeLevel_Get_Inner(handle); assert(lvl != nullptr && "Failed to find level to remove by requested LevelHandle"); levelCount -= 1; - for (long i = 0; i < lvl->wrappingEntities.next; ++i) { - ECS_MarkForRemoval(lvl->wrappingEntities.data[i]); - } + ECS_MarkForRemoval(lvl); for (long i = 0; i < lvl->cameras.next; ++i) { PkeCamera_Destroy(lvl->cameras.data[i]); } - PkeArray_HardReset<EntityHandle>(&lvl->wrappingEntities); PkeArray_HardReset<CameraHandle>(&lvl->cameras); Pke_ResetBucket(lvl->bkt); - lvl->handle = LevelHandle_MAX; - lvl->wrappingEntities.next = 0; - lvl->wrappingEntities.reserved = 0; - lvl->wrappingEntities.data = CAFE_BABE(EntityHandle); + lvl->levelHandle = LevelHandle_MAX; } diff --git a/src/level.hpp b/src/level.hpp index 793d2b9..ae454a5 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -9,7 +9,6 @@ extern PkeLevel LEVELS[]; LevelHandle PkeLevel_Create(const char *levelName); PkeLevel *PkeLevel_Get(LevelHandle handle); LevelHandle PkeLevel_GetHandle(const char *levelName); -void PkeLevel_RegisterWrappingEntity(LevelHandle levelHandle, EntityHandle entHandle); void PkeLevel_RegisterCamera(LevelHandle levelHandle, CameraHandle cameraHandle); void PkeLevel_Remove(LevelHandle handle); diff --git a/src/physics.cpp b/src/physics.cpp index 4825955..88c8139 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -28,7 +28,7 @@ btBroadphaseInterface *btBroadphase = nullptr; btConstraintSolver *btSolver = nullptr; struct EntityCollision { - EntityHandle a, b; + CompInstance *a, *b; }; PkeArray<EntityCollision> collisionsThisTick{}; @@ -80,11 +80,9 @@ struct CollisionHandlerStruct : public btOverlapFilterCallback { const auto *col0 = static_cast<btCollisionObject *>(proxy0->m_clientObject); const auto *col1 = static_cast<btCollisionObject *>(proxy1->m_clientObject); if (col0 && col1) { - EntityHandle ent0{}; - ent0.hash = reinterpret_cast<uint64_t>(col0->getUserPointer()); - EntityHandle ent1{}; - ent1.hash = reinterpret_cast<uint64_t>(col1->getUserPointer()); - if (ent0 != EntityHandle_MAX && ent1 != EntityHandle_MAX) { + CompInstance *ent0 = reinterpret_cast<CompInstance *>(col0->getUserPointer()); + CompInstance *ent1 = reinterpret_cast<CompInstance *>(col1->getUserPointer()); + if (ent0 != nullptr && ent1 != nullptr) { PkeArray_Add<EntityCollision>(&collisionsThisTick, { .a = ent0, .b = ent1, diff --git a/src/project.cpp b/src/project.cpp index 4abe7ab..0f08859 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -27,6 +27,7 @@ const char* const PKE_PROJ_FILE_PROJ_SETTINGS_SCENES_END = "PkeSet::Scenes: ]"; const char* const PKE_PROJ_FILE_ENTITY_TYPE_MODEL_ASSET_KEY = "ModelAssetKey: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE = "EntityTypeCode: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE = "EntityHandle: "; +const char* const PKE_PROJ_FILE_ENTITY_TYPE_CREATE_INSTANCE_CALLBACK_SIGNATURE = "InstanceCreateCallbackSignature: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_COLLISION_CALLBACK_SIGNATURE = "CollisionCallbackSignature: "; const char* const PKE_PROJ_FILE_ENTITY_TYPE_DETAILS_BEGIN = "EntityHandleDetails: {"; const char* const PKE_PROJ_FILE_ENTITY_TYPE_DETAILS_END = "EntityHandleDetails: }"; @@ -65,19 +66,21 @@ void Proj_SerializeEntityType(std::ofstream &stream, const EntityType &et) { NULL_CHAR_ARR(handleStr, 19); NULL_CHAR_ARR(modelAssetKey, AssetKeyLength + 1); NULL_CHAR_ARR(textureAssetKey, AssetKeyLength + 1); - snprintf(handleStr, 19, "0x%016lX", et.entityHandle.hash); + snprintf(handleStr, 19, "0x%016lX", et.handle.hash); snprintf(modelAssetKey, AssetKeyLength + 1, "%s", et.modelAssetKey); EntityType e{}; if (modelAssetKey[0] != '\0') stream << PKE_PROJ_FILE_ENTITY_TYPE_MODEL_ASSET_KEY << modelAssetKey << std::endl; if (et.entityTypeCode != e.entityTypeCode) stream << PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_TYPE_CODE << et.entityTypeCode << std::endl; - if (et.entityHandle != e.entityHandle) + if (et.handle != e.handle) stream << PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE << handleStr << std::endl; + if (et.createInstanceCallback.name[0] != '\0') { + stream << PKE_PROJ_FILE_ENTITY_TYPE_CREATE_INSTANCE_CALLBACK_SIGNATURE << et.createInstanceCallback.name << std::endl; + } for (size_t i = 0; i < et.detailsCount; ++i) { const EntityTypeDetails &etd = et.details[i]; snprintf(textureAssetKey, AssetKeyLength + 1, "%s", etd.textureAssetKey); - CompGrBinds *grBinds = ECS_GetGrBinds(etd.entityHandle); stream << PKE_PROJ_FILE_ENTITY_TYPE_DETAILS_BEGIN << std::endl; if (textureAssetKey[0] != '\0') @@ -90,9 +93,9 @@ void Proj_SerializeEntityType(std::ofstream &stream, const EntityType &et) { stream << PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_COLLISION_LAYER << static_cast<PhysicsCollision_T>(etd.bt.startingCollisionLayer) << std::endl; if (etd.bt.startingCollisionMask != e.details[0].bt.startingCollisionMask) stream << PKE_PROJ_FILE_ENTITY_TYPE_PHYSICS_STARTING_COLLISION_MASK << static_cast<PhysicsCollision_T>(etd.bt.startingCollisionMask) << std::endl; - if (grBinds) { - if (grBinds->collisionCallback.name[0] != '\0') { - stream << PKE_PROJ_FILE_ENTITY_TYPE_COLLISION_CALLBACK_SIGNATURE << grBinds->collisionCallback.name << std::endl; + if (etd.grBinds) { + if (etd.grBinds->collisionCallback.name[0] != '\0') { + stream << PKE_PROJ_FILE_ENTITY_TYPE_COLLISION_CALLBACK_SIGNATURE << etd.grBinds->collisionCallback.name << std::endl; } } stream << PKE_PROJ_FILE_ENTITY_TYPE_DETAILS_END << std::endl; @@ -155,21 +158,40 @@ void Proj_ParseProjectSettings(std::ifstream &stream) { void Proj_ParseEntityType(std::ifstream &stream) { char collisionSig[CallbackSignatureLength + 1]; collisionSig[0] = '\0'; + char createInstanceSig[CallbackSignatureLength + 1]; + createInstanceSig[0] = '\0'; EntityType et{}; - uint8_t detailCount = 0; + int64_t detailCount = 0; while (stream.getline(projReadLine, projReadLineLength)) { if (strcmp(PKE_PROJ_FILE_OBJ_END, projReadLine) == 0) { - int64_t existingEntityTypeIndex = EntityType_FindByTypeCode(et.entityTypeCode); - if (existingEntityTypeIndex != -1) { + EntityType *existingPtr = EntityType_FindByTypeCode(et.entityTypeCode); + if (existingPtr != nullptr) { + // TODO leaks et.EntityTypeCode continue; } - et.entityHandle = ECS_CreateEntity(); - GlobalEntityTypes.Push(et); - CompGrBinds *grBinds = ECS_GetGrBinds(et.entityHandle); - if (grBinds) { - strncpy(grBinds->collisionCallback.name, collisionSig, CallbackSignatureLength); - PkePlugin_SetSignatureFunc(&grBinds->collisionCallback); + EntityType *etPtr = EntityType_Create(); + strncpy(etPtr->modelAssetKey, et.modelAssetKey, AssetKeyLength); + etPtr->entityTypeCode = et.entityTypeCode; + if (createInstanceSig[0] == '\0') { + strncpy(etPtr->createInstanceCallback.name, createInstanceSig, CallbackSignatureLength); + PkePlugin_SetSignatureFunc(&etPtr->createInstanceCallback); + } else { + etPtr->createInstanceCallback.name[0] = 'd'; + etPtr->createInstanceCallback.func = reinterpret_cast<void *>(EntityType_CreateGenericInstance); + } + + for (int64_t i = 0; i < detailCount; ++i) { + etPtr->details[i] = et.details[i]; + strncpy(etPtr->details[i].textureAssetKey, et.details[i].textureAssetKey, AssetKeyLength); } + + EntityType_Load(*etPtr); + + for (int64_t i = 0; i < detailCount; ++i) { + strncpy(etPtr->details[i].grBinds->collisionCallback.name, collisionSig, CallbackSignatureLength); + PkePlugin_SetSignatureFunc(&etPtr->details[i].grBinds->collisionCallback); + } + return; } if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_MODEL_ASSET_KEY)) { @@ -188,10 +210,15 @@ void Proj_ParseEntityType(std::ifstream &stream) { } if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE)) { uint64_t prefixLen = strlen(PKE_PROJ_FILE_ENTITY_TYPE_ENTITY_HANDLE); - STR2NUM_ERROR result = str2num(et.entityHandle.hash, projReadLine + prefixLen); + STR2NUM_ERROR result = str2num(et.handle.hash, projReadLine + prefixLen); assert(result == STR2NUM_ERROR::SUCCESS); continue; } + if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_CREATE_INSTANCE_CALLBACK_SIGNATURE)) { + uint64_t prefixLen = strlen(PKE_PROJ_FILE_ENTITY_TYPE_CREATE_INSTANCE_CALLBACK_SIGNATURE); + strncpy(createInstanceSig, projReadLine + prefixLen, CallbackSignatureLength + 1); + continue; + } if (strstr(projReadLine, PKE_PROJ_FILE_ENTITY_TYPE_DETAILS_BEGIN)) { EntityTypeDetails &etd = et.details[detailCount]; while (stream.getline(projReadLine, projReadLineLength)) { @@ -343,12 +370,18 @@ void PkeProject_Save(const char *filePath) { } } - for (long i = 0; i < GlobalEntityTypes.Count(); ++i) { - f << PKE_PROJ_FILE_OBJ_ENTITY_TYPE << std::endl; - const auto &et = GlobalEntityTypes[i]; - const CompGrBinds *grBinds = ECS_GetGrBinds(et.entityHandle); - Proj_SerializeEntityType(f, et); - f << PKE_PROJ_FILE_OBJ_END << std::endl; + const auto entBucketCount = EntityType_GetBucketCount(); + for (PkeHandleBucketIndex_T b = 0; b < entBucketCount; ++b) { + PkeHandleItemIndex_T itemCount = 0; + auto *entities = EntityType_GetEntityTypes(b, itemCount); + for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) { + if (entities[i].modelAssetKey[0] == '\0') { + continue; + } + f << PKE_PROJ_FILE_OBJ_ENTITY_TYPE << std::endl; + Proj_SerializeEntityType(f, entities[i]); + f << PKE_PROJ_FILE_OBJ_END << std::endl; + } } f << PKE_PROJ_FILE_END << std::endl; |
