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 &);
#include "object.h"
using namespace std;
+using namespace Msp;
namespace R2C2 {
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)
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
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;
};
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;
}
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