diff options
Diffstat (limited to 'src/3d')
| -rw-r--r-- | src/3d/object.h | 5 | ||||
| -rw-r--r-- | src/3d/plane_data.h | 6 | ||||
| -rw-r--r-- | src/3d/renderer.h | 4 | ||||
| -rw-r--r-- | src/3d/renderer_draw.cc | 36 | ||||
| -rw-r--r-- | src/3d/scene_loader.cc | 31 |
5 files changed, 72 insertions, 10 deletions
diff --git a/src/3d/object.h b/src/3d/object.h index dcd96e3..a8eb98c 100644 --- a/src/3d/object.h +++ b/src/3d/object.h @@ -6,6 +6,7 @@ #include "util/asset_manager_dcl.h" #include "util/mini_math.h" +#include <memory> // For std::shared_ptr enum class ObjectType { CUBE, @@ -42,12 +43,14 @@ class Object3D { AssetId mesh_asset_id; vec3 local_extent; // Half-extents for AABB (used by meshes for shadows) void* user_data; // For tool-specific data, not for general use + std::shared_ptr<void> + shared_user_data; // For tool-specific data managed with shared ownership Object3D(ObjectType t = ObjectType::CUBE) : position(0, 0, 0), rotation(0, 0, 0, 1), scale(1, 1, 1), type(t), color(1, 1, 1, 1), velocity(0, 0, 0), mass(1.0f), restitution(0.5f), is_static(false), mesh_asset_id((AssetId)0), local_extent(1, 1, 1), - user_data(nullptr) { + user_data(nullptr), shared_user_data(nullptr) { } mat4 get_model_matrix() const { diff --git a/src/3d/plane_data.h b/src/3d/plane_data.h new file mode 100644 index 0000000..e6a117d --- /dev/null +++ b/src/3d/plane_data.h @@ -0,0 +1,6 @@ +#pragma once + +// Local struct to hold plane-specific data +struct PlaneData { + float distance; +}; diff --git a/src/3d/renderer.h b/src/3d/renderer.h index 02e01d5..bf3b497 100644 --- a/src/3d/renderer.h +++ b/src/3d/renderer.h @@ -30,7 +30,9 @@ struct ObjectData { mat4 model; mat4 inv_model; vec4 color; - vec4 params; // Type, etc. + // params.x = object type (as float), params.y = plane_distance (if + // applicable) + vec4 params; }; class Renderer3D { diff --git a/src/3d/renderer_draw.cc b/src/3d/renderer_draw.cc index b50229f..2b19787 100644 --- a/src/3d/renderer_draw.cc +++ b/src/3d/renderer_draw.cc @@ -1,6 +1,7 @@ // This file is part of the 64k demo project. // It implements the drawing logic for Renderer3D. +#include "3d/plane_data.h" // Include for PlaneData struct #include "3d/renderer.h" #include "util/asset_manager_utils.h" #include <algorithm> @@ -55,8 +56,16 @@ void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera, type_id = 0.0f; break; } - data.params = vec4(type_id, obj.local_extent.x, obj.local_extent.y, - obj.local_extent.z); + + float plane_distance = 0.0f; + if (obj.type == ObjectType::PLANE && obj.shared_user_data) { + // Safely cast shared_user_data to PlaneData* and get distance + plane_distance = + static_cast<PlaneData*>(obj.shared_user_data.get())->distance; + } + + data.params = + vec4(type_id, plane_distance, obj.local_extent.x, obj.local_extent.y); obj_data.push_back(data); if (obj_data.size() >= kMaxObjects) break; @@ -190,12 +199,25 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, if (obj.type == ObjectType::TORUS) { extent = vec3(1.5f, 0.5f, 1.5f); } else if (obj.type == ObjectType::MESH) { - MeshAsset mesh = GetMeshAsset(obj.mesh_asset_id); - if (mesh.num_indices > 0) { + if (obj.user_data) { + // Manually loaded mesh (e.g., test_mesh tool) + struct MeshData { + std::vector<MeshVertex> vertices; + std::vector<uint32_t> indices; + }; + auto* data = (MeshData*)obj.user_data; visual_debug_.add_mesh_wireframe( - obj.get_model_matrix(), mesh.num_vertices, mesh.vertices, - mesh.num_indices, mesh.indices, - vec3(0.0f, 1.0f, 1.0f)); // Cyan wireframe + obj.get_model_matrix(), (uint32_t)data->vertices.size(), + data->vertices.data(), (uint32_t)data->indices.size(), + data->indices.data(), vec3(0.0f, 1.0f, 1.0f)); // Cyan wireframe + } else { + MeshAsset mesh = GetMeshAsset(obj.mesh_asset_id); + if (mesh.num_indices > 0) { + visual_debug_.add_mesh_wireframe( + obj.get_model_matrix(), mesh.num_vertices, mesh.vertices, + mesh.num_indices, mesh.indices, + vec3(0.0f, 1.0f, 1.0f)); // Cyan wireframe + } } } else { extent = vec3(1.0f, 1.0f, 1.0f); diff --git a/src/3d/scene_loader.cc b/src/3d/scene_loader.cc index 669fac8..286edca 100644 --- a/src/3d/scene_loader.cc +++ b/src/3d/scene_loader.cc @@ -1,9 +1,12 @@ #include "3d/scene_loader.h" #include "generated/assets.h" +#include "plane_data.h" #include "util/asset_manager.h" #include "util/mini_math.h" #include <cstdio> #include <cstring> +#include <memory> // For std::shared_ptr +#include <new> // For std::nothrow #include <vector> bool SceneLoader::LoadScene(Scene& scene, const uint8_t* data, size_t size) { @@ -73,17 +76,31 @@ bool SceneLoader::LoadScene(Scene& scene, const uint8_t* data, size_t size) { offset += 4; vec3 scale(sx, sy, sz); + // Color components (cr, cg, cb, ca) float cr = *reinterpret_cast<const float*>(data + offset); offset += 4; float cg = *reinterpret_cast<const float*>(data + offset); offset += 4; float cb = *reinterpret_cast<const float*>(data + offset); offset += 4; + // Read ca, advance offset AFTER reading ca, then construct color float ca = *reinterpret_cast<const float*>(data + offset); - offset += 4; + offset += 4; // Offset is now after ca vec4 color(cr, cg, cb, ca); + // Plane Distance (if type == PLANE) + float plane_distance = 0.0f; + if (type == ObjectType::PLANE) { + // Check bounds before reading plane_distance + if (offset + 4 > size) + return false; + plane_distance = *reinterpret_cast<const float*>(data + offset); + offset += 4; // Advance offset after reading plane_distance + } + // Mesh Asset Name Length + // The offset is now correctly positioned for name_len, + // either after ca (if not PLANE) or after plane_distance (if PLANE). if (offset + 4 > size) return false; uint32_t name_len = *reinterpret_cast<const uint32_t*>(data + offset); @@ -132,6 +149,18 @@ bool SceneLoader::LoadScene(Scene& scene, const uint8_t* data, size_t size) { obj.is_static = is_static; // user_data is nullptr by default + // Store plane distance in shared_user_data if it's a plane + if (type == ObjectType::PLANE) { + // Allocate PlaneData on the heap and manage with shared_ptr + // Use std::make_shared for exception safety and efficiency + obj.shared_user_data = std::make_shared<PlaneData>(); + // Assign the plane distance + // Safely cast void* to PlaneData* using static_cast on the shared_ptr's + // get() + static_cast<PlaneData*>(obj.shared_user_data.get())->distance = + plane_distance; + } + // Add to scene scene.add_object(obj); } |
