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