Przeglądaj źródła

Add RenderWorld.mesh_raycast()

Daniele Bartolini 9 lat temu
rodzic
commit
f46f5a310a
3 zmienionych plików z 37 dodań i 1 usunięć
  1. 13 0
      src/lua/lua_api.cpp
  2. 21 1
      src/world/render_world.cpp
  3. 3 0
      src/world/render_world.h

+ 13 - 0
src/lua/lua_api.cpp

@@ -1887,6 +1887,18 @@ static int render_world_mesh_obb(lua_State* L)
 	return 2;
 }
 
+static int render_world_mesh_raycast(lua_State* L)
+{
+	LuaStack stack(L);
+	RenderWorld* rw = stack.get_render_world(1);
+	float t = rw->mesh_raycast(stack.get_mesh_instance(2)
+		, stack.get_vector3(3)
+		, stack.get_vector3(4)
+		);
+	stack.push_float(t);
+	return 1;
+}
+
 static int render_world_set_mesh_visible(lua_State* L)
 {
 	LuaStack stack(L);
@@ -3356,6 +3368,7 @@ void load_api(LuaEnvironment& env)
 	env.add_module_function("RenderWorld", "destroy_mesh",         render_world_destroy_mesh);
 	env.add_module_function("RenderWorld", "mesh_instances",       render_world_mesh_instances);
 	env.add_module_function("RenderWorld", "mesh_obb",             render_world_mesh_obb);
+	env.add_module_function("RenderWorld", "mesh_raycast",         render_world_mesh_raycast);
 	env.add_module_function("RenderWorld", "set_mesh_visible",     render_world_set_mesh_visible);
 	env.add_module_function("RenderWorld", "create_sprite",        render_world_create_sprite);
 	env.add_module_function("RenderWorld", "destroy_sprite",       render_world_destroy_sprite);

+ 21 - 1
src/world/render_world.cpp

@@ -7,6 +7,7 @@
 #include "color4.h"
 #include "debug_line.h"
 #include "hash.h"
+#include "intersection.h"
 #include "material.h"
 #include "material_manager.h"
 #include "matrix4x4.h"
@@ -95,6 +96,20 @@ OBB RenderWorld::mesh_obb(MeshInstance i)
 	return _mesh_manager._data.obb[i.i];
 }
 
+f32 RenderWorld::mesh_raycast(MeshInstance i, const Vector3& from, const Vector3& dir)
+{
+	CE_ASSERT(i.i < _mesh_manager._data.size, "Index out of bounds");
+	const MeshGeometry* mg = _mesh_manager._data.geometry[i.i];
+	return ray_mesh_intersection(from
+		, dir
+		, _mesh_manager._data.world[i.i]
+		, mg->vertices.data
+		, mg->vertices.stride
+		, (u16*)mg->indices.data
+		, mg->indices.num
+		);
+}
+
 SpriteInstance RenderWorld::create_sprite(UnitId id, const SpriteRendererDesc& srd, const Matrix4x4& tr)
 {
 	const SpriteResource* sr = (const SpriteResource*)_resource_manager->get(RESOURCE_TYPE_SPRITE, srd.sprite_resource);
@@ -379,6 +394,7 @@ void RenderWorld::MeshManager::allocate(u32 num)
 	const u32 bytes = num * (0
 		+ sizeof(UnitId)
 		+ sizeof(MeshResource*)
+		+ sizeof(MeshGeometry*)
 		+ sizeof(MeshData)
 		+ sizeof(StringId64)
 		+ sizeof(Matrix4x4)
@@ -394,7 +410,8 @@ void RenderWorld::MeshManager::allocate(u32 num)
 
 	new_data.unit = (UnitId*)(new_data.buffer);
 	new_data.resource = (const MeshResource**)(new_data.unit + num);
-	new_data.mesh = (MeshData*)(new_data.resource + num);
+	new_data.geometry = (const MeshGeometry**)(new_data.resource + num);
+	new_data.mesh = (MeshData*)(new_data.geometry + num);
 	new_data.material = (StringId64*)(new_data.mesh + num);
 	new_data.world = (Matrix4x4*)(new_data.material + num);
 	new_data.obb = (OBB*)(new_data.world + num);
@@ -402,6 +419,7 @@ void RenderWorld::MeshManager::allocate(u32 num)
 
 	memcpy(new_data.unit, _data.unit, _data.size * sizeof(UnitId));
 	memcpy(new_data.resource, _data.resource, _data.size * sizeof(MeshResource*));
+	memcpy(new_data.geometry, _data.geometry, _data.size * sizeof(MeshGeometry*));
 	memcpy(new_data.mesh, _data.mesh, _data.size * sizeof(MeshData));
 	memcpy(new_data.material, _data.material, _data.size * sizeof(StringId64));
 	memcpy(new_data.world, _data.world, _data.size * sizeof(Matrix4x4));
@@ -426,6 +444,7 @@ MeshInstance RenderWorld::MeshManager::create(UnitId id, const MeshResource* mr,
 
 	_data.unit[last]          = id;
 	_data.resource[last]      = mr;
+	_data.geometry[last]      = mg;
 	_data.mesh[last].vbh      = mg->vertex_buffer;
 	_data.mesh[last].ibh      = mg->index_buffer;
 	_data.material[last]      = mat;
@@ -463,6 +482,7 @@ void RenderWorld::MeshManager::destroy(MeshInstance i)
 
 	_data.unit[i.i]          = _data.unit[last];
 	_data.resource[i.i]      = _data.resource[last];
+	_data.geometry[i.i]      = _data.geometry[last];
 	_data.mesh[i.i].vbh      = _data.mesh[last].vbh;
 	_data.mesh[i.i].ibh      = _data.mesh[last].ibh;
 	_data.material[i.i]      = _data.material[last];

+ 3 - 0
src/world/render_world.h

@@ -38,6 +38,8 @@ public:
 	void set_mesh_visible(MeshInstance i, bool visible);
 	OBB mesh_obb(MeshInstance i);
 
+	f32 mesh_raycast(MeshInstance i, const Vector3& from, const Vector3& dir);
+
 	/// Creates a new sprite instance.
 	SpriteInstance create_sprite(UnitId id, const SpriteRendererDesc& srd, const Matrix4x4& tr);
 
@@ -129,6 +131,7 @@ private:
 
 			UnitId* unit;
 			const MeshResource** resource;
+			const MeshGeometry** geometry;
 			MeshData* mesh;
 			StringId64* material;
 			Matrix4x4* world;