feat: implemented transform hierarchy
This commit is contained in:
parent
48d66b946b
commit
67bd8017c5
|
@ -1,19 +1,15 @@
|
||||||
#include "camera_node.h"
|
#include "camera_node.h"
|
||||||
|
#include "utils/typeclass_helpers.h"
|
||||||
#include "utils/debug.h"
|
#include "utils/debug.h"
|
||||||
|
|
||||||
START_REFLECT(CameraNode);
|
START_REFLECT(CameraNode);
|
||||||
REFLECT_TYPECLASS(CameraNode, Drop);
|
REFLECT_TYPECLASS(CameraNode, Drop);
|
||||||
REFLECT_TYPECLASS(CameraNode, Transformable);
|
|
||||||
REFLECT_TYPECLASS(CameraNode, SceneNodeEntity);
|
REFLECT_TYPECLASS(CameraNode, SceneNodeEntity);
|
||||||
END_REFLECT(CameraNode);
|
END_REFLECT(CameraNode);
|
||||||
|
|
||||||
impl_Drop_for(CameraNode,
|
impl_Drop_for(CameraNode,
|
||||||
DestroyCameraNode
|
DestroyCameraNode
|
||||||
)
|
)
|
||||||
impl_Transformable_for(CameraNode,
|
|
||||||
CameraNodeGetTransform,
|
|
||||||
CameraNodeGetGlobalTransform
|
|
||||||
)
|
|
||||||
|
|
||||||
impl_SceneNodeEntity_defaults(CameraNode);
|
impl_SceneNodeEntity_defaults(CameraNode);
|
||||||
impl_SceneNodeEntity_for(CameraNode,
|
impl_SceneNodeEntity_for(CameraNode,
|
||||||
|
@ -23,11 +19,8 @@ impl_SceneNodeEntity_for(CameraNode,
|
||||||
)
|
)
|
||||||
|
|
||||||
SceneNode *CreateCameraNode() {
|
SceneNode *CreateCameraNode() {
|
||||||
CameraNode *camera_node = new(CameraNode);
|
CameraNode *self = new(CameraNode);
|
||||||
camera_node->transform = TransformIdentity();
|
return CreateSceneNode(CameraNode_as_SceneNodeEntity(self));
|
||||||
camera_node->global_transform = TransformIdentity();
|
|
||||||
camera_node->node = NULL;
|
|
||||||
return CreateSceneNode(CameraNode_as_SceneNodeEntity(camera_node));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyCameraNode(CameraNode *self) {
|
void DestroyCameraNode(CameraNode *self) {
|
||||||
|
@ -36,24 +29,20 @@ void DestroyCameraNode(CameraNode *self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraNodeEnterTree(CameraNode *self) {
|
void CameraNodeEnterTree(CameraNode *self) {
|
||||||
if(self->node->scene->main_camera == NULL) {
|
if(self->node->scene->main_camera == NULL)
|
||||||
self->node->scene->main_camera = self;
|
self->node->scene->main_camera = self;
|
||||||
LOG_INFO("CameraNodeEnterTree");
|
self->transform = TC_CAST(self->node->parent->entity, Transformable);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera3D CameraNodeGetCamera(CameraNode *self) {
|
Camera3D CameraNodeGetCamera(CameraNode *self) {
|
||||||
Matrix mat = TransformGetMatrix(&self->global_transform);
|
Transform global_transform = self->transform.tc->get_global_transform(self->transform.data);
|
||||||
|
Matrix mat = TransformGetMatrix(&global_transform);
|
||||||
Vector3 forward = { mat.m8, mat.m9, mat.m10 };
|
Vector3 forward = { mat.m8, mat.m9, mat.m10 };
|
||||||
LOG_INFO("Forward: %f, %f, %f", forward.x, forward.y, forward.z);
|
|
||||||
return (Camera3D){
|
return (Camera3D){
|
||||||
.fovy = 90,
|
.fovy = 90,
|
||||||
.position = self->global_transform.translation,
|
.position = global_transform.translation,
|
||||||
.projection = CAMERA_PERSPECTIVE,
|
.projection = CAMERA_PERSPECTIVE,
|
||||||
.target = Vector3Add(self->global_transform.translation, Vector3Scale(forward, 1000.f)),
|
.target = Vector3Add(global_transform.translation, Vector3Scale(forward, 1000.f)),
|
||||||
.up = (Vector3){mat.m4, mat.m5, mat.m6}
|
.up = (Vector3){mat.m4, mat.m5, mat.m6}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform *CameraNodeGetTransform(CameraNode *self) { return &self->transform; }
|
|
||||||
Transform *CameraNodeGetGlobalTransform(CameraNode *self) { return &self->global_transform; }
|
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
|
|
||||||
typedef struct CameraNode {
|
typedef struct CameraNode {
|
||||||
SceneNode *node;
|
SceneNode *node;
|
||||||
Transform transform;
|
Transformable transform;
|
||||||
Transform global_transform;
|
|
||||||
} CameraNode;
|
} CameraNode;
|
||||||
|
|
||||||
extern SceneNode *CreateCameraNode();
|
extern SceneNode *CreateCameraNode();
|
||||||
|
@ -20,12 +19,8 @@ extern void CameraNodeEnterTree(CameraNode *self);
|
||||||
|
|
||||||
extern Camera3D CameraNodeGetCamera(CameraNode *self);
|
extern Camera3D CameraNodeGetCamera(CameraNode *self);
|
||||||
|
|
||||||
extern Transform *CameraNodeGetTransform(CameraNode *self);
|
|
||||||
extern Transform *CameraNodeGetGlobalTransform(CameraNode *self);
|
|
||||||
|
|
||||||
DECL_REFLECT(CameraNode)
|
DECL_REFLECT(CameraNode)
|
||||||
decl_typeclass_impl(Drop, CameraNode)
|
decl_typeclass_impl(Drop, CameraNode)
|
||||||
decl_typeclass_impl(Transformable, CameraNode)
|
|
||||||
decl_typeclass_impl(SceneNodeEntity, CameraNode)
|
decl_typeclass_impl(SceneNodeEntity, CameraNode)
|
||||||
|
|
||||||
#endif // !CAMERA_NODE_H
|
#endif // !CAMERA_NODE_H
|
||||||
|
|
|
@ -35,6 +35,8 @@ void InitializeEngine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShutDown() {
|
void ShutDown() {
|
||||||
|
if(GetMainScene() != NULL)
|
||||||
|
DestroyScene(GetMainScene());
|
||||||
CleanResourceSubsystem();
|
CleanResourceSubsystem();
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "scene_node_entity.h"
|
#include "scene_node_entity.h"
|
||||||
|
#include "transformable.h"
|
||||||
#include "utils/debug.h"
|
#include "utils/debug.h"
|
||||||
#include "utils/drop.h"
|
#include "utils/drop.h"
|
||||||
#include "utils/mirror.h"
|
#include "utils/mirror.h"
|
||||||
|
@ -60,6 +61,19 @@ void Internal_SceneNodeTick(SceneNode *self, double delta) {
|
||||||
Internal_SceneNodeTick(*list_at_as(SceneNode*, &self->children, i), delta);
|
Internal_SceneNodeTick(*list_at_as(SceneNode*, &self->children, i), delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Update global transforms of all children recursively
|
||||||
|
static
|
||||||
|
void Internal_SceneNodeUpdateTransform(SceneNode *self) {
|
||||||
|
if(TC_MIRRORS(self->entity, Transformable)) {
|
||||||
|
Transformable transformable = TC_CAST(self->entity, Transformable);
|
||||||
|
if(transformable.tc->get_dirty_bit(transformable.data)) {
|
||||||
|
transformable.tc->force_update(transformable.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list_foreach(SceneNode **,child, &self->children)
|
||||||
|
Internal_SceneNodeUpdateTransform(*child);
|
||||||
|
}
|
||||||
|
|
||||||
SceneNode *CreateSceneNode(SceneNodeEntity entity) {
|
SceneNode *CreateSceneNode(SceneNodeEntity entity) {
|
||||||
// initialize memory
|
// initialize memory
|
||||||
SceneNode *self = new(SceneNode);
|
SceneNode *self = new(SceneNode);
|
||||||
|
@ -152,4 +166,5 @@ void DestroyScene(Scene *self) {
|
||||||
|
|
||||||
void SceneTick(Scene* self, double delta_time) {
|
void SceneTick(Scene* self, double delta_time) {
|
||||||
Internal_SceneNodeTick(self->root, delta_time);
|
Internal_SceneNodeTick(self->root, delta_time);
|
||||||
|
Internal_SceneNodeUpdateTransform(self->root);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "utils/list.h"
|
#include "utils/list.h"
|
||||||
#include "utils/typeclass_helpers.h"
|
#include "utils/typeclass_helpers.h"
|
||||||
typedef struct SceneNodeEntity SceneNodeEntity;
|
typedef struct SceneNodeEntity SceneNodeEntity;
|
||||||
|
typedef struct Transformable Transformable;
|
||||||
typedef struct CameraNode CameraNode;
|
typedef struct CameraNode CameraNode;
|
||||||
|
|
||||||
typedef struct Scene Scene;
|
typedef struct Scene Scene;
|
||||||
|
|
|
@ -10,21 +10,22 @@ END_REFLECT(TransformNode);
|
||||||
impl_Drop_for(TransformNode,
|
impl_Drop_for(TransformNode,
|
||||||
DestroyTransformNode
|
DestroyTransformNode
|
||||||
)
|
)
|
||||||
impl_Transformable_for(TransformNode,
|
impl_Transformable_for(TransformNode)
|
||||||
TransformNodeGetTransform,
|
impl_SceneNodeEntity_defaults(TransformNode)
|
||||||
TransformNodeGetGlobalTransform
|
|
||||||
)
|
|
||||||
impl_SceneNodeEntity_defaults(TransformNode);
|
|
||||||
impl_SceneNodeEntity_for(TransformNode,
|
impl_SceneNodeEntity_for(TransformNode,
|
||||||
TransformNode_default_enter_tree,
|
TransformNodeEnterTree,
|
||||||
TransformNode_default_exit_tree,
|
TransformNodeExitTree,
|
||||||
TransformNode_default_tick
|
TransformNode_default_tick
|
||||||
)
|
)
|
||||||
|
|
||||||
SceneNode *CreateTransformNode() {
|
SceneNode *CreateTransformNode() {
|
||||||
TransformNode *self = new(TransformNode);
|
TransformNode *self = new(TransformNode);
|
||||||
|
self->dirty_bit = 0x0;
|
||||||
|
self->node = NULL;
|
||||||
|
self->parent_transformable = tc_null(Transformable);
|
||||||
self->global_transform = TransformIdentity();
|
self->global_transform = TransformIdentity();
|
||||||
self->transform = TransformIdentity();
|
self->transform = TransformIdentity();
|
||||||
|
|
||||||
return CreateSceneNode(TransformNode_as_SceneNodeEntity(self));
|
return CreateSceneNode(TransformNode_as_SceneNodeEntity(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +33,15 @@ void DestroyTransformNode(TransformNode *self) {
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransformNodeEnterTree(TransformNode *self) {
|
||||||
|
if(self->node->parent != NULL && TC_MIRRORS(self->node->parent->entity, Transformable))
|
||||||
|
self->parent_transformable = TC_CAST(self->node->parent->entity, Transformable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TransformNodeExitTree(TransformNode *self) {
|
||||||
|
self->parent_transformable = tc_null(Transformable);
|
||||||
|
}
|
||||||
|
|
||||||
Transform *TransformNodeGetTransform(TransformNode *self) {
|
Transform *TransformNodeGetTransform(TransformNode *self) {
|
||||||
return &self->transform;
|
return &self->transform;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,16 @@
|
||||||
#include "scene_node_entity.h"
|
#include "scene_node_entity.h"
|
||||||
#include "utils/drop.h"
|
#include "utils/drop.h"
|
||||||
|
|
||||||
typedef struct TransformNode {
|
typedef struct TransformNode { ExtendsTransformable;
|
||||||
SceneNode *node;
|
SceneNode *node;
|
||||||
Transform transform;
|
|
||||||
Transform global_transform;
|
|
||||||
} TransformNode;
|
} TransformNode;
|
||||||
|
|
||||||
extern SceneNode *CreateTransformNode();
|
extern SceneNode *CreateTransformNode();
|
||||||
extern void DestroyTransformNode(TransformNode *self);
|
extern void DestroyTransformNode(TransformNode *self);
|
||||||
|
|
||||||
|
extern void TransformNodeEnterTree(TransformNode *self);
|
||||||
|
extern void TransformNodeExitTree(TransformNode *self);
|
||||||
|
|
||||||
extern Transform *TransformNodeGetTransform(TransformNode *self);
|
extern Transform *TransformNodeGetTransform(TransformNode *self);
|
||||||
extern Transform *TransformNodeGetGlobalTransform(TransformNode *self);
|
extern Transform *TransformNodeGetGlobalTransform(TransformNode *self);
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,56 @@ Matrix TransformGetMatrix(Transform const *self) {
|
||||||
return mat;
|
return mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateTransformable(Transformable *self, Transformable *parent) {
|
Vector3 TransformPosition(Transform const *self, Vector3 local_pos) {
|
||||||
Transform *parent_global = self->tc->get_global_transform(self->data);
|
return Vector3Add(TransformDirection(self, local_pos), self->translation);
|
||||||
Transform *global = self->tc->get_global_transform(self->data);
|
}
|
||||||
Transform *local = self->tc->get_transform(self->data);
|
|
||||||
global->translation = Vector3Add(parent_global->translation, local->translation);
|
Vector3 TransformDirection(Transform const *self, Vector3 local_direction) {
|
||||||
global->rotation = QuaternionMultiply(parent_global->rotation, local->rotation);
|
Matrix const m = TransformGetMatrix(self);
|
||||||
global->scale = Vector3Multiply(parent_global->scale, local->scale);
|
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 const *self, Vector3 local_scale) {
|
||||||
|
return Vector3Multiply(self->scale, TransformDirection(self, local_scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion TransformRotation(Transform const *self, Quaternion local_rotation) {
|
||||||
|
return QuaternionMultiply(self->rotation, local_rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform TransformTransform(Transform const *self, Transform const *other) {
|
||||||
|
return (Transform) {
|
||||||
|
.translation = TransformPosition(self, other->translation),
|
||||||
|
.scale = TransformScale(self, other->scale),
|
||||||
|
.rotation = TransformRotation(self, other->rotation)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 InverseTransformPosition(Transform const *self, Vector3 global_pos) {
|
||||||
|
return Vector3Subtract(InverseTransformDirection(self, global_pos), self->translation);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 InverseTransformDirection(Transform const *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))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 InverseTransformScale(Transform const *self, Vector3 global_scale) {
|
||||||
|
return Vector3Multiply(Vector3Invert(self->scale), InverseTransformDirection(self, global_scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion InverseTransformRotation(Transform const *self, Quaternion global_rotation) {
|
||||||
|
return QuaternionMultiply(QuaternionInvert(self->rotation), global_rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform InverseTransformTransform(Transform const *self, Transform const *other) {
|
||||||
|
return (Transform) {
|
||||||
|
.translation = InverseTransformPosition(self, other->translation),
|
||||||
|
.scale = InverseTransformScale(self, other->scale),
|
||||||
|
.rotation = InverseTransformRotation(self, other->rotation)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,31 +7,90 @@
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
|
|
||||||
|
struct Transformable;
|
||||||
|
|
||||||
typedef struct ITransformable {
|
typedef struct ITransformable {
|
||||||
SceneNode *node;
|
SceneNode *node;
|
||||||
Transform *(*const get_transform)(void*);
|
Transform (*const get_transform)(void*);
|
||||||
Transform *(*const get_global_transform)(void*);
|
void (*const set_transform)(void*, Transform);
|
||||||
|
Transform (*const get_global_transform)(void*);
|
||||||
|
void (*const set_global_transform)(void*, Transform);
|
||||||
|
void (*const force_update)(void*);
|
||||||
|
unsigned char (*const get_dirty_bit)(void*);
|
||||||
|
struct Transformable (*const get_parent_transformable)(void*);
|
||||||
} ITransformable;
|
} ITransformable;
|
||||||
|
|
||||||
typedef struct Transformable {
|
typedef struct Transformable {
|
||||||
ITransformable const *tc;
|
ITransformable const *tc;
|
||||||
void *data;
|
void *data;
|
||||||
IMirror const *mirror;
|
IMirror const *mirror;
|
||||||
|
ISceneNodeEntity const *scene_node_entity;
|
||||||
} Transformable;
|
} Transformable;
|
||||||
|
|
||||||
extern Transform TransformIdentity();
|
extern Transform TransformIdentity();
|
||||||
extern Matrix TransformGetMatrix(Transform const *self);
|
extern Matrix TransformGetMatrix(Transform const *self);
|
||||||
extern void UpdateTransformable(Transformable *self, Transformable *parent);
|
|
||||||
|
|
||||||
#define impl_Transformable_for(T, get_transform_f, get_global_transform_f)\
|
extern Vector3 TransformPosition(Transform const *self, Vector3 local_pos);
|
||||||
|
extern Vector3 TransformDirection(Transform const *self, Vector3 local_direction);
|
||||||
|
extern Vector3 TransformScale(Transform const *self, Vector3 local_scale);
|
||||||
|
extern Quaternion TransformRotation(Transform const *self, Quaternion local_rotation);
|
||||||
|
extern Transform TransformTransform(Transform const *self, Transform const *other);
|
||||||
|
|
||||||
|
extern Vector3 InverseTransformPosition(Transform const *self, Vector3 global_pos);
|
||||||
|
extern Vector3 InverseTransformDirection(Transform const *self, Vector3 global_direction);
|
||||||
|
extern Vector3 InverseTransformScale(Transform const *self, Vector3 global_scale);
|
||||||
|
extern Quaternion InverseTransformRotation(Transform const *self, Quaternion quat);
|
||||||
|
extern Transform InverseTransformTransform(Transform const *self, Transform const *other);
|
||||||
|
|
||||||
|
#define MATRIX_UP(self_) ((Vector3){self_.m0, self_.m1, self_.m2})
|
||||||
|
#define MATRIX_RIGHT(self_) ((Vector3){self_.m4, self_.m5, self_.m6})
|
||||||
|
#define MATRIX_FORWARD(self_) ((Vector3){self_.m8, self_.m9, self_.m10})
|
||||||
|
|
||||||
|
#define VECTOR3_RIGHT ((Vector3){1.f, 0.f, 0.f})
|
||||||
|
#define VECTOR3_UP ((Vector3){0.f, 1.f, 0.f})
|
||||||
|
#define VECTOR3_FORWARD ((Vector3){0.f, 0.f, 1.f})
|
||||||
|
|
||||||
|
//! Defines the variables required to implement Transformable. Put at the start of a struct
|
||||||
|
#define ExtendsTransformable Transform transform; Transform global_transform; Transformable parent_transformable; unsigned char dirty_bit
|
||||||
|
|
||||||
|
//! Define transformable getter-setters for type T
|
||||||
|
//! Requires member variables: Transform transform; Transform global_transform; Transformable parent_transformable; unsigned char dirty_bit;
|
||||||
|
//! Macro implements the interface functions itself to ensure consistent behaviour.
|
||||||
|
#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 |= 0x1; } /*!< sets local dirty bit */\
|
||||||
|
static Transform T##_get_global_transform_GEN_(T* self) { return self->global_transform; }\
|
||||||
|
static void T##_set_global_transform_GEN_(T* self, Transform value) {\
|
||||||
|
self->global_transform = value;\
|
||||||
|
if(tc_is_null(self->parent_transformable)) {\
|
||||||
|
self->transform = value;\
|
||||||
|
} else {\
|
||||||
|
self->parent_transformable.tc->force_update(self->parent_transformable.data); /* Force a transform update for the parent, to ensure its global transform is up-to-date */\
|
||||||
|
Transform parent_global = self->parent_transformable.tc->get_global_transform(self->parent_transformable.data);\
|
||||||
|
self->transform = InverseTransformTransform(&parent_global, &value); /* Use up-to-date parent transform to get the local transform to the new global transform */\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
static void T##_force_update_GEN_(T *self) {\
|
||||||
|
if(tc_is_null(self->parent_transformable)) {\
|
||||||
|
self->global_transform = self->transform;\
|
||||||
|
return;\
|
||||||
|
}\
|
||||||
|
Transform parent_global = self->parent_transformable.tc->get_global_transform(self->parent_transformable.data);\
|
||||||
|
self->global_transform = TransformTransform(&parent_global, &self->transform);\
|
||||||
|
}\
|
||||||
|
static unsigned char T##_get_dirty_bit_GEN_(T *self) { return self->dirty_bit; }\
|
||||||
|
static Transformable T##_get_parent_transformable_GEN_(T *self) { return self->parent_transformable; }\
|
||||||
Transformable T##_as_Transformable(T *x) {\
|
Transformable T##_as_Transformable(T *x) {\
|
||||||
TC_FN_TYPECHECK(Transform *,get_transform_f, T*);\
|
|
||||||
TC_FN_TYPECHECK(Transform *,get_global_transform_f, T*);\
|
|
||||||
static ITransformable const tc = {\
|
static ITransformable const tc = {\
|
||||||
.get_transform = (Transform *(*const)(void*)) get_transform_f,\
|
.get_transform = (Transform (*const)(void*)) T##_get_transform_GEN_,\
|
||||||
.get_global_transform = (Transform *(*const)(void*)) get_global_transform_f\
|
.set_transform = (void (*const)(void*,Transform)) T##_set_transform_GEN_,\
|
||||||
|
.get_global_transform = (Transform (*const)(void*)) T##_get_global_transform_GEN_,\
|
||||||
|
.set_global_transform = (void (*const)(void*,Transform)) T##_set_global_transform_GEN_,\
|
||||||
|
.force_update = (void (*const)(void*)) T##_force_update_GEN_,\
|
||||||
|
.get_dirty_bit = (unsigned char (*const)(void*)) T##_get_dirty_bit_GEN_,\
|
||||||
|
.get_parent_transformable = (Transformable (*const)(void*)) T##_get_parent_transformable_GEN_\
|
||||||
};\
|
};\
|
||||||
return (Transformable){ .tc = &tc, .data = x, .mirror = T##_as_Mirror(x).tc };\
|
return (Transformable){ .tc = &tc, .data = x, .scene_node_entity = T##_as_SceneNodeEntity(x).tc, .mirror = T##_as_Mirror(x).tc };\
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !TRANSFORMABLE_H
|
#endif // !TRANSFORMABLE_H
|
||||||
|
|
25
src/main.c
25
src/main.c
|
@ -1,4 +1,5 @@
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
#include "test_object.h"
|
||||||
#include "core/camera_node.h"
|
#include "core/camera_node.h"
|
||||||
#include "core/engine_global.h"
|
#include "core/engine_global.h"
|
||||||
#include "core/engine_loop.h"
|
#include "core/engine_loop.h"
|
||||||
|
@ -8,12 +9,24 @@
|
||||||
|
|
||||||
Scene *CreateInitialScene() {
|
Scene *CreateInitialScene() {
|
||||||
SceneNode *root = CreateTransformNode();
|
SceneNode *root = CreateTransformNode();
|
||||||
SceneNode *camera_node = CreateCameraNode();
|
SceneNode *camera_parent_parent = CreateTransformNode();
|
||||||
Transformable camera = TC_CAST(camera_node->entity, Transformable);
|
Transformable transformable = TC_CAST(camera_parent_parent->entity, Transformable);
|
||||||
Transform *camera_global = camera.tc->get_global_transform(camera.data);
|
Transform transform = transformable.tc->get_transform(transformable.data);
|
||||||
camera_global->translation = (Vector3){0.f, 10.f, -10.f};
|
transform.translation = (Vector3){10.f, 0.f, 0.f};
|
||||||
camera_global->rotation = QuaternionFromEuler(45.f * DEG2RAD, 0.f, 0.f);
|
transform.rotation = QuaternionFromEuler(0.f, -10.f * DEG2RAD, 0.f);
|
||||||
SceneNodeAddChild(root, camera_node);
|
transformable.tc->set_transform(transformable.data, transform);
|
||||||
|
// create camera with a transform parent
|
||||||
|
SceneNode *camera_parent = CreateTransformNode();
|
||||||
|
// set camera parent location
|
||||||
|
transformable = TC_CAST(camera_parent->entity, Transformable);
|
||||||
|
transform = transformable.tc->get_transform(transformable.data);
|
||||||
|
transform.translation = (Vector3){0.f, 10.f, -10.f};
|
||||||
|
transform.rotation = QuaternionFromEuler(45.f * DEG2RAD, 0.f, 0.f);
|
||||||
|
transformable.tc->set_transform(transformable.data, transform);
|
||||||
|
SceneNodeAddChild(root, camera_parent_parent);
|
||||||
|
SceneNodeAddChild(camera_parent_parent, camera_parent);
|
||||||
|
SceneNodeAddChild(camera_parent, CreateCameraNode());
|
||||||
|
SceneNodeAddChild(root, CreateTestObject());
|
||||||
return CreateScene(root);
|
return CreateScene(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue