Explorar o código

Merge branch 'master' of github.com:taylor001/crown

Daniele Bartolini %!s(int64=10) %!d(string=hai) anos
pai
achega
45d4cfc1f8
Modificáronse 5 ficheiros con 89 adicións e 20 borrados
  1. 12 0
      docs/lua_api.txt
  2. 20 11
      src/core/math/intersection.cpp
  3. 4 0
      src/core/math/intersection.h
  4. 11 0
      src/core/math/plane.h
  5. 42 9
      src/lua/lua_math.cpp

+ 12 - 0
docs/lua_api.txt

@@ -273,6 +273,18 @@ Matrix4x4Box
 Math
 ----
 
+	**ray_plane_intersection** (from, dir, point, normal) : float
+		Returns the distance along ray (from, dir) to intersection point with plane defined by
+		*point* and *normal* or -1.0 if no intersection.
+
+	**ray_disc_intersection** (from, dir, center, radius, normal) : float
+		Returns the distance along ray (from, dir) to intersection point with disc defined by
+		*center*, *radius* and *normal* or -1.0 if no intersection.
+
+	**ray_sphere_intersection** (from, dir, center, radius) : float
+		Returns the distance along ray (from, dir) to intersection point with sphere defined by
+		*center* and *radius* or -1.0 if no intersection.
+
 	**ray_obb_intersection** (from, dir, tm, half_extents) : float
 		Returns the distance along ray (from, dir) to intersection point with the oriented
 		bounding box (tm, half_extents) or -1.0 if no intersection.

+ 20 - 11
src/core/math/intersection.cpp

@@ -12,12 +12,10 @@
 namespace crown
 {
 
-/// Returns the distance along ray (from, dir) to intersection point with plane @a p.
-/// -1.0f if no collision.
 float ray_plane_intersection(const Vector3& from, const Vector3& dir, const Plane& p)
 {
-	float nd = dot(dir, p.n);
-	float orpn = dot(from, p.n);
+	const float nd   = dot(dir, p.n);
+	const float orpn = dot(from, p.n);
 	float dist = -1.0f;
 
 	if (nd < 0.0f)
@@ -26,18 +24,29 @@ float ray_plane_intersection(const Vector3& from, const Vector3& dir, const Plan
 	return dist > 0.0f ? dist : -1.0f;
 }
 
-/// Returns the distance along ray (from, dir) to intersection point with sphere @a s.
-/// -1.0f if no collision.
+float ray_disc_intersection(const Vector3& from, const Vector3& dir, const Vector3& center, float radius, const Vector3& normal)
+{
+	Plane p = plane::from_point_and_normal(center, normal);
+	const float t = ray_plane_intersection(from, dir, p);
+
+	if (t == -1.0)
+		return -1.0;
+
+	const Vector3 intersection_point = from + dir * t;
+	if (distance(intersection_point, center) < radius)
+		return t;
+
+	return -1.0;
+}
+
 float ray_sphere_intersection(const Vector3& from, const Vector3& dir, const Sphere& s)
 {
-	Vector3 v = s.c - from;
-	float b = dot(v, dir);
-	float det = (s.r * s.r) - dot(v, v) + (b * b);
+	const Vector3 v = s.c - from;
+	const float b   = dot(v, dir);
+	const float det = (s.r * s.r) - dot(v, v) + (b * b);
 
 	if (det < 0.0 || b < s.r)
-	{
 		return -1.0f;
-	}
 
 	return b - sqrtf(det);
 }

+ 4 - 0
src/core/math/intersection.h

@@ -14,6 +14,10 @@ namespace crown
 /// or -1.0 if no intersection.
 float ray_plane_intersection(const Vector3& from, const Vector3& dir, const Plane& p);
 
+/// Returns the distance along ray (from, dir) to intersection point with disc defined by
+/// @a center, @a radius and @a normal or -1.0 if no intersection.
+float ray_disc_intersection(const Vector3& from, const Vector3& dir, const Vector3& center, float radius, const Vector3& normal);
+
 /// Returns the distance along ray (from, dir) to intersection point with sphere @a s
 /// or -1.0 if no intersection.
 float ray_sphere_intersection(const Vector3& from, const Vector3& dir, const Sphere& s);

+ 11 - 0
src/core/math/plane.h

@@ -21,6 +21,9 @@ const Plane PLANE_ZAXIS = { VECTOR3_ZAXIS, 0.0f };
 /// @ingroup Math
 namespace plane
 {
+	/// Returns the plane defined by @a point and @a normal.
+	Plane from_point_and_normal(const Vector3& point, const Vector3& normal);
+
 	/// Normalizes the plane @a p and returns its result.
 	Plane& normalize(Plane& p);
 
@@ -31,6 +34,14 @@ namespace plane
 
 namespace plane
 {
+	inline Plane from_point_and_normal(const Vector3& point, const Vector3& normal)
+	{
+		Plane p;
+		p.n = normal;
+		p.d = -dot(normal, point);
+		return p;
+	}
+
 	inline Plane& normalize(Plane& p)
 	{
 		const float len = length(p.n);

+ 42 - 9
src/lua/lua_math.cpp

@@ -9,6 +9,7 @@
 #include "matrix4x4.h"
 #include "quaternion.h"
 #include "color4.h"
+#include "plane.h"
 #include "intersection.h"
 #include "lua_stack.h"
 #include "lua_environment.h"
@@ -19,10 +20,27 @@ namespace crown
 static int math_ray_plane_intersection(lua_State* L)
 {
 	LuaStack stack(L);
-	Plane p;
-	p.n = stack.get_vector3(3);
-	p.d = stack.get_float(4);
-	stack.push_float(ray_plane_intersection(stack.get_vector3(1), stack.get_vector3(2), p));
+	const Plane p = plane::from_point_and_normal(stack.get_vector3(3)
+		, stack.get_vector3(4)
+		);
+	const float t = ray_plane_intersection(stack.get_vector3(1)
+		, stack.get_vector3(2)
+		, p
+		);
+	stack.push_float(t);
+	return 1;
+}
+
+static int math_ray_disc_intersection(lua_State* L)
+{
+	LuaStack stack(L);
+	const float t = ray_disc_intersection(stack.get_vector3(1)
+		, stack.get_vector3(2)
+		, stack.get_vector3(3)
+		, stack.get_float(4)
+		, stack.get_vector3(5)
+		);
+	stack.push_float(t);
 	return 1;
 }
 
@@ -32,17 +50,23 @@ static int math_ray_sphere_intersection(lua_State* L)
 	Sphere s;
 	s.c = stack.get_vector3(3);
 	s.r = stack.get_float(4);
-	stack.push_float(ray_sphere_intersection(stack.get_vector3(1), stack.get_vector3(2), s));
+	const float t = ray_sphere_intersection(stack.get_vector3(1)
+		, stack.get_vector3(2)
+		, s
+		);
+	stack.push_float(t);
 	return 1;
 }
 
 static int math_ray_obb_intersection(lua_State* L)
 {
 	LuaStack stack(L);
-	stack.push_float(ray_obb_intersection(stack.get_vector3(1)
+	const float t = ray_obb_intersection(stack.get_vector3(1)
 		, stack.get_vector3(2)
 		, stack.get_matrix4x4(3)
-		, stack.get_vector3(4)));
+		, stack.get_vector3(4)
+		);
+	stack.push_float(t);
 	return 1;
 }
 
@@ -551,8 +575,16 @@ static int matrix4x4_to_string(lua_State* L)
 {
 	LuaStack stack(L);
 	Matrix4x4& a = stack.get_matrix4x4(1);
-	stack.push_fstring("%.1f, %.1f, %.1f, %.1f\n%.1f, %.1f, %.1f, %.1f\n%.1f, %.1f, %.1f, %.1f\n%.1f, %.1f, %.1f, %.1f\n",
-						a.x.x, a.x.y, a.x.z, a.y.w, a.y.x, a.y.y, a.y.z, a.y.w, a.z.x, a.z.y, a.z.z, a.z.w, a.t.x, a.t.y, a.t.z, a.t.w);
+	stack.push_fstring(
+		"%.1f, %.1f, %.1f, %.1f\n"
+		"%.1f, %.1f, %.1f, %.1f\n"
+		"%.1f, %.1f, %.1f, %.1f\n"
+		"%.1f, %.1f, %.1f, %.1f\n"
+		, a.x.x, a.x.y, a.x.z, a.y.w
+		, a.y.x, a.y.y, a.y.z, a.y.w
+		, a.z.x, a.z.y, a.z.z, a.z.w
+		, a.t.x, a.t.y, a.t.z, a.t.w
+		);
 	return 1;
 }
 
@@ -864,6 +896,7 @@ static int lightuserdata_newindex(lua_State* L)
 void load_math(LuaEnvironment& env)
 {
 	env.load_module_function("Math", "ray_plane_intersection",  math_ray_plane_intersection);
+	env.load_module_function("Math", "ray_disc_intersection",   math_ray_disc_intersection);
 	env.load_module_function("Math", "ray_sphere_intersection", math_ray_sphere_intersection);
 	env.load_module_function("Math", "ray_obb_intersection",    math_ray_obb_intersection);