Просмотр исходного кода

resource: fix mesh AABB computation

Daniele Bartolini 7 лет назад
Родитель
Сommit
3643a56a89

+ 2 - 2
samples/core/shaders/default.shader

@@ -160,7 +160,7 @@ bgfx_shaders = {
 		varying = """
 			vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
 
-			vec2 a_position  : POSITION;
+			vec3 a_position  : POSITION;
 			vec2 a_texcoord0 : TEXCOORD0;
 		"""
 
@@ -172,7 +172,7 @@ bgfx_shaders = {
 		vs_code = """
 			void main()
 			{
-				gl_Position = mul(u_modelViewProj, vec4(a_position.x, 0.0, a_position.y, 1.0));
+				gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0));
 				v_texcoord0 = a_texcoord0;
 			}
 		"""

+ 18 - 11
src/core/math/aabb.cpp

@@ -9,23 +9,30 @@ namespace crown
 {
 namespace aabb
 {
-	void add_points(AABB& b, u32 num, u32 stride, const void* points)
+	void from_points(AABB& b, u32 num, u32 stride, const void* points)
 	{
 		const char* pts = (const char*)points;
-		for (u32 i = 0; i < num; ++i, pts += stride)
+		const f32* point = (f32*)pts;
+
+		b.min.x = b.max.x = point[0];
+		b.min.y = b.max.y = point[1];
+		b.min.z = b.max.z = point[2];
+		pts += stride;
+
+		for (u32 i = 1; i < num; ++i, pts += stride)
 		{
-			const Vector3& pi = *(const Vector3*)pts;
-
-			b.min.x = fmin(b.min.x, pi.x);
-			b.min.y = fmin(b.min.y, pi.y);
-			b.min.z = fmin(b.min.z, pi.z);
-			b.max.x = fmax(b.max.x, pi.x);
-			b.max.y = fmax(b.max.y, pi.y);
-			b.max.z = fmax(b.max.z, pi.z);
+			point = (f32*)pts;
+
+			b.min.x = fmin(b.min.x, point[0]);
+			b.min.y = fmin(b.min.y, point[1]);
+			b.min.z = fmin(b.min.z, point[2]);
+			b.max.x = fmax(b.max.x, point[0]);
+			b.max.y = fmax(b.max.y, point[1]);
+			b.max.z = fmax(b.max.z, point[2]);
 		}
 	}
 
-	void add_boxes(AABB& b, u32 num, const AABB* boxes)
+	void from_boxes(AABB& b, u32 num, const AABB* boxes)
 	{
 		for (u32 i = 0; i < num; ++i)
 		{

+ 15 - 16
src/core/math/aabb.h

@@ -20,6 +20,15 @@ namespace aabb
 	/// Resets the AABB @a b.
 	void reset(AABB& b);
 
+	/// Creates the AABB @a a from @a num @a points.
+	void from_points(AABB& a, u32 num, u32 stride, const void* points);
+
+	/// Creates the AABB @a a from @a num @a points.
+	void from_points(AABB& b, u32 num, const Vector3* points);
+
+	/// Creates the AABB @a a from @a num @a boxes.
+	void from_boxes(AABB& b, u32 num, const AABB* boxes);
+
 	/// Returns the center of the box @a b.
 	Vector3 center(const AABB& b);
 
@@ -29,15 +38,6 @@ namespace aabb
 	/// Returns the volume of the box @a b.
 	f32 volume(const AABB& b);
 
-	/// Adds @a num @a points to the box @a b, expanding its bounds if necessary.
-	void add_points(AABB& a, u32 num, u32 stride, const void* points);
-
-	/// Adds @a num @a points to the box @a b, expanding its bounds if necessary.
-	void add_points(AABB& b, u32 num, const Vector3* points);
-
-	/// Adds @a num @a boxes to the box @a b, expanding its bounds if necessary.
-	void add_boxes(AABB& b, u32 num, const AABB* boxes);
-
 	/// Returns whether point @a p is contained in the box @a b.
 	bool contains_point(const AABB& b, const Vector3& p);
 
@@ -63,6 +63,11 @@ namespace aabb
 		b.max = VECTOR3_ZERO;
 	}
 
+	inline void from_points(AABB& b, u32 num, const Vector3* points)
+	{
+		aabb::from_points(b, num, sizeof(Vector3), points);
+	}
+
 	inline Vector3 center(const AABB& b)
 	{
 		return (b.min + b.max) * 0.5f;
@@ -78,11 +83,6 @@ namespace aabb
 		return (b.max.x - b.min.x) * (b.max.y - b.min.y) * (b.max.z - b.min.z);
 	}
 
-	inline void add_points(AABB& b, u32 num, const Vector3* points)
-	{
-		aabb::add_points(b, num, sizeof(Vector3), points);
-	}
-
 	inline bool contains_point(const AABB& b, const Vector3& p)
 	{
 		return p.x > b.min.x
@@ -127,8 +127,7 @@ namespace aabb
 		vertices[7] = vertices[7] * m;
 
 		AABB r;
-		aabb::reset(r);
-		aabb::add_points(r, 8, vertices);
+		aabb::from_points(r, countof(vertices), vertices);
 		return r;
 	}
 

+ 1 - 2
src/core/math/frustum.h

@@ -107,8 +107,7 @@ namespace frustum
 		vertices[7] = vertex(f, 7);
 
 		AABB r;
-		aabb::reset(r);
-		aabb::add_points(r, 8, vertices);
+		aabb::from_points(r, countof(vertices), vertices);
 		return r;
 	}
 

+ 7 - 14
src/core/unit_tests.cpp

@@ -697,16 +697,14 @@ static void test_aabb()
 		ENSURE(fequal(c, 39.36f, 0.00001f));
 	}
 	{
-		AABB a;
-		aabb::reset(a);
-
 		const Vector3 points[] =
 		{
 			{ -1.2f,  3.4f,  5.5f },
 			{  8.2f, -2.4f, -1.5f },
 			{ -5.9f,  9.2f,  6.0f }
 		};
-		aabb::add_points(a, countof(points), points);
+		AABB a;
+		aabb::from_points(a, countof(points), points);
 		ENSURE(fequal(a.min.x, -5.9f, 0.00001f));
 		ENSURE(fequal(a.min.y, -2.4f, 0.00001f));
 		ENSURE(fequal(a.min.z, -1.5f, 0.00001f));
@@ -715,11 +713,6 @@ static void test_aabb()
 		ENSURE(fequal(a.max.z,  6.0f, 0.00001f));
 	}
 	{
-		AABB boxes[3];
-		aabb::reset(boxes[0]);
-		aabb::reset(boxes[1]);
-		aabb::reset(boxes[2]);
-
 		const Vector3 points[] =
 		{
 			{ -1.2f,  3.4f,  5.5f },
@@ -734,13 +727,13 @@ static void test_aabb()
 			{ -8.6f, -4.8f,  2.8f },
 			{  4.1f,  4.7f, -0.4f }
 		};
-		aabb::add_points(boxes[0], countof(points)/3, &points[0]);
-		aabb::add_points(boxes[1], countof(points)/3, &points[3]);
-		aabb::add_points(boxes[2], countof(points)/3, &points[6]);
+		AABB boxes[3];
+		aabb::from_points(boxes[0], countof(points)/3, &points[0]);
+		aabb::from_points(boxes[1], countof(points)/3, &points[3]);
+		aabb::from_points(boxes[2], countof(points)/3, &points[6]);
 
 		AABB d;
-		aabb::reset(d);
-		aabb::add_boxes(d, countof(boxes), boxes);
+		aabb::from_boxes(d, countof(boxes), boxes);
 		ENSURE(fequal(d.min.x, -8.6f, 0.00001f));
 		ENSURE(fequal(d.min.y, -4.8f, 0.00001f));
 		ENSURE(fequal(d.min.z, -2.2f, 0.00001f));

+ 4 - 8
src/resource/mesh_resource.cpp

@@ -233,18 +233,14 @@ namespace mesh_resource_internal
 			_decl.end();
 
 			// Bounds
-			aabb::reset(_aabb);
-			aabb::add_points(_aabb
+			aabb::from_points(_aabb
 				, array::size(_positions) / 3
-				, sizeof(f32) * 3
+				, sizeof(_positions[0]) * 3
 				, array::begin(_positions)
 				);
-			_aabb = aabb::transformed(_aabb, _matrix_local);
 
-			_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;
+			_obb.tm = matrix4x4(QUATERNION_IDENTITY, aabb::center(_aabb) * _matrix_local);
+			_obb.half_extents = (_aabb.max - _aabb.min) * 0.5f;
 		}
 
 		void write()

+ 14 - 15
src/resource/sprite_resource.cpp

@@ -80,46 +80,45 @@ namespace sprite_resource_internal
 			y1 = y1 == 0.0f ? y1 : -y1;
 
 			array::push_back(vertices, x0);
+			array::push_back(vertices, 0.0f);
 			array::push_back(vertices, y0);
 			array::push_back(vertices, u0);
 			array::push_back(vertices, v0);
 
 			array::push_back(vertices, x1);
+			array::push_back(vertices, 0.0f);
 			array::push_back(vertices, y0);
 			array::push_back(vertices, u1);
 			array::push_back(vertices, v0);
 
 			array::push_back(vertices, x1);
+			array::push_back(vertices, 0.0f);
 			array::push_back(vertices, y1);
 			array::push_back(vertices, u1);
 			array::push_back(vertices, v1);
 
 			array::push_back(vertices, x0);
+			array::push_back(vertices, 0.0f);
 			array::push_back(vertices, y1);
 			array::push_back(vertices, u0);
 			array::push_back(vertices, v1);
 		}
 
+		const u32 num_vertices = array::size(vertices) / 5; // 5 components per vertex
+
 		AABB aabb;
-		aabb::reset(aabb);
-		for (u32 i = 0; i < array::size(vertices); i += 4)
-		{
-			Vector3 v;
-			v.x = vertices[i + 0];
-			v.y = 0.0f;
-			v.z = vertices[i + 1];
-			aabb::add_points(aabb, 1, &v);
-		}
+		aabb::from_points(aabb
+			, num_vertices
+			, sizeof(vertices[0])*5
+			, array::begin(vertices)
+			);
+		// Enforce some thickness
 		aabb.min.y = -0.25f;
 		aabb.max.y =  0.25f;
 
 		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
+		obb.half_extents = (aabb.max - aabb.min) * 0.5f;
 
 		// Write
 		SpriteResource sr;
@@ -141,7 +140,7 @@ namespace sprite_resource
 {
 	const f32* frame_data(const SpriteResource* sr, u32 i)
 	{
-		return ((f32*)&sr[1]) + 16*i;
+		return ((f32*)&sr[1]) + 20*i;
 	}
 
 } // namespace sprite_resource

+ 36 - 32
src/world/render_world.cpp

@@ -228,10 +228,10 @@ f32 RenderWorld::sprite_cast_ray(UnitId unit, const Vector3& from, const Vector3
 
 	const f32 vertices[] =
 	{
-		frame[ 0], 0.0f, frame[ 1],
-		frame[ 4], 0.0f, frame[ 5],
-		frame[ 8], 0.0f, frame[ 9],
-		frame[12], 0.0f, frame[13]
+		frame[ 0], frame[ 1], frame[ 2],
+		frame[ 5], frame[ 6], frame[ 7],
+		frame[10], frame[11], frame[12],
+		frame[15], frame[16], frame[17]
 	};
 
 	const u16 indices[] =
@@ -408,7 +408,7 @@ void RenderWorld::render(const Matrix4x4& view)
 	{
 		bgfx::VertexDecl decl;
 		decl.begin()
-			.add(bgfx::Attrib::Position,  2, bgfx::AttribType::Float)
+			.add(bgfx::Attrib::Position,  3, bgfx::AttribType::Float)
 			.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float, false)
 			.end()
 			;
@@ -425,17 +425,17 @@ void RenderWorld::render(const Matrix4x4& view)
 		{
 			const f32* frame = sprite_resource::frame_data(sid.resource[i], sid.frame[i]);
 
-			f32 u0 = frame[ 2]; // u
-			f32 v0 = frame[ 3]; // v
+			f32 u0 = frame[ 3]; // u
+			f32 v0 = frame[ 4]; // v
 
-			f32 u1 = frame[ 6]; // u
-			f32 v1 = frame[ 7]; // v
+			f32 u1 = frame[ 8]; // u
+			f32 v1 = frame[ 9]; // v
 
-			f32 u2 = frame[10]; // u
-			f32 v2 = frame[11]; // v
+			f32 u2 = frame[13]; // u
+			f32 v2 = frame[14]; // v
 
-			f32 u3 = frame[14]; // u
-			f32 v3 = frame[15]; // v
+			f32 u3 = frame[18]; // u
+			f32 v3 = frame[19]; // v
 
 			if (sid.flip_x[i])
 			{
@@ -453,25 +453,29 @@ void RenderWorld::render(const Matrix4x4& view)
 
 			vdata[ 0] = frame[ 0]; // x
 			vdata[ 1] = frame[ 1]; // y
-			vdata[ 2] = u0;
-			vdata[ 3] = v0;
-
-			vdata[ 4] = frame[ 4]; // x
-			vdata[ 5] = frame[ 5]; // y
-			vdata[ 6] = u1;
-			vdata[ 7] = v1;
-
-			vdata[ 8] = frame[ 8]; // x
-			vdata[ 9] = frame[ 9]; // y
-			vdata[10] = u2;
-			vdata[11] = v2;
-
-			vdata[12] = frame[12]; // x
-			vdata[13] = frame[13]; // y
-			vdata[14] = u3;
-			vdata[15] = v3;
-
-			vdata += 16;
+			vdata[ 2] = frame[ 2]; // z
+			vdata[ 3] = u0;
+			vdata[ 4] = v0;
+
+			vdata[ 5] = frame[ 5]; // x
+			vdata[ 6] = frame[ 6]; // y
+			vdata[ 7] = frame[ 7]; // z
+			vdata[ 8] = u1;
+			vdata[ 9] = v1;
+
+			vdata[10] = frame[10]; // x
+			vdata[11] = frame[11]; // y
+			vdata[12] = frame[12]; // z
+			vdata[13] = u2;
+			vdata[14] = v2;
+
+			vdata[15] = frame[15]; // x
+			vdata[16] = frame[16]; // y
+			vdata[17] = frame[17]; // z
+			vdata[18] = u3;
+			vdata[19] = v3;
+
+			vdata += 20;
 
 			*idata++ = i*4+0;
 			*idata++ = i*4+1;