Преглед изворни кода

resource: compile whole mesh hierarchy

Daniele Bartolini пре 5 година
родитељ
комит
d91f550e61

+ 43 - 23
src/resource/mesh_resource.cpp

@@ -249,8 +249,6 @@ namespace mesh_resource_internal
 		Array<u16> _tangent_indices;
 		Array<u16> _binormal_indices;
 
-		Matrix4x4 _matrix_local;
-
 		u32 _vertex_stride;
 		Array<char> _vertex_buffer;
 		Array<u16> _index_buffer;
@@ -275,7 +273,6 @@ namespace mesh_resource_internal
 			, _uv_indices(default_allocator())
 			, _tangent_indices(default_allocator())
 			, _binormal_indices(default_allocator())
-			, _matrix_local(MATRIX4X4_IDENTITY)
 			, _vertex_stride(0)
 			, _vertex_buffer(default_allocator())
 			, _index_buffer(default_allocator())
@@ -331,13 +328,11 @@ namespace mesh_resource_internal
 			}
 		}
 
-		void parse(const char* geometry, const char* node)
+		void parse(const char* geometry)
 		{
 			TempAllocator4096 ta;
 			JsonObject obj(ta);
-			JsonObject obj_node(ta);
 			sjson::parse(obj, geometry);
-			sjson::parse(obj_node, node);
 
 			_has_normal = json_object::has(obj, "normal");
 			_has_uv     = json_object::has(obj, "texcoord");
@@ -355,8 +350,6 @@ namespace mesh_resource_internal
 
 			parse_indices(obj["indices"]);
 
-			_matrix_local = sjson::parse_matrix4x4(obj_node["matrix_local"]);
-
 			_vertex_stride = 0;
 			_vertex_stride += 3 * sizeof(f32);
 			_vertex_stride += (_has_normal ? 3 * sizeof(f32) : 0);
@@ -375,7 +368,6 @@ namespace mesh_resource_internal
 				xyz.x = _positions[p_idx + 0];
 				xyz.y = _positions[p_idx + 1];
 				xyz.z = _positions[p_idx + 2];
-				xyz = xyz * _matrix_local;
 				array::push(_vertex_buffer, (char*)&xyz, sizeof(xyz));
 
 				if (_has_normal)
@@ -419,7 +411,7 @@ namespace mesh_resource_internal
 				, array::begin(_positions)
 				);
 
-			_obb.tm = from_quaternion_translation(QUATERNION_IDENTITY, aabb::center(_aabb) * _matrix_local);
+			_obb.tm = from_quaternion_translation(QUATERNION_IDENTITY, aabb::center(_aabb));
 			_obb.half_extents = (_aabb.max - _aabb.min) * 0.5f;
 		}
 
@@ -438,6 +430,42 @@ namespace mesh_resource_internal
 		}
 	};
 
+	s32 compile_node(MeshCompiler& mc, CompileOptions& opts, const JsonObject& geometries, const HashMap<StringView, const char*>::Entry* entry)
+	{
+		TempAllocator4096 ta;
+		const StringView key = entry->first;
+		const char* node = entry->second;
+		const char* geometry = geometries[key];
+
+		const StringId32 node_name(key.data(), key.length());
+		opts.write(node_name._id);
+
+		JsonObject obj_node(ta);
+		sjson::parse(obj_node, node);
+
+		mc.reset();
+		mc.parse(geometry);
+		mc.write();
+
+		if (json_object::has(obj_node, "children"))
+		{
+			JsonObject children(ta);
+			sjson::parse_object(children, obj_node["children"]);
+
+			auto cur = json_object::begin(children);
+			auto end = json_object::end(children);
+			for (; cur != end; ++cur)
+			{
+				JSON_OBJECT_SKIP_HOLE(children, cur);
+
+				s32 err = compile_node(mc, opts, geometries, cur);
+				DATA_COMPILER_ENSURE(err == 0, opts);
+			}
+		}
+
+		return 0;
+	}
+
 	s32 compile(CompileOptions& opts)
 	{
 		Buffer buf = opts.read();
@@ -456,22 +484,14 @@ namespace mesh_resource_internal
 
 		MeshCompiler mc(opts);
 
-		auto cur = json_object::begin(geometries);
-		auto end = json_object::end(geometries);
+		auto cur = json_object::begin(nodes);
+		auto end = json_object::end(nodes);
 		for (; cur != end; ++cur)
 		{
-			JSON_OBJECT_SKIP_HOLE(geometries, cur);
-
-			const StringView key = cur->first;
-			const char* geometry = cur->second;
-			const char* node = nodes[key];
-
-			const StringId32 name(key.data(), key.length());
-			opts.write(name._id);
+			JSON_OBJECT_SKIP_HOLE(nodes, cur);
 
-			mc.reset();
-			mc.parse(geometry, node);
-			mc.write();
+			s32 err = compile_node(mc, opts, geometries, cur);
+			DATA_COMPILER_ENSURE(err == 0, opts);
 		}
 
 		return 0;

+ 30 - 2
src/resource/physics_resource.cpp

@@ -154,6 +154,31 @@ namespace physics_resource_internal
 		sd.box.half_size = (aabb.max - aabb.min) * 0.5f;
 	}
 
+	const char* find_node_by_name(const JsonObject& nodes, const char* name)
+	{
+		auto cur = json_object::begin(nodes);
+		auto end = json_object::end(nodes);
+		for (; cur != end; ++cur)
+		{
+			JSON_OBJECT_SKIP_HOLE(nodes, cur);
+
+			if (cur->first == name)
+				return cur->second;
+
+			TempAllocator512 ta;
+			JsonObject node(ta);
+			JsonObject children(ta);
+			sjson::parse_object(node, cur->second);
+			if (json_object::has(node, "children"))
+			{
+				sjson::parse_object(children, node["children"]);
+				return find_node_by_name(children, name);
+			}
+		}
+
+		return NULL;
+	}
+
 	s32 compile_collider(Buffer& output, const char* json, CompileOptions& opts)
 	{
 		TempAllocator4096 ta;
@@ -208,13 +233,16 @@ namespace physics_resource_internal
 				, name.c_str()
 				);
 			sjson::parse(geometry, geometries[name.c_str()]);
+
+			// Find node
 			sjson::parse(nodes, json_mesh["nodes"]);
-			DATA_COMPILER_ASSERT(json_object::has(nodes, name.c_str())
+			const char* node_data = find_node_by_name(nodes, name.c_str());
+			DATA_COMPILER_ASSERT(node_data != NULL
 				, opts
 				, "Node '%s' does not exist"
 				, name.c_str()
 				);
-			sjson::parse(node, nodes[name.c_str()]);
+			sjson::parse(node, node_data);
 
 			Matrix4x4 matrix_local = sjson::parse_matrix4x4(node["matrix_local"]);
 			cd.local_tm = matrix_local;

+ 1 - 1
src/resource/types.h

@@ -63,7 +63,7 @@ struct UnitResource;
 #define RESOURCE_VERSION_UNIT             RESOURCE_VERSION(6)
 #define RESOURCE_VERSION_LEVEL            (RESOURCE_VERSION_UNIT + 4) //!< Level embeds UnitResource
 #define RESOURCE_VERSION_MATERIAL         RESOURCE_VERSION(2)
-#define RESOURCE_VERSION_MESH             RESOURCE_VERSION(3)
+#define RESOURCE_VERSION_MESH             RESOURCE_VERSION(4)
 #define RESOURCE_VERSION_PACKAGE          RESOURCE_VERSION(5)
 #define RESOURCE_VERSION_PHYSICS_CONFIG   RESOURCE_VERSION(1)
 #define RESOURCE_VERSION_SCRIPT           RESOURCE_VERSION(1)

+ 1 - 1
src/world/physics_world_bullet.cpp

@@ -355,7 +355,7 @@ struct PhysicsWorldImpl
 
 		ColliderInstanceData cid;
 		cid.unit         = unit;
-		cid.local_tm     = sd->local_tm;
+		cid.local_tm     = MATRIX4X4_IDENTITY;
 		cid.vertex_array = vertex_array;
 		cid.shape        = child_shape;
 		cid.next.i       = UINT32_MAX;