Bläddra i källkod

Add RenderWorld::sprite_obb()

Daniele Bartolini 8 år sedan
förälder
incheckning
dbc77eb7a8

+ 6 - 0
docs/lua_api.rst

@@ -607,6 +607,9 @@ Mesh
 **mesh_instances** (rw, unit) : Id
 	Returns the IDs for all the meshes of the *unit*.
 
+**mesh_obb** (rw, id) : Matrix4x4, Vector3
+	Returns the OBB of the mesh *id*.
+
 **mesh_raycast** (rw, id, from, dir) : float
 	Returns the distance along ray (from, dir) to intersection point with the mesh *id* or -1.0 if no intersection.
 
@@ -628,6 +631,9 @@ Sprite
 **sprite_set_visible** (rw, unit, visible)
 	Sets whether the sprite is *visible*.
 
+**sprite_obb** (rw, unit) : Matrix4x4, Vector3
+	Returns the OBB of the sprite.
+
 **sprite_flip_x** (rw, unit, flip)
 	Sets whether to flip the sprite on the x-axis.
 

+ 10 - 0
src/lua/lua_api.cpp

@@ -1947,6 +1947,15 @@ static int render_world_sprite_flip_y(lua_State* L)
 	return 0;
 }
 
+static int render_world_sprite_obb(lua_State* L)
+{
+	LuaStack stack(L);
+	OBB obb = stack.get_render_world(1)->sprite_obb(stack.get_unit(2));
+	stack.push_matrix4x4(obb.tm);
+	stack.push_vector3(obb.half_extents);
+	return 2;
+}
+
 static int render_world_sprite_raycast(lua_State* L)
 {
 	LuaStack stack(L);
@@ -3402,6 +3411,7 @@ void load_api(LuaEnvironment& env)
 	env.add_module_function("RenderWorld", "sprite_set_visible",   render_world_sprite_set_visible);
 	env.add_module_function("RenderWorld", "sprite_flip_x",        render_world_sprite_flip_x);
 	env.add_module_function("RenderWorld", "sprite_flip_y",        render_world_sprite_flip_y);
+	env.add_module_function("RenderWorld", "sprite_obb",           render_world_sprite_obb);
 	env.add_module_function("RenderWorld", "sprite_raycast",       render_world_sprite_raycast);
 	env.add_module_function("RenderWorld", "light_create",         render_world_light_create);
 	env.add_module_function("RenderWorld", "light_destroy",        render_world_light_destroy);

+ 26 - 2
src/resource/sprite_resource.cpp

@@ -3,6 +3,7 @@
  * License: https://github.com/taylor001/crown/blob/master/LICENSE
  */
 
+#include "aabb.h"
 #include "array.h"
 #include "compile_options.h"
 #include "config.h"
@@ -99,12 +100,35 @@ namespace sprite_resource_internal
 			array::push_back(vertices, v1);
 		}
 
+		AABB aabb;
+		aabb::reset(aabb);
+		for (u32 i = 0; i < array::size(vertices); i += 4)
+		{
+			Vector3 v;
+			v.x = vertices[i + 0];
+			v.y = vertices[i + 1];
+			v.z = 0.0f;
+			aabb::add_points(aabb, 1, &v);
+		}
+
+		OBB obb;
+		obb.tm = matrix4x4(QUATERNION_IDENTITY, aabb::center(aabb));
+		obb.half_extents.x = (aabb.max.x - aabb.min.x) * 0.5f;
+		obb.half_extents.y = (aabb.max.y - aabb.min.y) * 0.5f;
+		obb.half_extents.z = (aabb.max.z - aabb.min.z) * 0.5f;
+
 		const u32 num_vertices = array::size(vertices) / 4; // 4 components per vertex
 
 		// Write
-		opts.write(RESOURCE_VERSION_SPRITE);
+		SpriteResource sr;
+		sr.version = RESOURCE_VERSION_SPRITE;
+		sr.obb = obb;
+		sr.num_verts = num_vertices;
+
+		opts.write(sr.version);
+		opts.write(sr.obb);
 
-		opts.write(num_vertices);
+		opts.write(sr.num_verts);
 		for (u32 i = 0; i < array::size(vertices); i++)
 			opts.write(vertices[i]);
 	}

+ 1 - 0
src/resource/sprite_resource.h

@@ -18,6 +18,7 @@ namespace crown
 struct SpriteResource
 {
 	u32 version;
+	OBB obb;
 	u32 num_verts;
 	// verts[num_verts]
 };

+ 15 - 0
src/world/render_world.cpp

@@ -181,6 +181,21 @@ void RenderWorld::sprite_flip_y(UnitId unit, bool flip)
 	_sprite_manager._data.flip_y[i.i] = flip;
 }
 
+OBB RenderWorld::sprite_obb(UnitId unit)
+{
+	SpriteInstance i = _sprite_manager.sprite(unit);
+	CE_ASSERT(i.i < _sprite_manager._data.size, "Index out of bounds");
+
+	const OBB& obb = _sprite_manager._data.resource[i.i]->obb;
+	const Matrix4x4& world = _sprite_manager._data.world[i.i];
+
+	OBB o;
+	o.tm = obb.tm * world;
+	o.half_extents = obb.half_extents;
+
+	return o;
+}
+
 f32 RenderWorld::sprite_raycast(UnitId unit, const Vector3& from, const Vector3& dir)
 {
 	SpriteInstance i = _sprite_manager.sprite(unit);

+ 3 - 0
src/world/render_world.h

@@ -71,6 +71,9 @@ public:
 	/// Sets whether to flip the sprite on the y-axis.
 	void sprite_flip_y(UnitId unit, bool flip);
 
+	/// Returns the OBB of the sprite.
+	OBB sprite_obb(UnitId unit);
+
 	/// Returns the distance along ray (from, dir) to intersection point with sprite
 	/// or -1.0 if no intersection.
 	f32 sprite_raycast(UnitId unit, const Vector3& from, const Vector3& dir);