]> git.tdb.fi Git - r2c2.git/commitdiff
Report the closest object when picking
authorMikko Rasa <tdb@tdb.fi>
Tue, 25 Mar 2014 23:56:00 +0000 (01:56 +0200)
committerMikko Rasa <tdb@tdb.fi>
Wed, 26 Mar 2014 00:09:02 +0000 (02:09 +0200)
source/libr2c2/layout.cpp
source/libr2c2/object.cpp
source/libr2c2/object.h
source/libr2c2/vehicle.cpp
source/libr2c2/vehicle.h

index ac7101dfcf4e49708f8571a0f62bc4a9df292db4..c7dc346d61db45c652c3f553fc438c92e9f8576f 100644 (file)
@@ -188,12 +188,21 @@ template<typename T>
 T *Layout::pick(const Ray &ray)
 {
        const set<Object *> &objs = objects.get();
+       T *closest = 0;
+       float distance = -1;
        for(set<Object *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
                if(T *t = dynamic_cast<T *>(*i))
-                       if(t->collide_ray(ray))
-                               return t;
-
-       return 0;
+               {
+                       float d = -1;
+                       if(t->collide_ray(ray, &d))
+                               if(!closest || d<distance)
+                               {
+                                       closest = t;
+                                       distance = d;
+                               }
+               }
+
+       return closest;
 }
 
 template Object *Layout::pick<Object>(const Ray &);
index 7a23d11a04e4779ee13da5e094a80a059cc4f147..7a896b6581b40c849e5a3296c513260038b4c230 100644 (file)
@@ -2,6 +2,7 @@
 #include "object.h"
 
 using namespace std;
+using namespace Msp;
 
 namespace R2C2 {
 
@@ -95,7 +96,7 @@ const Shape *Object::get_shape() const
        return get_type().get_shape();
 }
 
-bool Object::collide_ray(const Ray &ray) const
+bool Object::collide_ray(const Ray &ray, float *d) const
 {
        const Shape *s = get_shape();
        if(!s)
@@ -103,7 +104,16 @@ bool Object::collide_ray(const Ray &ray) const
 
        Transform reverse_trans = Transform::rotation(rotation, Vector(0, 0, -1))*
                Transform::translation(-position);
-       return s->check_intersection(reverse_trans.transform(ray));
+       if(d)
+       {
+               vector<Geometry::SurfacePoint<float, 3> > points = s->get_intersections(reverse_trans.transform(ray));
+               if(points.empty())
+                       return false;
+               *d = points.front().distance;
+               return true;
+       }
+       else
+               return s->check_intersection(reverse_trans.transform(ray));
 }
 
 BoundingBox Object::get_bounding_box() const
index 22937921d47a92190edb2d8abc76ca254b9a761b..a0bd4f362714313bd72c5bc28b7c120bfd4f119f 100644 (file)
@@ -53,7 +53,7 @@ public:
        virtual void break_links();
 
        const Shape *get_shape() const;
-       virtual bool collide_ray(const Ray &) const;
+       virtual bool collide_ray(const Ray &, float * = 0) const;
        virtual BoundingBox get_bounding_box() const;
 };
 
index dee1e762239837164b7bdaed7b422e168eeff0be..cb776f413daacb20f82889076aeab17e451cc842 100644 (file)
@@ -356,10 +356,10 @@ int Vehicle::get_link_slot(const Object &other) const
                return -1;
 }
 
-bool Vehicle::collide_ray(const Ray &ray) const
+bool Vehicle::collide_ray(const Ray &ray, float *d) const
 {
        if(is_placed())
-               return Object::collide_ray(ray);
+               return Object::collide_ray(ray, d);
        else
                return false;
 }
index 33ca7284a6ce837d5378799ad7b6fed5c60397e6..b522b429125f1fecc3a65d92526c4f643a7da847 100644 (file)
@@ -108,7 +108,7 @@ public:
        virtual Vehicle *get_link(unsigned) const;
        virtual int get_link_slot(const Object &) const;
 
-       virtual bool collide_ray(const Ray &) const;
+       virtual bool collide_ray(const Ray &, float * = 0) const;
 };
 
 } // namespace R2C2