]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Line.hh
experimental shapes hierarchy and raycasting
[chaz/yoink] / src / Moof / Line.hh
diff --git a/src/Moof/Line.hh b/src/Moof/Line.hh
new file mode 100644 (file)
index 0000000..4a54e2d
--- /dev/null
@@ -0,0 +1,131 @@
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+ Redistribution   and   use  in  source  and  binary  forms,  with  or  without
+ modification, are permitted provided that the following conditions are met:
+   * Redistributions  of  source  code  must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+   * Redistributions  in binary form must reproduce the above copyright notice,
+     this  list of conditions and the following disclaimer in the documentation
+     and/or other materials provided with the distribution.
+ THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _MOOF_LINE_HH_
+#define _MOOF_LINE_HH_
+
+#include <Moof/Drawable.hh>
+#include <Moof/Math.hh>
+#include <Moof/OpenGL.hh>
+#include <Moof/Ray.hh>
+#include <Moof/Texture.hh>
+
+#include <Moof/Log.hh>
+
+
+namespace Mf {
+
+
+template <int D>
+struct Line : public Drawable, public Shape<D>
+{
+       typedef cml::vector< Scalar, cml::fixed<D> > Vector;
+
+       Vector  a;
+       Vector  b;
+
+       Scalar intersectRay(const Ray<2>& ray, Ray<2>::Intersection& intersection)
+       {
+               // solve: Cx + r*Dx = Ax + s(Bx - Ax)
+               //        Cy + r*Dy = Ay + s(By - Ay)
+               // where: 0 <= s <= 1 if intersection
+               // given: A = a
+               //        B = b
+               //        C = ray.point
+               //        D = ray.direction
+
+               Scalar denom = ray.direction[0] * (b[1] - a[1]) +
+                                          ray.direction[1] * (a[0] - b[0]);
+
+               // check if the ray and line are parallel
+               if (isEqual(denom, SCALAR(0.0)))
+               {
+                       Scalar numer = a[0] * (ray.point[1] - b[1]) +
+                                                  b[0] * (a[1] - ray.point[1]) +
+                                                  ray.point[0] * (b[1] - a[1]);
+
+                       // check if they are collinear
+                       if (isEqual(numer, SCALAR(0.0)))
+                       {
+                               intersection.point = ray.point;
+                               intersection.normal.set(0.0, 0.0);
+                               return SCALAR(0.0);
+                       }
+
+                       return SCALAR(-1.0);
+               }
+
+               Scalar s = (ray.direction[0] * (ray.point[1] - a[1]) +
+                                       ray.direction[1] * (a[0] - ray.point[0])) / denom;
+
+               // check if the ray hits the segment
+               if (s < SCALAR(0.0) || s > SCALAR(1.0)) return SCALAR(-1.0);
+
+               Scalar r = -(a[0] * (ray.point[1] - b[1]) +
+                                        b[0] * (a[1] - ray.point[1]) +
+                                        ray.point[0] * (b[1] - a[1])) / denom;
+
+               // make sure we're dealing with the right side of the ray
+               if (r < SCALAR(0.0)) return SCALAR(-1.0);
+
+               intersection.point = ray.point + r * ray.direction;
+
+               // gotta use the correct normal
+               Vector n = cml::perp(a - b);
+               if (cml::dot(a - ray.point, n) < 0) intersection.normal = n;
+               else                                intersection.normal = -n;
+
+               return r;
+       }
+
+       void draw(Scalar alpha = 0.0) const
+       {
+               Mf::Texture::resetBind();
+               glBegin(GL_LINES);
+                       glVertex(a);
+                       glVertex(b);
+               glEnd();
+       }
+};
+
+
+template <int D, int N>
+struct Polygon : public Shape<D>
+{
+       typedef cml::vector< Scalar, cml::fixed<D> > Vector;
+
+       Vector  points[N];
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_LINE_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
This page took 0.023229 seconds and 4 git commands to generate.