feat: implemented MeshRenderEntity
This commit is contained in:
parent
dda35f69f0
commit
2be8b21372
BIN
resources/spacefighter.glb
Normal file
BIN
resources/spacefighter.glb
Normal file
Binary file not shown.
|
@ -46,7 +46,7 @@ void CameraNodeExitTree(CameraNode *self) {
|
|||
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);
|
||||
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
|
||||
|
|
50
src/core/mesh_render_entity.c
Normal file
50
src/core/mesh_render_entity.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include "mesh_render_entity.h"
|
||||
#include "render.h"
|
||||
|
||||
START_REFLECT(MeshRenderEntity);
|
||||
REFLECT_TYPECLASS(MeshRenderEntity, Drop);
|
||||
REFLECT_TYPECLASS(MeshRenderEntity, SceneNodeEntity);
|
||||
REFLECT_TYPECLASS(MeshRenderEntity, Renderable);
|
||||
END_REFLECT(MeshRenderEntity);
|
||||
|
||||
impl_SceneNodeEntity_defaults(MeshRenderEntity)
|
||||
impl_SceneNodeEntity_for(MeshRenderEntity,
|
||||
MeshRenderEntityEnterTree,
|
||||
MeshRenderEntityExitTree,
|
||||
MeshRenderEntity_default_tick
|
||||
)
|
||||
|
||||
impl_Drop_for(MeshRenderEntity,
|
||||
DestroyMeshRenderEntity
|
||||
)
|
||||
|
||||
impl_Renderable_for(MeshRenderEntity,
|
||||
MeshRenderEntityDraw
|
||||
)
|
||||
|
||||
SceneNode *CreateMeshRenderEntity(char const *resource_path) {
|
||||
MeshRenderEntity *self = new(MeshRenderEntity);
|
||||
GetModelResource(resource_path, &self->model);
|
||||
return CreateSceneNode(MeshRenderEntity_as_SceneNodeEntity(self));
|
||||
}
|
||||
|
||||
void DestroyMeshRenderEntity(MeshRenderEntity *self) {
|
||||
free(self);
|
||||
}
|
||||
|
||||
void MeshRenderEntityEnterTree(MeshRenderEntity *self) {
|
||||
SceneNodeEntity parent_entity = self->node->parent->entity;
|
||||
self->transform = TC_CAST(parent_entity, Transformable);
|
||||
LoadResource(self->model.handle);
|
||||
AddRenderable(MeshRenderEntity_as_Renderable(self));
|
||||
}
|
||||
|
||||
void MeshRenderEntityExitTree(MeshRenderEntity *self) {
|
||||
ReleaseResource(self->model.handle);
|
||||
RemoveRenderable(MeshRenderEntity_as_Renderable(self));
|
||||
}
|
||||
|
||||
void MeshRenderEntityDraw(MeshRenderEntity *self) {
|
||||
self->model.resource->transform = TransformGetMatrix(self->transform.tc->get_global_transform(self->transform.data));
|
||||
DrawModel(*self->model.resource, (Vector3){0.f, 0.f, 0.f}, 1.f, WHITE);
|
||||
}
|
30
src/core/mesh_render_entity.h
Normal file
30
src/core/mesh_render_entity.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef MESH_RENDER_ENTITY_H
|
||||
#define MESH_RENDER_ENTITY_H
|
||||
|
||||
#include "renderable.h"
|
||||
#include "resources.h"
|
||||
#include "scene_node_entity.h"
|
||||
#include "transformable.h"
|
||||
#include "utils/drop.h"
|
||||
#include "utils/mirror.h"
|
||||
|
||||
typedef struct MeshRenderEntity {
|
||||
SceneNode *node;
|
||||
Transformable transform;
|
||||
ModelResource model;
|
||||
} MeshRenderEntity;
|
||||
|
||||
extern SceneNode *CreateMeshRenderEntity(char const *resource_path);
|
||||
extern void DestroyMeshRenderEntity(MeshRenderEntity *self);
|
||||
|
||||
extern void MeshRenderEntityEnterTree(MeshRenderEntity *self);
|
||||
extern void MeshRenderEntityExitTree(MeshRenderEntity *self);
|
||||
|
||||
extern void MeshRenderEntityDraw(MeshRenderEntity *self);
|
||||
|
||||
DECL_REFLECT(MeshRenderEntity);
|
||||
decl_typeclass_impl(Drop, MeshRenderEntity);
|
||||
decl_typeclass_impl(SceneNodeEntity, MeshRenderEntity);
|
||||
decl_typeclass_impl(Renderable, MeshRenderEntity);
|
||||
|
||||
#endif // !MESH_RENDER_ENTITY_H
|
|
@ -1,31 +1,178 @@
|
|||
#include "resources.h"
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
#include "utils/hash_map.h"
|
||||
#include "utils/dictionary.h"
|
||||
#include "utils/debug.h"
|
||||
#include "utils/strutil.h"
|
||||
|
||||
char const *RESOURCE_DIRECTORY = "resources";
|
||||
|
||||
typedef enum ResourceType {
|
||||
RESOURCE_MODEL, RESOURCE_TEXTURE,
|
||||
RESOURCE_MAX
|
||||
} ResourceType;
|
||||
|
||||
typedef struct ResourceContainer {
|
||||
char const *path;
|
||||
char const *name;
|
||||
unsigned use_counter;
|
||||
bool is_loaded;
|
||||
ResourceType type;
|
||||
union {
|
||||
Model model;
|
||||
Texture texture;
|
||||
};
|
||||
} ResourceContainer;
|
||||
|
||||
typedef void (*LoadResourceFn)(ResourceContainer *resource);
|
||||
typedef void (*UnloadResourceFn)(ResourceContainer *resource);
|
||||
|
||||
static void Internal_LoadModelResource(ResourceContainer *resource);
|
||||
static void Internal_UnloadModelResource(ResourceContainer *resource);
|
||||
static void Internal_LoadTextureResource(ResourceContainer *resource);
|
||||
static void Internal_UnloadTextureResource(ResourceContainer *resource);
|
||||
|
||||
LoadResourceFn g_load_functions[] = {Internal_LoadModelResource, Internal_LoadTextureResource};
|
||||
UnloadResourceFn g_unload_functions[] = {Internal_UnloadModelResource, Internal_UnloadTextureResource};
|
||||
|
||||
static HashMap g_resource_map;
|
||||
static FilePathList g_resource_files;
|
||||
|
||||
//! hash function for hashmaps with char* as key type.
|
||||
static uintptr_t HashMapHashString(char const **str_ptr) {
|
||||
return strhash(*str_ptr);
|
||||
}
|
||||
|
||||
//! Use file extensions to figure out the
|
||||
static ResourceType ResourceGetTypeFromPath(char const *path) {
|
||||
// Texture files
|
||||
if(IsFileExtension(path, ".png")) return RESOURCE_TEXTURE;
|
||||
if(IsFileExtension(path, ".jpg")) return RESOURCE_TEXTURE;
|
||||
if(IsFileExtension(path, ".jpeg")) return RESOURCE_TEXTURE;
|
||||
// Model files
|
||||
if(IsFileExtension(path, ".glb")) return RESOURCE_MODEL;
|
||||
if(IsFileExtension(path, ".gltf")) return RESOURCE_MODEL;
|
||||
return RESOURCE_MAX;
|
||||
}
|
||||
|
||||
//! Find which resource directory to use: Relative to working directory, or relative to application directory
|
||||
//! Working directory resources are only supposed to be used for debugging.
|
||||
static inline
|
||||
void InitializeResourceDirectory() {
|
||||
void Internal_InitializeResourceDirectory() {
|
||||
// if there is a resource directory in the working directory, prioritize that for debugging
|
||||
if(DirectoryExists(RESOURCE_DIRECTORY)) {
|
||||
ChangeDirectory(TextFormat("%s/%s", GetWorkingDirectory(), RESOURCE_DIRECTORY));
|
||||
LOG_WARNING("Using working dir resources, this is possible for debug purposes.");
|
||||
LOG_WARNING("Using working dir resources, this is intended for debug purposes only.");
|
||||
return;
|
||||
}
|
||||
// check application installation directory for a resource directory
|
||||
// this is the default running environment
|
||||
char const *installation_resource_dir = TextFormat(GetApplicationDirectory(), RESOURCE_DIRECTORY);
|
||||
char const *installation_resource_dir = TextFormat("%s/%s", GetApplicationDirectory(), RESOURCE_DIRECTORY);
|
||||
if(DirectoryExists(installation_resource_dir)) {
|
||||
ChangeDirectory(installation_resource_dir);
|
||||
return;
|
||||
}
|
||||
UNREACHABLE("Failed to find resource directory");
|
||||
UNREACHABLE("Failed to find a valid resource directory");
|
||||
}
|
||||
|
||||
static inline
|
||||
void Internal_IndexResourceDirectory() {
|
||||
g_resource_files = LoadDirectoryFilesEx(GetWorkingDirectory(), NULL, true);
|
||||
g_resource_map = hash_map_from_types(char const *, ResourceContainer, HashMapHashString);
|
||||
ResourceContainer placeholder;
|
||||
for(size_t i = 0; i < g_resource_files.count; ++i) {
|
||||
placeholder = (ResourceContainer){
|
||||
.is_loaded = false,
|
||||
.use_counter = 0,
|
||||
.path = g_resource_files.paths[i],
|
||||
.name = GetFileName(g_resource_files.paths[i]),
|
||||
.type = ResourceGetTypeFromPath(g_resource_files.paths[i])
|
||||
};
|
||||
// only index resources that the engine knows how to load
|
||||
if(placeholder.type != RESOURCE_MAX) {
|
||||
LOG_INFO("Internal_IndexResourceDirectory: Indexing %s as %s", placeholder.path, placeholder.name);
|
||||
hash_map_insert(&g_resource_map, &placeholder.name, &placeholder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeResourceSubsystem() {
|
||||
InitializeResourceDirectory();
|
||||
Internal_InitializeResourceDirectory();
|
||||
Internal_IndexResourceDirectory();
|
||||
}
|
||||
|
||||
void CleanResourceSubsystem() {
|
||||
List resources = hash_map_values(&g_resource_map);
|
||||
list_foreach(ResourceContainer *,resource, &resources)
|
||||
g_unload_functions[resource->type](resource);
|
||||
hash_map_empty(&g_resource_map);
|
||||
UnloadDirectoryFiles(g_resource_files);
|
||||
}
|
||||
|
||||
bool GetModelResource(char const *path, ModelResource *out) {
|
||||
ResourceContainer *container = hash_map_get_as(ResourceContainer, &g_resource_map, &path);
|
||||
*out = ResourceEmpty(Model);
|
||||
// assert some assumptions about the found resource
|
||||
ASSERT_RETURN(container != NULL, false, "GetTextureResource: Resource %s not in index.", path);
|
||||
ASSERT_RETURN(container->type == RESOURCE_MODEL, false, "GetTextureResource: Resource %s is not a Texture.", path);
|
||||
++container->use_counter;
|
||||
*out = (ModelResource) {
|
||||
.handle = container,
|
||||
.resource = &container->model
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetTextureResource(char const *path, TextureResource *out) {
|
||||
ResourceContainer *container = hash_map_get_as(ResourceContainer, &g_resource_map, &path);
|
||||
*out = ResourceEmpty(Texture);
|
||||
// assert some assumptions about the found resource
|
||||
ASSERT_RETURN(container != NULL, false, "GetTextureResource: Resource %s not in index.", path);
|
||||
ASSERT_RETURN(container->type != RESOURCE_TEXTURE, false, "GetTextureResource: Resource %s is not a Texture.", path);
|
||||
*out = (TextureResource) {
|
||||
.handle = container,
|
||||
.resource = &container->texture
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsResourceLoaded(ResourceHandle handle) {
|
||||
return handle->is_loaded;
|
||||
}
|
||||
|
||||
void LoadResource(ResourceHandle handle) {
|
||||
ASSERT_RETURN(handle != NULL,, "LoadResource: Resource handle invalid");
|
||||
g_load_functions[handle->type](handle);
|
||||
handle->is_loaded = true;
|
||||
++handle->use_counter;
|
||||
}
|
||||
|
||||
void ReleaseResource(ResourceHandle handle) {
|
||||
ASSERT_RETURN(handle != NULL,, "ReleaseResource: Resource handle invalid");
|
||||
ASSERT_RETURN_WARN(handle->is_loaded,, "ReleaseResource: Resource %s is not loaded.", handle->path);
|
||||
g_unload_functions[handle->type](handle);
|
||||
handle->is_loaded = false;
|
||||
--handle->use_counter;
|
||||
}
|
||||
|
||||
static
|
||||
void Internal_LoadModelResource(ResourceContainer *resource) {
|
||||
resource->model = LoadModel(resource->path);
|
||||
}
|
||||
|
||||
static
|
||||
void Internal_UnloadModelResource(ResourceContainer *resource) {
|
||||
UnloadModel(resource->model);
|
||||
resource->model = (Model){0};
|
||||
}
|
||||
|
||||
static
|
||||
void Internal_LoadTextureResource(ResourceContainer *resource) {
|
||||
resource->texture = LoadTexture(resource->path);
|
||||
}
|
||||
|
||||
static
|
||||
void Internal_UnloadTextureResource(ResourceContainer *resource) {
|
||||
UnloadTexture(resource->texture);
|
||||
resource->texture = (Texture){0};
|
||||
}
|
||||
|
|
|
@ -2,10 +2,30 @@
|
|||
#define RESOURCES_H
|
||||
|
||||
#include "raylib.h"
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
typedef struct ResourceContainer* ResourceHandle;
|
||||
#define ResourceType(T) typedef struct T##Resource { ResourceHandle handle; T *resource; } T##Resource
|
||||
#define ResourceEmpty(T) ((T##Resource){.handle = NULL, .resource = NULL})
|
||||
|
||||
ResourceType(Model);
|
||||
ResourceType(Texture);
|
||||
|
||||
//! Allocate and initialize memory required to operate resource subsystem
|
||||
extern void InitializeResourceSubsystem();
|
||||
//! Clean and shut down resource subsystem, all resource calls are invalid after this
|
||||
extern void CleanResourceSubsystem();
|
||||
//! Get model from resources.
|
||||
extern bool GetModelResource(char const *path, ModelResource *out);
|
||||
//! Get indexed texture from resources.
|
||||
extern bool GetTextureResource(char const *path, TextureResource *out);
|
||||
|
||||
//! Check if a resource is loaded or not.
|
||||
extern bool IsResourceLoaded(ResourceHandle handle);
|
||||
//! Load a resource using a handle returned from Get{Type}Resource, increments use count.
|
||||
extern void LoadResource(ResourceHandle resource);
|
||||
//! Release a resource using a handle returned from Get{Type}Resource, increments use count.
|
||||
extern void ReleaseResource(ResourceHandle handle);
|
||||
|
||||
#endif // !RESOURCES_H
|
||||
|
|
|
@ -9,45 +9,45 @@ Transform TransformIdentity() {
|
|||
}
|
||||
|
||||
|
||||
Matrix TransformGetMatrix(Transform const *self) {
|
||||
Matrix mat = MatrixScale(self->scale.x, self->scale.y, self->scale.z);
|
||||
mat = MatrixMultiply(mat, QuaternionToMatrix(self->rotation));
|
||||
mat.m12 = self->translation.x;
|
||||
mat.m13 = self->translation.y;
|
||||
mat.m14 = self->translation.z;
|
||||
Matrix TransformGetMatrix(Transform self) {
|
||||
Matrix mat = MatrixScale(self.scale.x, self.scale.y, self.scale.z);
|
||||
mat = MatrixMultiply(mat, QuaternionToMatrix(self.rotation));
|
||||
mat.m12 = self.translation.x;
|
||||
mat.m13 = self.translation.y;
|
||||
mat.m14 = self.translation.z;
|
||||
return mat;
|
||||
}
|
||||
|
||||
Vector3 TransformPosition(Transform const *self, Vector3 local_pos) {
|
||||
return Vector3Add(TransformDirection(self, local_pos), self->translation);
|
||||
Vector3 TransformPosition(Transform self, Vector3 local_pos) {
|
||||
return Vector3Add(TransformDirection(self, local_pos), self.translation);
|
||||
}
|
||||
|
||||
Vector3 TransformDirection(Transform const *self, Vector3 local_direction) {
|
||||
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));
|
||||
}
|
||||
|
||||
Vector3 TransformScale(Transform const *self, Vector3 local_scale) {
|
||||
return Vector3Multiply(self->scale, TransformDirection(self, local_scale));
|
||||
Vector3 TransformScale(Transform 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);
|
||||
Quaternion TransformRotation(Transform self, Quaternion local_rotation) {
|
||||
return QuaternionMultiply(self.rotation, local_rotation);
|
||||
}
|
||||
|
||||
Transform TransformTransform(Transform const *self, Transform const *other) {
|
||||
Transform TransformTransform(Transform self, Transform other) {
|
||||
return (Transform) {
|
||||
.translation = TransformPosition(self, other->translation),
|
||||
.scale = TransformScale(self, other->scale),
|
||||
.rotation = TransformRotation(self, other->rotation)
|
||||
.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 InverseTransformPosition(Transform self, Vector3 global_pos) {
|
||||
return Vector3Subtract(InverseTransformDirection(self, global_pos), self.translation);
|
||||
}
|
||||
|
||||
Vector3 InverseTransformDirection(Transform const *self, Vector3 global_direction) {
|
||||
Vector3 InverseTransformDirection(Transform self, Vector3 global_direction) {
|
||||
Matrix const mat = TransformGetMatrix(self);
|
||||
return (Vector3){
|
||||
Vector3DotProduct(MATRIX_RIGHT(mat), Vector3Scale(VECTOR3_RIGHT, global_direction.x)),
|
||||
|
@ -56,18 +56,18 @@ Vector3 InverseTransformDirection(Transform const *self, Vector3 global_directio
|
|||
};
|
||||
}
|
||||
|
||||
Vector3 InverseTransformScale(Transform const *self, Vector3 global_scale) {
|
||||
return Vector3Multiply(Vector3Invert(self->scale), InverseTransformDirection(self, global_scale));
|
||||
Vector3 InverseTransformScale(Transform 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);
|
||||
Quaternion InverseTransformRotation(Transform self, Quaternion global_rotation) {
|
||||
return QuaternionMultiply(QuaternionInvert(self.rotation), global_rotation);
|
||||
}
|
||||
|
||||
Transform InverseTransformTransform(Transform const *self, Transform const *other) {
|
||||
Transform InverseTransformTransform(Transform self, Transform other) {
|
||||
return (Transform) {
|
||||
.translation = InverseTransformPosition(self, other->translation),
|
||||
.scale = InverseTransformScale(self, other->scale),
|
||||
.rotation = InverseTransformRotation(self, other->rotation)
|
||||
.translation = InverseTransformPosition(self, other.translation),
|
||||
.scale = InverseTransformScale(self, other.scale),
|
||||
.rotation = InverseTransformRotation(self, other.rotation)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -28,19 +28,19 @@ typedef struct Transformable {
|
|||
} Transformable;
|
||||
|
||||
extern Transform TransformIdentity();
|
||||
extern Matrix TransformGetMatrix(Transform const *self);
|
||||
extern Matrix TransformGetMatrix(Transform self);
|
||||
|
||||
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 TransformPosition(Transform self, Vector3 local_pos);
|
||||
extern Vector3 TransformDirection(Transform self, Vector3 local_direction);
|
||||
extern Vector3 TransformScale(Transform self, Vector3 local_scale);
|
||||
extern Quaternion TransformRotation(Transform self, Quaternion local_rotation);
|
||||
extern Transform TransformTransform(Transform self, Transform 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);
|
||||
extern Vector3 InverseTransformPosition(Transform self, Vector3 global_pos);
|
||||
extern Vector3 InverseTransformDirection(Transform self, Vector3 global_direction);
|
||||
extern Vector3 InverseTransformScale(Transform self, Vector3 global_scale);
|
||||
extern Quaternion InverseTransformRotation(Transform self, Quaternion quat);
|
||||
extern Transform InverseTransformTransform(Transform self, Transform other);
|
||||
|
||||
#define MATRIX_UP(self_) ((Vector3){self_.m0, self_.m1, self_.m2})
|
||||
#define MATRIX_RIGHT(self_) ((Vector3){self_.m4, self_.m5, self_.m6})
|
||||
|
@ -66,7 +66,7 @@ static void T##_set_global_transform_GEN_(T* self, Transform value) {\
|
|||
self->transform = value;\
|
||||
} else {\
|
||||
Transform parent_global = self->parent_transformable.tc->get_global_transform(self->parent_transformable.data);\
|
||||
self->transform = InverseTransformTransform(&parent_global, &value); /* Use parent transform to transform the local transform to the new global transform */\
|
||||
self->transform = InverseTransformTransform(parent_global, value); /* Use parent transform to transform the local transform to the new global transform */\
|
||||
}\
|
||||
}\
|
||||
static void T##_force_update_GEN_(T *self) {\
|
||||
|
@ -75,7 +75,7 @@ static void T##_force_update_GEN_(T *self) {\
|
|||
return;\
|
||||
}\
|
||||
Transform parent_global = self->parent_transformable.tc->get_global_transform(self->parent_transformable.data);\
|
||||
self->global_transform = TransformTransform(&parent_global, &self->transform);\
|
||||
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; }\
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "core/engine_loop.h"
|
||||
#include "core/scene.h"
|
||||
#include "core/transform_node.h"
|
||||
#include "core/mesh_render_entity.h"
|
||||
#include "utils/debug.h"
|
||||
|
||||
Scene *CreateInitialScene() {
|
||||
|
@ -28,6 +29,7 @@ Scene *CreateInitialScene() {
|
|||
SceneNodeAddChild(camera_parent_parent, camera_parent);
|
||||
SceneNodeAddChild(camera_parent, CreateCameraNode());
|
||||
SceneNodeAddChild(camera_parent, CreateTestObject());
|
||||
SceneNodeAddChild(root, CreateMeshRenderEntity("spacefighter.glb"));
|
||||
return CreateScene(root);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue