feat: implemented camera controller
This commit is contained in:
parent
0f612b0bd6
commit
4704f9ca7b
10 changed files with 153 additions and 30 deletions
|
|
@ -51,7 +51,7 @@ Camera3D CameraNodeGetCamera(CameraNode *self) {
|
|||
Vector3 forward = MATRIX_FORWARD(mat);
|
||||
// construct a new camera at the global transform location and facing the forward vector
|
||||
return (Camera3D){
|
||||
.fovy = 70,
|
||||
.fovy = 90,
|
||||
.position = global_transform.translation,
|
||||
.projection = CAMERA_PERSPECTIVE,
|
||||
.target = Vector3Add(global_transform.translation, forward),
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ void InitializeRaylibContext() {
|
|||
InitWindow(1280, 800, "FOGD Engine");
|
||||
if(!IsWindowFullscreen())
|
||||
ToggleFullscreen();
|
||||
SetTargetFPS(120);
|
||||
SetTargetFPS(60);
|
||||
}
|
||||
|
||||
|
||||
void RunGame(Scene *initial_scene) {
|
||||
// set the main scene
|
||||
SwitchScene(initial_scene);
|
||||
|
|
|
|||
|
|
@ -5,18 +5,6 @@
|
|||
#include "utils/drop.h"
|
||||
#include "utils/mirror.h"
|
||||
|
||||
//! Tick a node and all children recursively
|
||||
static
|
||||
void Internal_SceneNodeTick(SceneNode *self, double delta) {
|
||||
// tick self first
|
||||
self->entity.tc->tick(self->entity.data, delta);
|
||||
// fix the number of elements to update now,
|
||||
// so that if/when new children are added, they don't get ticked until next frame
|
||||
size_t const len = self->children.len;
|
||||
for(size_t i = 0; i < len; ++i)
|
||||
Internal_SceneNodeTick(*list_at_as(SceneNode*, &self->children, i), delta);
|
||||
}
|
||||
|
||||
//! Update global transform of a node
|
||||
static
|
||||
void Internal_SceneNodeUpdateTransform(SceneNode *self) {
|
||||
|
|
@ -45,6 +33,19 @@ void Internal_SceneNodeUpdateTransformRecursive(SceneNode *self, bool is_dirty)
|
|||
Internal_SceneNodeUpdateTransformRecursive(*child, is_dirty);
|
||||
}
|
||||
|
||||
//! Tick a node and all children recursively
|
||||
static
|
||||
void Internal_SceneNodeTick(SceneNode *self, double delta) {
|
||||
// tick self first
|
||||
self->entity.tc->tick(self->entity.data, delta);
|
||||
// fix the number of elements to update now,
|
||||
// so that if/when new children are added, they don't get ticked until next frame
|
||||
size_t const len = self->children.len;
|
||||
for(size_t i = 0; i < len; ++i) {
|
||||
Internal_SceneNodeTick(*list_at_as(SceneNode*, &self->children, i), delta);
|
||||
}
|
||||
}
|
||||
|
||||
//! Remove a single node (does NOT recurse to children children) from this scene.
|
||||
static
|
||||
void Internal_SceneRemoveNode(Scene *self, SceneNode *node) {
|
||||
|
|
@ -181,6 +182,6 @@ void DestroyScene(Scene *self) {
|
|||
}
|
||||
|
||||
void SceneTick(Scene* self, double delta_time) {
|
||||
Internal_SceneNodeTick(self->root, delta_time);
|
||||
Internal_SceneNodeUpdateTransformRecursive(self->root, false);
|
||||
Internal_SceneNodeTick(self->root, delta_time);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ Vector3 TransformPosition(Transform self, Vector3 local_pos) {
|
|||
|
||||
Vector3 TransformDirection(Transform self, Vector3 local_direction) {
|
||||
Matrix const m = TransformGetMatrix(self);
|
||||
return Vector3Add(Vector3Add(Vector3Scale(MATRIX_RIGHT(m), local_direction.x), Vector3Scale(MATRIX_UP(m), local_direction.y)), Vector3Scale(MATRIX_FORWARD(m), local_direction.z));
|
||||
return Vector3Add(Vector3Add(Vector3Scale(MATRIX_RIGHT(m), local_direction.x),
|
||||
Vector3Scale(MATRIX_UP(m), local_direction.y)),
|
||||
Vector3Scale(MATRIX_FORWARD(m), local_direction.z));
|
||||
}
|
||||
|
||||
Vector3 TransformScale(Transform self, Vector3 local_scale) {
|
||||
|
|
@ -41,15 +43,15 @@ Transform TransformTransform(Transform self, Transform other) {
|
|||
}
|
||||
|
||||
Vector3 InverseTransformPosition(Transform self, Vector3 global_pos) {
|
||||
return Vector3Subtract(InverseTransformDirection(self, global_pos), self.translation);
|
||||
return InverseTransformDirection(self, Vector3Subtract(global_pos, self.translation));
|
||||
}
|
||||
|
||||
Vector3 InverseTransformDirection(Transform self, Vector3 global_direction) {
|
||||
Matrix const mat = TransformGetMatrix(self);
|
||||
return (Vector3){
|
||||
Vector3DotProduct(MATRIX_RIGHT(mat), Vector3Scale(VECTOR3_RIGHT, global_direction.x)),
|
||||
Vector3DotProduct(MATRIX_UP(mat), Vector3Scale(VECTOR3_UP, global_direction.y)),
|
||||
Vector3DotProduct(MATRIX_FORWARD(mat), Vector3Scale(VECTOR3_FORWARD, global_direction.z))
|
||||
Vector3DotProduct((Vector3){global_direction.x, 0.f, 0.f}, MATRIX_RIGHT(mat)),
|
||||
Vector3DotProduct((Vector3){0.f, global_direction.y, 0.f}, MATRIX_UP(mat)),
|
||||
Vector3DotProduct((Vector3){0.f, 0.f, global_direction.z}, MATRIX_FORWARD(mat))
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -68,3 +70,9 @@ Transform InverseTransformTransform(Transform self, Transform other) {
|
|||
.rotation = InverseTransformRotation(self, other.rotation)
|
||||
};
|
||||
}
|
||||
|
||||
float QuaternionAngleDifference(Quaternion a, Quaternion b) {
|
||||
Quaternion c = QuaternionMultiply(a, QuaternionInvert(b));
|
||||
return 2.f*asinf(Vector3Length((Vector3){c.x, c.y, c.z}));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ extern Vector3 InverseTransformScale(Transform self, Vector3 global_scale);
|
|||
extern Quaternion InverseTransformRotation(Transform self, Quaternion quat);
|
||||
extern Transform InverseTransformTransform(Transform self, Transform other);
|
||||
|
||||
extern float QuaternionAngleDifference(Quaternion a, Quaternion b);
|
||||
|
||||
#define MATRIX_RIGHT(self_) ((Vector3){self_.m0, self_.m1, self_.m2})
|
||||
#define MATRIX_UP(self_) ((Vector3){self_.m4, self_.m5, self_.m6})
|
||||
#define MATRIX_FORWARD(self_) ((Vector3){self_.m8, self_.m9, self_.m10})
|
||||
|
|
@ -60,7 +62,13 @@ extern Transform InverseTransformTransform(Transform self, Transform other);
|
|||
#define impl_Transformable_for(T)\
|
||||
static Transform T##_get_transform_GEN_(T* self) { return self->transform; }\
|
||||
static void T##_set_transform_GEN_(T* self, Transform value) { self->transform = value; self->dirty_bit = 1; } /*!< sets dirty bit */\
|
||||
static Transform T##_get_global_transform_GEN_(T* self) { return self->global_transform; }\
|
||||
static void T##_force_update_GEN_(T* self);\
|
||||
static Transform T##_get_global_transform_GEN_(T* self) {\
|
||||
if(self->dirty_bit) {\
|
||||
T##_force_update_GEN_(self);\
|
||||
}\
|
||||
return self->global_transform;\
|
||||
}\
|
||||
static void T##_set_global_transform_GEN_(T* self, Transform value) {\
|
||||
if(tc_is_null(self->parent_transformable)) {\
|
||||
self->transform = value;\
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue