diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2023-10-31 12:46:09 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2023-11-15 13:13:25 -0500 |
| commit | f2c808b1235b9d76e4d4753c025f404e7736ca3c (patch) | |
| tree | 34100f4a05d6feb40474c50f1d3539611b0016ba | |
| parent | 18e65823663af6e2a1472b66486526a23d5e9c30 (diff) | |
use model for collision + refactor physics init and rigidbody creation
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/components.hpp | 15 | ||||
| -rw-r--r-- | src/ecs.cpp | 74 | ||||
| -rw-r--r-- | src/ecs.hpp | 2 | ||||
| -rw-r--r-- | src/entities.cpp | 14 | ||||
| -rw-r--r-- | src/entities.hpp | 4 | ||||
| -rw-r--r-- | src/game.cpp | 47 | ||||
| -rw-r--r-- | src/main.cpp | 3 | ||||
| -rw-r--r-- | src/physics.cpp | 90 | ||||
| -rw-r--r-- | src/physics.hpp | 15 |
10 files changed, 189 insertions, 77 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 22de8fc..c921388 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,8 @@ set(PKE_SOURCE_FILES src/dynamic-array.cpp src/asset-manager.hpp src/asset-manager.cpp + src/physics.hpp + src/physics.cpp src/player-input.hpp src/player-input.cpp src/static/cube.hpp diff --git a/src/components.hpp b/src/components.hpp index 0903492..a8b4e88 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -4,9 +4,8 @@ #include "macros.hpp" #include "dynamic-array.hpp" -#include <BulletCollision/CollisionShapes/btCollisionShape.h> -#include <LinearMath/btDefaultMotionState.h> #include <BulletDynamics/Dynamics/btRigidBody.h> +#include <LinearMath/btDefaultMotionState.h> #include <vulkan/vulkan_core.h> const uint64_t ECS_UNSET_VAL = 0xFFFFFFFFFFFFFFFF; @@ -57,18 +56,16 @@ struct InstPos { btTransform posRot; btVector3 scale; }; - +struct InstBt { + btDefaultMotionState *motionState; + btRigidBody *rigidBody; +}; struct CompInstance { EntityHandle entHandle = EntityHandle_MAX; GrBindsHandle grBindsHandle = GrBindsHandle_MAX; InstanceHandle instanceHandle = InstanceHandle_MAX; uint64_t index = ECS_UNSET_VAL; - struct { - btVector3 localInertia; - btCollisionShape *collisionShape; - btDefaultMotionState defaultMotionState; - btRigidBody *rigidBody; - } bt; + InstBt bt; bool isNeedingUpdated = false; }; diff --git a/src/ecs.cpp b/src/ecs.cpp index b5b0ce4..654bc71 100644 --- a/src/ecs.cpp +++ b/src/ecs.cpp @@ -4,10 +4,12 @@ #include "game-settings.hpp" #include "math-helpers.hpp" #include "memory.hpp" +#include "physics.hpp" #include "vendor/glm_include.hpp" #include "window.hpp" #include <btBulletDynamicsCommon.h> +#include <BulletCollision/CollisionShapes/btConvexHullShape.h> #include <glm/gtc/type_ptr.hpp> TypeSafeInt_B(EntityHandle); @@ -34,13 +36,6 @@ BucketContainer<EntityBucket, EntityHandle_T> Entities_BucketContainer{}; BucketContainer<GrBindsBucket, GrBindsHandle_T> Comp_GrBinds_BucketContainer{}; BucketContainer<InstanceBucket, InstanceHandle_T> Comp_Instance_BucketContainer{}; -MemBucket *bulletBucket = nullptr; -btDefaultCollisionConfiguration *btConfiguration = nullptr; -btCollisionDispatcher *btDispatcher = nullptr; -btBroadphaseInterface *btBroadphase = nullptr; -btConstraintSolver *btSolver = nullptr; -btDiscreteDynamicsWorld *btDynamicsWorld = nullptr; - void ECS_GetEntity_Inner(EntityHandle entHandle, Entity*& ent) { EntityHandle_T entHandle_t{static_cast<EntityHandle_T>(entHandle)}; assert(entHandle_t != EntityHandle_T_MAX && "Unknown entity handle"); @@ -53,19 +48,6 @@ void ECS_Init() { Buckets_Init(Entities_BucketContainer); Buckets_Init(Comp_GrBinds_BucketContainer); Buckets_Init(Comp_Instance_BucketContainer); - // bullet - { - bulletBucket = Pke_BeginTransientBucket(); - btConfiguration = Pke_New<btDefaultCollisionConfiguration>(bulletBucket); - btDispatcher = Pke_New<btCollisionDispatcher>(bulletBucket); - new (btDispatcher) btCollisionDispatcher(btConfiguration); - btBroadphase = Pke_New<btDbvtBroadphase>(bulletBucket); - btSolver = Pke_New<btSequentialImpulseConstraintSolver>(bulletBucket); - btDynamicsWorld = Pke_New<btDiscreteDynamicsWorld>(bulletBucket); - new (btDynamicsWorld) btDiscreteDynamicsWorld(btDispatcher, btBroadphase, btSolver, btConfiguration); - auto grav = btDynamicsWorld->getGravity(); - btDynamicsWorld->setGravity(btVector3(grav.getX(), grav.getZ(), grav.getY())); - } } uint64_t ECS_GetEntities_BucketCount() { @@ -182,20 +164,18 @@ void ECS_Tick_Early(double delta) { } void ECS_Tick(double delta) { - if (btDynamicsWorld && pkeSettings.isSimulationPaused == false) { - auto physicsTickCount = btDynamicsWorld->stepSimulation(delta, 0); - if (physicsTickCount != 0) { - for (long b = 0; b <= Comp_Instance_BucketContainer.bucketCounter; ++b) { - auto &bkt = Comp_Instance_BucketContainer.buckets[b]; - long count = Comp_Instance_BucketContainer.bucketCounter == b ? Comp_Instance_BucketContainer.itemCounter >> 32 : maxBucketItemCount; - for (uint32_t i = 0; i < count; ++i) { - auto &inst = bkt.instances[i]; - auto activationState = inst.bt.rigidBody->getActivationState(); - if (activationState == ISLAND_SLEEPING || activationState == DISABLE_SIMULATION || activationState == WANTS_DEACTIVATION) { - continue; - } - inst.isNeedingUpdated = true; + int32_t physicsTickCount = Physics_Tick(delta); + if (physicsTickCount != 0) { + for (long b = 0; b <= Comp_Instance_BucketContainer.bucketCounter; ++b) { + auto &bkt = Comp_Instance_BucketContainer.buckets[b]; + long count = Comp_Instance_BucketContainer.bucketCounter == b ? Comp_Instance_BucketContainer.itemCounter >> 32 : maxBucketItemCount; + for (uint32_t i = 0; i < count; ++i) { + auto &inst = bkt.instances[i]; + auto activationState = inst.bt.rigidBody->getActivationState(); + if (activationState == ISLAND_SLEEPING || activationState == DISABLE_SIMULATION || activationState == WANTS_DEACTIVATION) { + continue; } + inst.isNeedingUpdated = true; } } } @@ -258,13 +238,13 @@ void ECS_Tick_Late(double delta) { } btTransform btMatrix_posRot; - inst.bt.defaultMotionState.getWorldTransform(btMatrix_posRot); + inst.bt.motionState->getWorldTransform(btMatrix_posRot); float openglMatrix[16]; btMatrix_posRot.getOpenGLMatrix(openglMatrix); glm::mat4 glmMat_posRot = glm::make_mat4(openglMatrix); glm::vec3 scale; - BulletToGlm(inst.bt.collisionShape->getLocalScaling(), scale); + BulletToGlm(inst.bt.rigidBody->getCollisionShape()->getLocalScaling(), scale); chunk->mats.Push(glm::scale(glmMat_posRot, scale)); bfrUpdate->runningSize += sizeof(glm::mat4); @@ -365,7 +345,7 @@ CompGrBinds *ECS_GetGrBinds(uint64_t bucketIndex, uint64_t &itemCount) { return Comp_GrBinds_BucketContainer.buckets[bucketIndex].compGrBinds; } -CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityTypeEntityHandle, const InstPos &instPos) { +CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityTypeEntityHandle) { assert(entHandle != EntityHandle_MAX); assert(entityTypeEntityHandle != EntityHandle_MAX); @@ -401,20 +381,6 @@ CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityType EntitiesWithExcessInstances.Push(grBinds->entHandle); } - if (btDynamicsWorld) { - comp->bt.localInertia = btVector3(0, 0, 0); - comp->bt.collisionShape = Pke_New<btBoxShape>(bulletBucket); - new (comp->bt.collisionShape) btBoxShape(instPos.scale); - comp->bt.collisionShape->calculateLocalInertia(btScalar(1.f), comp->bt.localInertia); - comp->bt.defaultMotionState = btDefaultMotionState(instPos.posRot); - comp->bt.rigidBody = Pke_New<btRigidBody>(bulletBucket); - new (comp->bt.rigidBody) btRigidBody(btScalar(1.f), &comp->bt.defaultMotionState, comp->bt.collisionShape, comp->bt.localInertia); - comp->bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); - comp->bt.rigidBody->setAngularVelocity(btVector3(0,0,0)); - btDynamicsWorld->addRigidBody(comp->bt.rigidBody); - comp->bt.rigidBody->setUserPointer(reinterpret_cast<void *>(comp->entHandle)); - } - return *comp; } @@ -445,14 +411,13 @@ void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos, bool ove auto i = Buckets_GetItemIndex(instanceHandle_t); auto *inst = &Comp_Instance_BucketContainer.buckets[b].instances[i]; - if (btDynamicsWorld && overridePhysics) { + if (BtDynamicsWorld && overridePhysics) { inst->bt.rigidBody->setWorldTransform(instPos.posRot); - inst->bt.collisionShape->setLocalScaling(instPos.scale); + inst->bt.rigidBody->getCollisionShape()->setLocalScaling(instPos.scale); inst->bt.rigidBody->setLinearVelocity(btVector3(0,0,0)); inst->bt.rigidBody->setAngularVelocity(btVector3(0,0,0)); - btDynamicsWorld->getPairCache()->cleanProxyFromPairs(inst->bt.rigidBody->getBroadphaseProxy(), btDynamicsWorld->getDispatcher()); + BtDynamicsWorld->getPairCache()->cleanProxyFromPairs(inst->bt.rigidBody->getBroadphaseProxy(), BtDynamicsWorld->getDispatcher()); inst->bt.rigidBody->activate(); - inst->isNeedingUpdated = true; } } @@ -471,7 +436,6 @@ CompInstance *ECS_GetInstances(uint64_t bucketIndex, uint64_t &itemCount) { } void ECS_Teardown() { - Pke_EndTransientBucket(bulletBucket); EntitiesWithExcessInstances.~DynArray(); entitiesYetToBeRemoved.~DynArray(); EntitiesToBeRemoved.~DynArray(); diff --git a/src/ecs.hpp b/src/ecs.hpp index 4a10b3a..480ba0c 100644 --- a/src/ecs.hpp +++ b/src/ecs.hpp @@ -32,7 +32,7 @@ CompGrBinds *ECS_GetGrBinds(EntityHandle entHandle); uint64_t ECS_GetGrBinds_BucketCount(); CompGrBinds *ECS_GetGrBinds(uint64_t bucketIndex, uint64_t &itemCount); -CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityTypeEntityHandle, const InstPos &instPos); +CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityTypeEntityHandle); CompInstance *ECS_GetInstance(EntityHandle entHandle); void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos, bool overridePhysics = false); uint64_t ECS_GetInstances_BucketCount(); diff --git a/src/entities.cpp b/src/entities.cpp index a9108a0..c06aa3c 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -1,7 +1,10 @@ #include "entities.hpp" -#include <vulkan/vulkan_core.h> +#include "physics.hpp" + +#include <BulletCollision/CollisionShapes/btConvexHullShape.h> + DynArray<EntityType> GlobalEntityTypes{16}; void EntityType_Init() { @@ -546,7 +549,6 @@ void EntityType_Load(EntityType &et) { srcPtr = static_cast<char *>(gltfData->buffers[0].data) + accIndex.buffer_view->offset; memcpy(dstPtr, srcPtr, accIndex.buffer_view->size); - VkCommandBufferBeginInfo vkCommandBufferBeginInfo; vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; vkCommandBufferBeginInfo.pNext = nullptr; @@ -610,6 +612,14 @@ void EntityType_Load(EntityType &et) { vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &et.deviceMemoryInst); vkBindBufferMemory(vkDevice, grBinds.instanceBuffer, et.deviceMemoryInst, 0); + // bullet + { + et.bt.shape = Pke_New<btConvexHullShape>(MemBkt_Bullet); + btScalar *vertDataPointer = reinterpret_cast<btScalar *>(accVert.buffer_view->buffer->data); + vertDataPointer += accVert.buffer_view->offset; + new (et.bt.shape) btConvexHullShape(vertDataPointer, accVert.count, accVert.stride); + } + // cleanup cgltf_free(gltfData); AM_Destroy(assetHandle); diff --git a/src/entities.hpp b/src/entities.hpp index 4c5b498..f45f7d3 100644 --- a/src/entities.hpp +++ b/src/entities.hpp @@ -9,6 +9,7 @@ #include "memory.hpp" #include "window.hpp" +#include <BulletCollision/CollisionShapes/btCollisionShape.h> #include <vulkan/vulkan_core.h> struct EntityType { @@ -30,6 +31,9 @@ struct EntityType { int16_t AccessorIndexUV = -1; int16_t AccessorIndexIndex = -1; } Importer_GLTF; + struct { + btCollisionShape *shape = nullptr; + } bt; }; extern DynArray<EntityType> GlobalEntityTypes; diff --git a/src/game.cpp b/src/game.cpp index f0fac6c..6cde580 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,6 +1,7 @@ #include "game.hpp" +#include "BulletCollision/CollisionShapes/btConvexHullShape.h" #include "camera.hpp" #include "components.hpp" #include "dynamic-array.hpp" @@ -9,6 +10,7 @@ #include "helpers.hpp" #include "imgui.h" #include "math-helpers.hpp" +#include "physics.hpp" #include "player-input.hpp" #include "vendor/glm_include.hpp" #include "window.hpp" @@ -138,8 +140,8 @@ void SerializeInstance(std::ofstream &stream, const CompInstance &comp) { stream << PKE_FILE_INSTANCE_ENTITY_TYPE_CODE << et->entityTypeCode << std::endl; btTransform trans; - comp.bt.defaultMotionState.getWorldTransform(trans); - btVector3 scale = comp.bt.collisionShape->getLocalScaling(); + comp.bt.motionState->getWorldTransform(trans); + btVector3 scale = comp.bt.rigidBody->getCollisionShape()->getLocalScaling(); if (trans != baseInst.posRot) { btVector3 pos = trans.getOrigin(); btQuaternion rot = trans.getRotation(); @@ -262,7 +264,19 @@ void ParseInstance(std::ifstream &stream) { } const auto &et = GlobalEntityTypes[existingEntityTypeIndex]; auto entityHandle = ECS_CreateEntity(); - ECS_CreateInstance(entityHandle, et.entityHandle, instPos); + auto &compInst = ECS_CreateInstance(entityHandle, et.entityHandle); + + btVector3 localInertia(0, 0, 0); + et.bt.shape->calculateLocalInertia(btScalar(1.f), 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(btScalar(1.f), compInst.bt.motionState, et.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); + compInst.bt.rigidBody->setUserPointer(reinterpret_cast<void *>(compInst.entHandle)); break; } if (strstr(readLine, PKE_FILE_INSTANCE_ENTITY_HANDLE)) { @@ -438,12 +452,25 @@ void Game_Tick(double delta) { } while (entityInstancesToCreate.Count() > 0) { auto createInfo = entityInstancesToCreate.Pop(); + // TODO needs to be more elegant + int64_t etIndex = EntityType_FindByEntityHandle(createInfo.entityTypeEntityHandle); + auto &et = GlobalEntityTypes[etIndex]; EntityHandle newEntity = ECS_CreateEntity(); - InstPos instPos; - instPos.posRot = btTransform{}; - instPos.posRot.setIdentity(); - instPos.scale = btVector3(1, 1, 1); - ECS_CreateInstance(newEntity, createInfo.entityTypeEntityHandle, instPos); + auto &compInst = ECS_CreateInstance(newEntity, createInfo.entityTypeEntityHandle); + + btVector3 localInertia(0, 0, 0); + et.bt.shape->calculateLocalInertia(btScalar(1.f), 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(btScalar(1.f), compInst.bt.motionState, et.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->setUserPointer(reinterpret_cast<void *>(compInst.entHandle)); } PkeInput_Tick(delta); @@ -834,8 +861,8 @@ void RecordImGui_CompInstPos(bool readonly, CompInstance *component) { bool changed = false; InstPos instPos; - component->bt.defaultMotionState.getWorldTransform(instPos.posRot); - instPos.scale = component->bt.collisionShape->getLocalScaling(); + component->bt.motionState->getWorldTransform(instPos.posRot); + instPos.scale = component->bt.rigidBody->getCollisionShape()->getLocalScaling(); btVector3 pos = instPos.posRot.getOrigin(); btQuaternion rot = instPos.posRot.getRotation(); diff --git a/src/main.cpp b/src/main.cpp index c8c8a0d..045fdfe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include <thread> #include <csignal> +#include "physics.hpp" #include "player-input.hpp" #include "asset-manager.hpp" #include "ecs.hpp" @@ -32,6 +33,7 @@ int main() { fprintf(stdout, "PKE ENTERING\n"); try { AM_Init(); + Physics_Init(); Game_Init(); ECS_Init(); CreateWindow(&windowProps); @@ -126,6 +128,7 @@ int main() { Event_Teardown(); EntityType_Teardown(); PkeInput_Teardown(); + Physics_Teardown(); ECS_Teardown(); AM_DebugPrint(); AM_Teardown(); diff --git a/src/physics.cpp b/src/physics.cpp new file mode 100644 index 0000000..b8d093d --- /dev/null +++ b/src/physics.cpp @@ -0,0 +1,90 @@ + +#include "physics.hpp" + +#include "dynamic-array.hpp" +#include "game-settings.hpp" + +#include <btBulletDynamicsCommon.h> +#include <LinearMath/btAlignedAllocator.h> + +MemBucket *MemBkt_Bullet = nullptr; +btDiscreteDynamicsWorld *BtDynamicsWorld = nullptr; + +struct AllocedData { + void *data; + std::size_t size; +}; +DynArray<AllocedData> *bulletAllocs; + +btDefaultCollisionConfiguration *btConfiguration = nullptr; +btCollisionDispatcher *btDispatcher = nullptr; +btBroadphaseInterface *btBroadphase = nullptr; +btConstraintSolver *btSolver = nullptr; + +void *pke_btAlignedAllocFunc(size_t size, int alignment) { + void *ptr = Pke_New(size, alignment, MemBkt_Bullet); + bulletAllocs->Push({ptr, size}); + return ptr; +} +void pke_btAlignedFreeFunc(void *memBlock) { + auto &arr = *bulletAllocs; + auto count = arr.Count(); + long index = -1; + for (long i = 0; i < count; ++i) { + if (arr[i].data == memBlock) { + index = i; + break; + } + } + assert(index != -1); + Pke_Delete(const_cast<void *>(memBlock), arr[index].size, MemBkt_Bullet); + bulletAllocs->Remove(index); +} +void *pke_btAllocFunc(size_t size) { + void *ptr = Pke_New(size, MINIMUM_ALIGNMENT, MemBkt_Bullet); + bulletAllocs->Push({ptr, size}); + return ptr; +} +void pke_btFreeFunc(void *memBlock) { + auto &arr = *bulletAllocs; + auto count = arr.Count(); + long index = -1; + for (long i = 0; i < count; ++i) { + if (arr[i].data == memBlock) { + index = i; + break; + } + } + assert(index != -1); + Pke_Delete(const_cast<void *>(memBlock), arr[index].size, MemBkt_Bullet); + bulletAllocs->Remove(index); +} + +void Physics_Init() { + MemBkt_Bullet = Pke_BeginTransientBucket(); + bulletAllocs = Pke_New<DynArray<AllocedData>>(MemBkt_Bullet); + new (bulletAllocs) DynArray<AllocedData>(MemBkt_Bullet); + bulletAllocs->Reserve(1024); + btAlignedAllocSetCustom(pke_btAllocFunc, pke_btFreeFunc); + btAlignedAllocSetCustomAligned(pke_btAlignedAllocFunc, pke_btAlignedFreeFunc); + + btConfiguration = Pke_New<btDefaultCollisionConfiguration>(MemBkt_Bullet); + btDispatcher = Pke_New<btCollisionDispatcher>(MemBkt_Bullet); + new (btDispatcher) btCollisionDispatcher(btConfiguration); + btBroadphase = Pke_New<btDbvtBroadphase>(MemBkt_Bullet); + btSolver = Pke_New<btSequentialImpulseConstraintSolver>(MemBkt_Bullet); + BtDynamicsWorld = Pke_New<btDiscreteDynamicsWorld>(MemBkt_Bullet); + new (BtDynamicsWorld) btDiscreteDynamicsWorld(btDispatcher, btBroadphase, btSolver, btConfiguration); + auto grav = BtDynamicsWorld->getGravity(); + BtDynamicsWorld->setGravity(btVector3(grav.getX(), grav.getZ(), grav.getY())); +} + +int32_t Physics_Tick(double delta) { + if (pkeSettings.isSimulationPaused == true) + return 0; + return BtDynamicsWorld->stepSimulation(delta, 0); +} + +void Physics_Teardown() { + Pke_EndTransientBucket(MemBkt_Bullet); +} diff --git a/src/physics.hpp b/src/physics.hpp new file mode 100644 index 0000000..3d41ab7 --- /dev/null +++ b/src/physics.hpp @@ -0,0 +1,15 @@ +#ifndef PKE_PHYSICS_HPP +#define PKE_PHYSICS_HPP + +#include "memory.hpp" + +#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h> + +extern MemBucket *MemBkt_Bullet; +extern btDiscreteDynamicsWorld *BtDynamicsWorld; + +void Physics_Init(); +int32_t Physics_Tick(double delta); +void Physics_Teardown(); + +#endif /* PKE_PHYSICS_HPP */ |
