summaryrefslogtreecommitdiff
path: root/src/3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/3d')
-rw-r--r--src/3d/object.h5
-rw-r--r--src/3d/plane_data.h6
-rw-r--r--src/3d/renderer.h4
-rw-r--r--src/3d/renderer_draw.cc36
-rw-r--r--src/3d/scene_loader.cc31
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);
}