summaryrefslogtreecommitdiff
path: root/src/camera.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2024-01-15 18:20:58 -0500
committerJonathan Bradley <jcb@pikum.xyz>2024-01-15 18:20:58 -0500
commitc30b1f9b2f5d231e98194db526560eb4e010edff (patch)
tree328825d5187f5f0b3ffd6754f8795f6a5947b8f7 /src/camera.cpp
parent05a6ca44e40da855a1ddc32cfe799edef74f7bdf (diff)
major refactor so cameras are entities and have a rigid body instance
Diffstat (limited to 'src/camera.cpp')
-rw-r--r--src/camera.cpp136
1 files changed, 132 insertions, 4 deletions
diff --git a/src/camera.cpp b/src/camera.cpp
index c7a861c..e66a6cf 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -1,26 +1,65 @@
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
#include "bucketed-array.hpp"
#include "camera.hpp"
+#include "ecs.hpp"
+#include "math-helpers.hpp"
#include "memory.hpp"
+#include "physics.hpp"
PkeCamera NullCamera {
- .handle = CameraHandle_MAX,
+ .camHandle = CameraHandle_MAX,
.pos = glm::vec3(3.f, 3.f, 3.f),
.rot = glm::quat(1.f, 0.f, 0.f, 0.f),
.target = glm::vec3(0.f),
.type = PKE_CAMERA_TYPE_ORTHOGONAL,
.orientation = PKE_CAMERA_ORIENTATION_TARGET,
.stale = PKE_CAMERA_STALE_ALL,
+ .phys = {
+ .inst = nullptr,
+ .constraint = nullptr,
+ },
};
PkeCamera *ActiveCamera = &NullCamera;
const PkeHandleItemIndex_T MAX_CAMERAS_PER_BUCKET = 32;
BucketContainer<PkeCamera, CameraHandle> Camera_BucketContainer{};
-PkeCamera &PkeCamera_Register() {
+btSphereShape CameraShape{1.f};
+
+PkeCamera &PkeCamera_Register(const InstPos &instPos) {
CameraHandle cameraHandle{Buckets_NewHandle(Camera_BucketContainer)};
+
auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
- cam.handle = cameraHandle;
+ new (&cam) PkeCamera{};
+
+ ECS_CreateEntity(&cam, nullptr);
+ cam.camHandle = cameraHandle;
+ cam.phys.inst = ECS_CreateInstance(&cam, nullptr);
+
+ btVector3 gravity(0.f, 0.f, 0.f);
+
+ cam.phys.inst->physicsLayer = PhysicsCollision{0};
+ cam.phys.inst->physicsMask = PhysicsCollision{0};
+
+ btVector3 localInertia(0, 0, 0);
+ CameraShape.calculateLocalInertia(instPos.mass, localInertia);
+ cam.phys.inst->bt.motionState = Pke_New<btDefaultMotionState>(MemBkt_Bullet);
+ new (cam.phys.inst->bt.motionState) btDefaultMotionState(instPos.posRot);
+
+ cam.phys.inst->bt.rigidBody = Pke_New<btRigidBody>(MemBkt_Bullet);
+ new (cam.phys.inst->bt.rigidBody) btRigidBody(instPos.mass, cam.phys.inst->bt.motionState, &CameraShape, localInertia);
+
+ cam.phys.inst->bt.rigidBody->setLinearVelocity(btVector3(0,0,0));
+ cam.phys.inst->bt.rigidBody->setAngularVelocity(btVector3(0,0,0));
+ cam.phys.inst->bt.rigidBody->getCollisionShape()->setLocalScaling(instPos.scale);
+ BtDynamicsWorld->addRigidBody(cam.phys.inst->bt.rigidBody);
+ cam.phys.inst->bt.rigidBody->setGravity(gravity);
+ cam.phys.inst->bt.rigidBody->getBroadphaseProxy()->m_collisionFilterGroup = static_cast<PhysicsCollision_T>(cam.phys.inst->physicsLayer);
+ cam.phys.inst->bt.rigidBody->getBroadphaseProxy()->m_collisionFilterMask = static_cast<PhysicsCollision_T>(cam.phys.inst->physicsMask);
+ cam.phys.inst->bt.rigidBody->setUserPointer(reinterpret_cast<void *>(cam.phys.inst));
+
return cam;
}
@@ -29,16 +68,68 @@ PkeCamera *PkeCamera_Get(CameraHandle cameraHandle) {
return &Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
}
+void PkeCamera_AttachToInstance(CameraHandle cameraHandle, CompInstance *inst) {
+ assert(cameraHandle != CameraHandle_MAX);
+ auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
+
+ btVector3 cameraOffset(0.f, -10.f, -10.f);
+
+ btTransform trfm;
+ inst->bt.motionState->getWorldTransform(trfm);
+ BulletToGlm(trfm.getOrigin(), cam.target);
+ trfm.setOrigin(trfm.getOrigin() + cameraOffset);
+ BulletToGlm(trfm.getOrigin(), cam.pos);
+
+ cam.phys.inst->bt.motionState->setWorldTransform(trfm);
+ cam.phys.inst->bt.rigidBody->setWorldTransform(trfm);
+ cam.phys.inst->bt.rigidBody->setLinearVelocity(btVector3(0,0,0));
+ cam.phys.inst->bt.rigidBody->setAngularVelocity(btVector3(0,0,0));
+ cam.phys.inst->bt.rigidBody->activate();
+
+ assert(cam.phys.constraint == nullptr || cam.phys.constraint == CAFE_BABE(btTypedConstraint));
+ cam.phys.constraint = Pke_New<btTypedConstraint>(MemBkt_Bullet);
+ new (cam.phys.constraint) btPoint2PointConstraint(*cam.phys.inst->bt.rigidBody, *inst->bt.rigidBody, btVector3(0.f, 0.f, 0.f), cameraOffset);
+ BtDynamicsWorld->addConstraint(cam.phys.constraint);
+
+ cam.orientation = PKE_CAMERA_ORIENTATION_TARGET;
+ cam.stale = PKE_CAMERA_STALE_POSROT;
+}
+
+void PkeCamera_DetachFromInstance(CameraHandle cameraHandle, CompInstance *inst) {
+ assert(cameraHandle != CameraHandle_MAX);
+ auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
+ BtDynamicsWorld->removeConstraint(cam.phys.constraint);
+ Pke_Delete<btTypedConstraint>(cam.phys.constraint, MemBkt_Bullet);
+ cam.phys.constraint = CAFE_BABE(btTypedConstraint);
+ cam.stale = PKE_CAMERA_STALE_POSROT;
+}
+
void PkeCamera_Destroy(CameraHandle cameraHandle) {
assert(cameraHandle != CameraHandle_MAX);
auto &cam = Camera_BucketContainer.buckets[cameraHandle.bucketIndex][cameraHandle.itemIndex];
- cam.handle = CameraHandle_MAX;
+
+ BtDynamicsWorld->removeRigidBody(cam.phys.inst->bt.rigidBody);
+ Pke_Delete<btRigidBody>(cam.phys.inst->bt.rigidBody, MemBkt_Bullet);
+ cam.phys.inst->bt.rigidBody = CAFE_BABE(btRigidBody);
+
+ Pke_Delete<btDefaultMotionState>(cam.phys.inst->bt.motionState, MemBkt_Bullet);
+ cam.phys.inst->bt.motionState = CAFE_BABE(btDefaultMotionState);
+
+ if (cam.phys.constraint != nullptr && cam.phys.constraint != CAFE_BABE(btTypedConstraint)) {
+ BtDynamicsWorld->removeConstraint(cam.phys.constraint);
+ Pke_Delete<btTypedConstraint>(cam.phys.constraint, MemBkt_Bullet);
+ }
+
+ ECS_MarkForRemoval(&cam);
+ cam.camHandle = CameraHandle_MAX;
cam.pos = glm::vec3(0);
cam.rot = glm::quat{};
cam.target = glm::vec3(0);
cam.type = PkeCameraType_MAX;
cam.orientation = PkeCameraOrientation_MAX;
cam.stale = PkeCameraStaleFlags_MAX;
+ cam.phys.inst = CAFE_BABE(CompInstance);
+ cam.phys.constraint = CAFE_BABE(btTypedConstraint);
}
int64_t PkeCamera_GetBucketCount() {
@@ -62,3 +153,40 @@ void PkeCamera_Teardown() {
Buckets_Destroy(Camera_BucketContainer);
}
+void PkeCamera_Tick(double delta) {
+ /*
+ for (PkeHandleBucketIndex_T b = 0; b <= Camera_BucketContainer.pkeHandle.bucketIndex; ++b) {
+ auto &bkt = Camera_BucketContainer.buckets[b];
+ long itemCount = Camera_BucketContainer.pkeHandle.bucketIndex == b ? Camera_BucketContainer.pkeHandle.itemIndex : Camera_BucketContainer.limits.itemIndex;
+ for (PkeHandleItemIndex_T i = 0; i < itemCount; ++i) {
+ auto &cam = bkt[i];
+ if (cam.handle == EntityHandle_MAX) {
+ continue;
+ }
+ btTransform trfm;
+ if (cam.phys.constraint != nullptr && cam.phys.constraint != CAFE_BABE(btTypedConstraint)) {
+ cam.phys.constraint->getRigidBodyB().getMotionState()->getWorldTransform(trfm);
+ BulletToGlm(trfm.getOrigin(), cam.target);
+ }
+ cam.phys.inst->bt.motionState->getWorldTransform(trfm);
+ BulletToGlm(trfm.getOrigin(), cam.pos);
+ cam.stale = cam.stale | PKE_CAMERA_STALE_POSROT;
+ cam.phys.inst->isNeedingUpdated = false;
+ }
+ }
+ */
+ btTransform trfm;
+ if (ActiveCamera->phys.constraint != nullptr && ActiveCamera->phys.constraint != CAFE_BABE(btTypedConstraint)) {
+ ActiveCamera->phys.constraint->getRigidBodyB().getMotionState()->getWorldTransform(trfm);
+ BulletToGlm(trfm.getOrigin(), ActiveCamera->target);
+ ActiveCamera->stale = ActiveCamera->stale | PKE_CAMERA_STALE_ROT;
+ }
+ if (ActiveCamera->phys.inst != nullptr && ActiveCamera->phys.inst != CAFE_BABE(CompInstance)) {
+ ActiveCamera->phys.inst->bt.motionState->getWorldTransform(trfm);
+ BulletToGlm(trfm.getOrigin(), ActiveCamera->pos);
+ BulletToGlm(trfm.getRotation(), ActiveCamera->rot);
+ ActiveCamera->stale = ActiveCamera->stale | PKE_CAMERA_STALE_POSROT;
+ ActiveCamera->phys.inst->isNeedingUpdated = false;
+ }
+}
+