fogd-engine/src/core/camera_node.c
2024-09-13 11:27:28 +02:00

61 lines
2 KiB
C

#include "camera_node.h"
#include "utils/typeclass_helpers.h"
#include "utils/debug.h"
START_REFLECT(CameraNode);
REFLECT_TYPECLASS(CameraNode, Drop);
REFLECT_TYPECLASS(CameraNode, SceneNodeEntity);
END_REFLECT(CameraNode);
impl_Drop_for(CameraNode,
DestroyCameraNode
)
impl_SceneNodeEntity_defaults(CameraNode);
impl_SceneNodeEntity_for(CameraNode,
CameraNodeEnterTree,
CameraNode_default_exit_tree,
CameraNode_default_tick
)
SceneNode *CreateCameraNode() {
CameraNode *self = new(CameraNode);
return CreateSceneNode(CameraNode_as_SceneNodeEntity(self));
}
void DestroyCameraNode(CameraNode *self) {
SceneNodeDetachEntity(self->node);
free(self);
}
void CameraNodeEnterTree(CameraNode *self) {
// register self as main camera if none are selected yet
if(self->node->scene->main_camera == NULL)
self->node->scene->main_camera = self;
// get parent transformable object
self->transform = TC_CAST(self->node->parent->entity, Transformable);
ASSERT_RETURN(!tc_is_null(self->transform),, "CameraNodeEnterTree: Camera node HAS TO be the child of a transformable node.");
}
void CameraNodeExitTree(CameraNode *self) {
// if this is the current main camera, set the main camera to null
if(self->node->scene->main_camera == self)
self->node->scene->main_camera = NULL;
}
Camera3D CameraNodeGetCamera(CameraNode *self) {
// Get the global transform matrix of the parent transformable
Transform global_transform = self->transform.tc->get_global_transform(self->transform.data);
Matrix mat = TransformGetMatrix(&global_transform);
// get the forward row from the matrix
Vector3 forward = MATRIX_FORWARD(mat);
// construct a new camera at the global transform location and facing the forward vector
return (Camera3D){
.fovy = 90,
.position = global_transform.translation,
.projection = CAMERA_PERSPECTIVE,
.target = Vector3Add(global_transform.translation, Vector3Scale(forward, 1000.f)),
.up = (Vector3){mat.m4, mat.m5, mat.m6}
};
}