Bläddra i källkod

Added ray/cone intersection.

Branimir Karadžić 8 år sedan
förälder
incheckning
7b94b8dcb4
2 ändrade filer med 96 tillägg och 0 borttagningar
  1. 86 0
      examples/common/bounds.cpp
  2. 10 0
      examples/common/bounds.h

+ 86 - 0
examples/common/bounds.cpp

@@ -647,6 +647,92 @@ bool intersect(const Ray& _ray, const Cylinder& _cylinder, bool _capsule, Inters
 	return false;
 	return false;
 }
 }
 
 
+bool intersect(const Ray& _ray, const Cone& _cone, Intersection* _intersection)
+{
+	float axis[3];
+	bx::vec3Sub(axis, _cone.m_end, _cone.m_pos);
+
+	float normal[3];
+	const float len = bx::vec3Norm(normal, axis);
+
+	Disk disk;
+	bx::vec3Move(disk.m_center, _cone.m_pos);
+	bx::vec3Neg(disk.m_normal, normal);
+	disk.m_radius = _cone.m_radius;
+
+	if (intersect(_ray, disk, _intersection) )
+	{
+		return true;
+	}
+
+	float rs[3];
+	bx::vec3Sub(rs, _ray.m_pos, _cone.m_end);
+
+	const float hyp  = bx::fsqrt(bx::fsq(_cone.m_radius) + bx::fsq(len) );
+	const float cosa = len/hyp;
+
+	const float cosaSq = bx::fsq(cosa);
+
+	const float rsdotaxis = bx::vec3Dot(rs, normal);
+	const float rdota = bx::vec3Dot(normal, _ray.m_dir);
+
+	const float aa = bx::fsq(rdota) - cosaSq;
+	const float bb = 2.0f * (rdota*rsdotaxis - bx::vec3Dot(_ray.m_dir, rs)*cosaSq);
+	const float cc = bx::fsq(rsdotaxis) - bx::vec3Dot(rs, rs)*cosaSq;
+
+	float det = bb*bb - 4.0f*aa*cc;
+
+	if (0.0f > det)
+	{
+		return false;
+	}
+
+	det = bx::fsqrt(det);
+
+	float t1 = (-bb - det) / (2.0f * aa);
+	float t2 = (-bb + det) / (2.0f * aa);
+
+	float tt = t1;
+	if (0.0f > t1
+	|| (0.0f < t2 && t2 < t1) )
+	{
+		tt = t2;
+	}
+
+	if (0.0f > tt)
+	{
+		return false;
+	}
+
+	float point[3];
+	getPointAt(point, _ray, tt);
+
+	const float hh = bx::vec3Dot(normal, point);
+
+	if (0.0f > hh
+	||  len  < hh)
+	{
+		return false;
+	}
+
+	if (NULL != _intersection)
+	{
+		_intersection->m_dist = tt;
+
+		bx::vec3Move(_intersection->m_pos, point);
+
+		const float scale = hh / bx::vec3Dot(point, point);
+		float pointScaled[3];
+		bx::vec3Mul(pointScaled, point, scale);
+
+		float tmp[3];
+		bx::vec3Sub(tmp, pointScaled, normal);
+		bx::vec3Norm(_intersection->m_normal, tmp);
+	}
+
+	return true;
+}
+
 bool intersect(const Ray& _ray, const Plane& _plane, Intersection* _intersection)
 bool intersect(const Ray& _ray, const Plane& _plane, Intersection* _intersection)
 {
 {
 	float equation = bx::vec3Dot(_ray.m_pos, _plane.m_normal) + _plane.m_dist;
 	float equation = bx::vec3Dot(_ray.m_pos, _plane.m_normal) + _plane.m_dist;

+ 10 - 0
examples/common/bounds.h

@@ -19,6 +19,13 @@ struct Cylinder
 	float m_radius;
 	float m_radius;
 };
 };
 
 
+struct Cone
+{
+	float m_pos[3];
+	float m_end[3];
+	float m_radius;
+};
+
 struct Disk
 struct Disk
 {
 {
 	float m_center[3];
 	float m_center[3];
@@ -118,6 +125,9 @@ bool intersect(const Ray& _ray, const Aabb& _aabb, Intersection* _intersection =
 /// Intersect ray / cylinder.
 /// Intersect ray / cylinder.
 bool intersect(const Ray& _ray, const Cylinder& _cylinder, bool _capsule, Intersection* _intersection = NULL);
 bool intersect(const Ray& _ray, const Cylinder& _cylinder, bool _capsule, Intersection* _intersection = NULL);
 
 
+/// Intersect ray / cone.
+bool intersect(const Ray& _ray, const Cone& _cone, Intersection* _intersection = NULL);
+
 /// Intersect ray / disk.
 /// Intersect ray / disk.
 bool intersect(const Ray& _ray, const Disk& _disk, Intersection* _intersection = NULL);
 bool intersect(const Ray& _ray, const Disk& _disk, Intersection* _intersection = NULL);