diff --git a/Data/sandbox-log.txt b/Data/sandbox-log.txt
index adb2a55..1ba171d 100644
--- a/Data/sandbox-log.txt
+++ b/Data/sandbox-log.txt
@@ -1,55 +1,224 @@
-[05:21:15 AM] Info: Starting...
+[00:52:43 AM] Info: Starting...
KP3D version 2
===============================
Copyright (C) kpworld.xyz 2018-2024
Contact me! @kp_cftsz
-[05:21:15 AM] Info: Initializing SDL
-[05:21:15 AM] Info: Initializing OpenGL
-[05:21:15 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
-[05:21:15 AM] Info: Initializing GLEW
-[05:21:15 AM] Info: Initializing SDL_mixer
-[05:21:15 AM] Info: Reticulating splines...
-[05:21:15 AM] Info: Ready!
-[05:21:15 AM] Info: Loading script: build-cylinder.scm
-[05:21:15 AM] Info: Loading script: build-stairs.scm
-[05:21:15 AM] Info: Loading material resource: block.png
-[05:21:15 AM] Info: Found normal map texture: materials/block_n.png
-[05:21:15 AM] Info: Loading material resource: brick2.jpg
-[05:21:15 AM] Info: Found normal map texture: materials/brick2_n.jpg
-[05:21:15 AM] Info: Loading material resource: bricks.jpg
-[05:21:15 AM] Info: Found normal map texture: materials/bricks_n.jpg
-[05:21:15 AM] Info: Loading material resource: FLAT5_7.png
-[05:21:15 AM] Info: Found normal map texture: materials/FLAT5_7_n.png
-[05:21:15 AM] Info: Loading material resource: floor0.png
-[05:21:15 AM] Info: Found normal map texture: materials/floor0_n.png
-[05:21:15 AM] Info: Loading material resource: floor1.png
-[05:21:15 AM] Info: Found normal map texture: materials/floor1_n.png
-[05:21:15 AM] Info: Loading material resource: GRASS2.png
-[05:21:15 AM] Info: Found normal map texture: materials/GRASS2_n.png
-[05:21:15 AM] Info: Loading material resource: hardwood.jpg
-[05:21:15 AM] Info: Found normal map texture: materials/hardwood_n.jpg
-[05:21:15 AM] Info: Loading texture resource: .kp3d/banner.png
-[05:21:15 AM] Info: Loading texture resource: .kp3d/crosshair.png
-[05:21:15 AM] Info: Loading texture resource: .kp3d/empty.png
-[05:21:15 AM] Info: Loading texture resource: .kp3d/logo.png
-[05:21:15 AM] Info: Loading texture resource: .kp3d/map_grid.png
-[05:21:15 AM] Info: Loading texture resource: .kp3d/not_found.png
-[05:21:15 AM] Info: Loading texture resource: .kp3d/skybox.png
-[05:21:15 AM] Info: Loading texture resource: .kp3d/uv_test.png
-[05:21:15 AM] Info: Loading texture resource: .kp3d/water.png
-[05:21:15 AM] Info: Loading texture resource: dot.png
-[05:21:15 AM] Info: Loading texture resource: editor/stem.png
-[05:21:15 AM] Info: Loading texture resource: logo.png
-[05:21:15 AM] Info: Loading texture resource: skyboxes/sky50e2dd1d496fc.jpg
-[05:21:15 AM] Info: Loading texture resource: skyboxes/sky8.jpg
-[05:21:15 AM] Info: Loading texture resource: skyboxes/sky9.jpg
-[05:21:15 AM] Info: Loading texture resource: skyboxes/skybox.jpg
-[05:21:15 AM] Info: Loading texture resource: skyboxes/skybox_11.jpg
-[05:21:15 AM] Info: Loading texture resource: skyboxes/skybox_14.jpg
-[05:21:15 AM] Info: Loading texture resource: skyboxes/skybox_15.jpg
-[05:21:15 AM] Info: Loading texture resource: skyboxes/skybox_3.jpg
-[05:21:15 AM] Info: Loading texture resource: skybox_16.jpg
-[05:21:15 AM] Info: Map init
-[05:21:15 AM] Info: Finalized mesh with 49 batches
+[00:52:43 AM] Info: Initializing SDL
+[00:52:43 AM] Info: Initializing OpenGL
+[00:52:43 AM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
+[00:52:43 AM] Info: Initializing GLEW
+[00:52:43 AM] Info: Initializing SDL_mixer
+[00:52:43 AM] Info: Reticulating splines...
+[00:52:43 AM] Info: Ready!
+[00:52:43 AM] Info: Loading script: build-cylinder.scm
+[00:52:43 AM] Info: Loading script: build-stairs.scm
+[00:52:43 AM] Info: Loading material resource: block.png
+[00:52:43 AM] Info: Found normal map texture: materials/block_n.png
+[00:52:43 AM] Info: Loading material resource: brick2.jpg
+[00:52:43 AM] Info: Found normal map texture: materials/brick2_n.jpg
+[00:52:43 AM] Info: Loading material resource: bricks.jpg
+[00:52:43 AM] Info: Found normal map texture: materials/bricks_n.jpg
+[00:52:43 AM] Info: Loading material resource: FLAT5_7.png
+[00:52:43 AM] Info: Found normal map texture: materials/FLAT5_7_n.png
+[00:52:43 AM] Info: Loading material resource: floor0.png
+[00:52:43 AM] Info: Found normal map texture: materials/floor0_n.png
+[00:52:43 AM] Info: Loading material resource: floor1.png
+[00:52:43 AM] Info: Found normal map texture: materials/floor1_n.png
+[00:52:43 AM] Info: Loading material resource: GRASS2.png
+[00:52:43 AM] Info: Found normal map texture: materials/GRASS2_n.png
+[00:52:43 AM] Info: Loading material resource: hardwood.jpg
+[00:52:43 AM] Info: Found normal map texture: materials/hardwood_n.jpg
+[00:52:43 AM] Info: Loading texture resource: .kp3d/banner.png
+[00:52:43 AM] Info: Loading texture resource: .kp3d/crosshair.png
+[00:52:43 AM] Info: Loading texture resource: .kp3d/empty.png
+[00:52:43 AM] Info: Loading texture resource: .kp3d/logo.png
+[00:52:43 AM] Info: Loading texture resource: .kp3d/map_grid.png
+[00:52:43 AM] Info: Loading texture resource: .kp3d/not_found.png
+[00:52:43 AM] Info: Loading texture resource: .kp3d/skybox.png
+[00:52:43 AM] Info: Loading texture resource: .kp3d/uv_test.png
+[00:52:43 AM] Info: Loading texture resource: .kp3d/water.png
+[00:52:43 AM] Info: Loading texture resource: dot.png
+[00:52:43 AM] Info: Loading texture resource: editor/stem.png
+[00:52:43 AM] Info: Loading texture resource: logo.png
+[00:52:43 AM] Info: Loading texture resource: skyboxes/sky50e2dd1d496fc.jpg
+[00:52:43 AM] Info: Loading texture resource: skyboxes/sky8.jpg
+[00:52:43 AM] Info: Loading texture resource: skyboxes/sky9.jpg
+[00:52:43 AM] Info: Loading texture resource: skyboxes/skybox.jpg
+[00:52:43 AM] Info: Loading texture resource: skyboxes/skybox_11.jpg
+[00:52:43 AM] Info: Loading texture resource: skyboxes/skybox_14.jpg
+[00:52:43 AM] Info: Loading texture resource: skyboxes/skybox_15.jpg
+[00:52:43 AM] Info: Loading texture resource: skyboxes/skybox_3.jpg
+[00:52:43 AM] Info: Loading texture resource: skybox_16.jpg
+[00:52:43 AM] Info: Map init
+[00:52:43 AM] Info: Finalized mesh with 49 batches
+[00:52:50 AM] Info: Finalized mesh with 56 batches
+[00:52:57 AM] Info: Finalized mesh with 62 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:14 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:15 AM] Info: Finalized mesh with 63 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:16 AM] Info: Finalized mesh with 64 batches
+[00:53:24 AM] Info: Finalized mesh with 64 batches
+[00:53:27 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:56 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:57 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:53:58 AM] Info: Finalized mesh with 64 batches
+[00:54:04 AM] Info: Finalized mesh with 64 batches
diff --git a/KP3Dii/KP3Dii.vcxproj b/KP3Dii/KP3Dii.vcxproj
index fbad46b..efca154 100644
--- a/KP3Dii/KP3Dii.vcxproj
+++ b/KP3Dii/KP3Dii.vcxproj
@@ -168,6 +168,7 @@
+
@@ -222,6 +223,7 @@
+
diff --git a/KP3Dii/KP3Dii.vcxproj.filters b/KP3Dii/KP3Dii.vcxproj.filters
index 3d5de85..67fd3f8 100644
--- a/KP3Dii/KP3Dii.vcxproj.filters
+++ b/KP3Dii/KP3Dii.vcxproj.filters
@@ -43,6 +43,7 @@
+
@@ -101,6 +102,7 @@
+
diff --git a/KP3Dii/src/KP3D_Math.h b/KP3Dii/src/KP3D_Math.h
index ee98d5a..0994c30 100644
--- a/KP3Dii/src/KP3D_Math.h
+++ b/KP3Dii/src/KP3D_Math.h
@@ -54,6 +54,11 @@ KP3D_INLINE bool FloatCmp(float a, float b, float epsilon = 0.000001f) // std::n
return a > b - epsilon && a < b + epsilon;
}
+KP3D_INLINE bool FloatMod(float a, float n)
+{
+ return a - floor(a / n) * n;
+}
+
KP3D_INLINE bool PosCmp(Vec3 a, Vec3 b, float epsilon = 0.000001f)
{
return FloatCmp(a.x, b.x, epsilon) && FloatCmp(a.y, b.y, epsilon) && FloatCmp(a.z, b.z, epsilon);
diff --git a/KP3Dii/src/KP3D_Renderer3D.cpp b/KP3Dii/src/KP3D_Renderer3D.cpp
index 3ee5676..938f8aa 100644
--- a/KP3Dii/src/KP3D_Renderer3D.cpp
+++ b/KP3Dii/src/KP3D_Renderer3D.cpp
@@ -307,8 +307,8 @@ void Renderer3D::DrawBillboard(const Texture& texture, const Vec3& position, Vec
DrawMesh(r3d_state->billboard, m);
}
-void Renderer3D::DrawSmartBillboard(
- const std::vector& textures,
+void Renderer3D::DrawBillboardSprites(
+ const Texture** textures,
float degrees,
const Vec3& position,
Vec2 size,
@@ -316,10 +316,8 @@ void Renderer3D::DrawSmartBillboard(
float yaw
)
{
- auto fmod = [&](float a, float n) { return a - floor(a / n) * n; };
-
float angle = degrees - r3d_state->v->yaw;
- angle = fmod((angle + 180.0f), 360.0f) - 180.0f;
+ angle = FloatMod((angle + 180.0f), 360.0f) - 180.0f;
int idx = 0;
float fudge = 45.0f / 2.0f;
diff --git a/KP3Dii/src/KP3D_Renderer3D.h b/KP3Dii/src/KP3D_Renderer3D.h
index f689f32..b143254 100644
--- a/KP3Dii/src/KP3D_Renderer3D.h
+++ b/KP3Dii/src/KP3D_Renderer3D.h
@@ -24,8 +24,8 @@ public:
static void DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader = true, uint (*func_highlight)(const RenderBatch3D&) = nullptr, const Mat4& modelview = Mat4());
static void DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader = true, uint (*func_highlight)(const RenderBatch3D&) = nullptr);
static void DrawBillboard(const Texture& texture, const Vec3& position, Vec2 size, bool both_axes = false, float yaw = 90.0f);
- static void DrawSmartBillboard(
- const std::vector& textures,
+ static void DrawBillboardSprites(
+ const Texture** textures,
float degrees,
const Vec3& position,
Vec2 size,
diff --git a/KP3Dii/src/KP3D_Thing.cpp b/KP3Dii/src/KP3D_Thing.cpp
new file mode 100644
index 0000000..38b66f1
--- /dev/null
+++ b/KP3Dii/src/KP3D_Thing.cpp
@@ -0,0 +1,53 @@
+#include "KP3D_Thing.h"
+
+#include
+
+#include "KP3D_Renderer3D.h"
+
+namespace {
+
+std::unique_ptr default_sprite;
+
+void LoadDefaultSprite()
+{
+ if (default_sprite)
+ return;
+ default_sprite.reset(new kp3d::Texture());
+ default_sprite->Load(".kp3d/not_found.png");
+}
+
+} // namespace
+
+namespace kp3d {
+
+Thing::Thing():
+ display{Display::NONE}
+{
+ LoadDefaultSprite();
+}
+
+Thing::~Thing()
+{
+}
+
+void Thing::Update()
+{
+}
+
+void Thing::Render()
+{
+ switch (display.type)
+ {
+ case Display::NONE:
+ Renderer3D::DrawBillboard(*default_sprite.get(), transform.translation, {1.0f, 1.0f});
+ break;
+ case Display::MESH:
+ Renderer3D::DrawModel(*display.data.mesh.model, transform);
+ break;
+ case Display::SPRITES:
+ Renderer3D::DrawBillboardSprites(display.data.sprites.textures, transform.rotation.y, transform.translation, {1.0f, 1.0f});
+ break;
+ }
+}
+
+} // namespace kp3d
diff --git a/KP3Dii/src/KP3D_Thing.h b/KP3Dii/src/KP3D_Thing.h
new file mode 100644
index 0000000..16db026
--- /dev/null
+++ b/KP3Dii/src/KP3D_Thing.h
@@ -0,0 +1,71 @@
+#pragma once
+
+#include
+
+#include
+
+#include "KP3D_Common.h"
+#include "KP3D_Texture.h"
+#include "KP3D_Model.h"
+#include "KP3D_StaticMesh.h"
+#include "KP3D_Vec3.h"
+#include "KP3D_Transform.h"
+
+namespace kp3d {
+
+inline static constexpr size_t NUM_SPRITES_PER_DISPLAY = 8;
+
+struct Display
+{
+ enum Type: byte
+ {
+ NONE,
+ MESH,
+ SPRITES,
+ OTHER
+ } type;
+
+ enum Flags: byte
+ {
+ NO_FLAGS,
+ FLAG_FACE_CAMERA = 1 << 0,
+ FLAG_GROUNDED = 1 << 1,
+ FLAG_VISIBLE = 1 << 2,
+ FLAG_DELETE = 1 << 3,
+ FLAG_COLLISIONS = 1 << 4,
+ FLAG_RELATIVE_HR = 1 << 5
+ };
+
+ union Data
+ {
+ struct Mesh
+ {
+ Model* model;
+ Transform relative_transform;
+ int animation_index;
+ bool animating;
+ } mesh;
+
+ struct Sprites
+ {
+ Texture* textures[NUM_SPRITES_PER_DISPLAY];
+ } sprites;
+ } data;
+};
+
+class Thing
+{
+public:
+ Thing();
+ virtual ~Thing();
+
+ void Update();
+ void Render();
+
+public:
+ Display display;
+ Transform transform;
+
+};
+
+} // namespace kp3d