Ver Fonte

Add DebugLine::add_arc()

Daniele Bartolini há 8 anos atrás
pai
commit
3553b3d77c
4 ficheiros alterados com 73 adições e 33 exclusões
  1. 3 0
      docs/lua_api.rst
  2. 18 0
      src/lua/lua_api.cpp
  3. 47 31
      src/world/debug_line.cpp
  4. 5 2
      src/world/debug_line.h

+ 3 - 0
docs/lua_api.rst

@@ -939,6 +939,9 @@ DebugLine
 **add_axes** (debug_line, tm, length)
 	Adds lines for each axis with the given *length*.
 
+**add_arc** (debug_line, center, radius, plane_normal, midpoint_normal, color, [circle_segments = 36]);
+	Adds an arc at *center* with the given *radius* and *plane_normal* and *midpoint_normal* vectors.
+
 **add_circle** (debug_line, center, radius, normal, color, [segments = 36])
 	Adds a circle at *center* with the given *radius* and *normal* vector.
 

+ 18 - 0
src/lua/lua_api.cpp

@@ -2779,6 +2779,23 @@ static int debug_line_add_axes(lua_State* L)
 	return 0;
 }
 
+static int debug_line_add_arc(lua_State* L)
+{
+	LuaStack stack(L);
+	const u32 segments = stack.num_args() >= 7
+		? stack.get_int(7)
+		: DebugLine::NUM_SEGMENTS
+		;
+	stack.get_debug_line(1)->add_arc(stack.get_vector3(2)
+		, stack.get_float(3)
+		, stack.get_vector3(4)
+		, stack.get_vector3(5)
+		, stack.get_color4(6)
+		, segments
+		);
+	return 0;
+}
+
 static int debug_line_add_circle(lua_State* L)
 {
 	LuaStack stack(L);
@@ -3492,6 +3509,7 @@ void load_api(LuaEnvironment& env)
 
 	env.add_module_function("DebugLine", "add_line",    debug_line_add_line);
 	env.add_module_function("DebugLine", "add_axes",    debug_line_add_axes);
+	env.add_module_function("DebugLine", "add_arc",     debug_line_add_arc);
 	env.add_module_function("DebugLine", "add_circle",  debug_line_add_circle);
 	env.add_module_function("DebugLine", "add_cone",    debug_line_add_cone);
 	env.add_module_function("DebugLine", "add_sphere",  debug_line_add_sphere);

+ 47 - 31
src/world/debug_line.cpp

@@ -57,57 +57,73 @@ void DebugLine::add_axes(const Matrix4x4& m, f32 length)
 	add_line(pos, pos + z(m)*length, COLOR4_BLUE);
 }
 
+void DebugLine::add_arc(const Vector3& center, f32 radius, const Vector3& plane_normal, const Vector3& midpoint_normal, const Color4& color, u32 circle_segments)
+{
+	const Vector3 x = midpoint_normal * radius;
+	const Vector3 y = cross(midpoint_normal, plane_normal) * radius;
+	const u32 segments = circle_segments / 2;
+	const f32 step = PI / (f32)(segments > 3 ? segments : 3);
+	Vector3 from = center - y;
+
+	for (u32 i = 0; i <= segments; ++i)
+	{
+		const f32 t = step * i - PI_HALF;
+		const Vector3 to = center + x*cosf(t) + y*sinf(t);
+		add_line(from, to, color);
+		from = to;
+	}
+}
+
 void DebugLine::add_circle(const Vector3& center, f32 radius, const Vector3& normal, const Color4& color, u32 segments)
 {
-	const Vector3 dir = normal;
 	const Vector3 arr[] =
 	{
-		{ dir.z, dir.z, -dir.x -dir.y },
-		{ -dir.y -dir.z, dir.x, dir.x }
+		{ normal.z, normal.z, -normal.x -normal.y },
+		{ -normal.y -normal.z, normal.x, normal.x }
 	};
-	const int idx = ((dir.z != 0.0f) && (-dir.x != dir.y));
+	const int idx = ((normal.z != 0.0f) && (-normal.x != normal.y));
 	Vector3 right = arr[idx];
 	normalize(right);
 
-	const f32 incr = 360.0f / (f32)(segments >= 3 ? segments : 3);
-	f32 deg0 = 0.0f;
-	for (u32 ss = 0; ss < segments; ++ss, deg0 += incr)
-	{
-		const f32 rad0 = frad(deg0);
-		const f32 rad1 = frad(deg0 + incr);
-
-		const Vector3 from0 = right*cos(-rad0) + cross(dir, right)*sin(-rad0) + dir*dot(dir, right)*(1.0f-cos(-rad0));
-		const Vector3 from1 = right*cos(-rad1) + cross(dir, right)*sin(-rad1) + dir*dot(dir, right)*(1.0f-cos(-rad1));
+	const Vector3 x = right * radius;
+	const Vector3 y = cross(right, normal) * radius;
+	const f32 step = PI_TWO / (f32)(segments > 3 ? segments : 3);
+	Vector3 from = center - y;
 
-		add_line(center + radius*from0, center + radius*from1, color);
+	for (u32 i = 0; i <= segments; ++i)
+	{
+		const f32 t = step * i - PI_HALF;
+		const Vector3 to = center + x*cosf(t) + y*sinf(t);
+		add_line(from, to, color);
+		from = to;
 	}
 }
 
-void DebugLine::add_cone(const Vector3& from, const Vector3& to, f32 radius, const Color4& color, u32 segments)
+void DebugLine::add_cone(const Vector3& base_center, const Vector3& tip, f32 radius, const Color4& color, u32 segments)
 {
-	Vector3 dir = to - from;
-	normalize(dir);
+	Vector3 normal = tip - base_center;
+	normalize(normal);
 	const Vector3 arr[] =
 	{
-		{ dir.z, dir.z, -dir.x -dir.y },
-		{ -dir.y -dir.z, dir.x, dir.x }
+		{ normal.z, normal.z, -normal.x -normal.y },
+		{ -normal.y -normal.z, normal.x, normal.x }
 	};
-	const int idx = ((dir.z != 0.0f) && (-dir.x != dir.y));
+	const int idx = ((normal.z != 0.0f) && (-normal.x != normal.y));
 	Vector3 right = arr[idx];
 	normalize(right);
 
-	const f32 incr = 360.0f / (f32)(segments >= 3 ? segments : 3);
-	f32 deg0 = 0.0f;
-	for (u32 ss = 0; ss < segments; ++ss, deg0 += incr)
-	{
-		const f32 rad0 = frad(deg0);
-		const f32 rad1 = frad(deg0 + incr);
-
-		const Vector3 from0 = right*cos(-rad0) + cross(dir, right)*sin(-rad0) + dir*dot(dir, right)*(1.0f-cos(-rad0));
-		const Vector3 from1 = right*cos(-rad1) + cross(dir, right)*sin(-rad1) + dir*dot(dir, right)*(1.0f-cos(-rad1));
+	const Vector3 x = right * radius;
+	const Vector3 y = cross(right, normal) * radius;
+	const f32 step = PI_TWO / (f32)(segments > 3 ? segments : 3);
+	Vector3 from = base_center - y;
 
-		add_line(from + radius*from0, to, color);
-		add_line(from + radius*from0, from + radius*from1, color);
+	for (u32 i = 0; i <= segments; ++i)
+	{
+		const f32 t = step * i - PI_HALF;
+		const Vector3 to = base_center + x*cosf(t) + y*sinf(t);
+		add_line(from, to, color);
+		add_line(from, tip, color);
+		from = to;
 	}
 }
 

+ 5 - 2
src/world/debug_line.h

@@ -50,11 +50,14 @@ struct DebugLine
 	/// Adds lines for each axis with the given @a length.
 	void add_axes(const Matrix4x4& m, f32 length = 1.0f);
 
+	/// Adds an arc at @a center with the given @a radius and @a plane_normal and @a midpoint_normal vectors.
+	void add_arc(const Vector3& center, f32 radius, const Vector3& plane_normal, const Vector3& midpoint_normal, const Color4& color, u32 circle_segments = NUM_SEGMENTS);
+
 	/// Adds a circle at @a center with the given @a radius and @a normal vector.
 	void add_circle(const Vector3& center, f32 radius, const Vector3& normal, const Color4& color, u32 segments = NUM_SEGMENTS);
 
-	/// Adds a cone with the base centered at @a from and the tip at @a to.
-	void add_cone(const Vector3& from, const Vector3& to, f32 radius, const Color4& color, u32 segments = NUM_SEGMENTS);
+	/// Adds a cone with the base centered at @a base_center and the tip at @a tip.
+	void add_cone(const Vector3& base_center, const Vector3& tip, f32 radius, const Color4& color, u32 segments = NUM_SEGMENTS);
 
 	/// Adds a sphere at @a center with the given @a radius and @a color.
 	void add_sphere(const Vector3& center, const f32 radius, const Color4& color, u32 segments = NUM_SEGMENTS);