2015-10-15 18:21:32 +00:00
|
|
|
#include "CappedCylinder.h"
|
|
|
|
|
|
|
|
#include "Vector3.h"
|
|
|
|
#include "PackStream.h"
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
CappedCylinder::CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length)
|
2015-11-10 00:12:14 +00:00
|
|
|
: InfiniteCylinder(InfiniteRay(base, direction), radius), length(length),
|
|
|
|
container(base.add(direction.scale(length * 0.5)), length * 0.5) {
|
2015-10-15 18:21:32 +00:00
|
|
|
}
|
|
|
|
|
2015-11-10 00:12:14 +00:00
|
|
|
int CappedCylinder::findRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
|
2015-11-09 21:30:46 +00:00
|
|
|
Vector3 *second_intersection) const {
|
2015-11-10 00:12:14 +00:00
|
|
|
if (not container.checkRayIntersection(ray)) {
|
|
|
|
// We don't hit the containing sphere at all
|
2015-10-15 18:21:32 +00:00
|
|
|
return 0;
|
2015-11-10 00:12:14 +00:00
|
|
|
} else {
|
|
|
|
// TODO Apply the caps
|
|
|
|
int count = InfiniteCylinder::findRayIntersection(ray, first_intersection, second_intersection);
|
|
|
|
|
|
|
|
if (count == 0) {
|
|
|
|
return 0;
|
|
|
|
} else if (count == 2) {
|
|
|
|
if (checkPointProjection(first_intersection)) {
|
|
|
|
if (checkPointProjection(second_intersection)) {
|
|
|
|
return 2;
|
|
|
|
} else {
|
|
|
|
return 1;
|
|
|
|
}
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2015-11-10 00:12:14 +00:00
|
|
|
if (checkPointProjection(second_intersection)) {
|
|
|
|
*first_intersection = *second_intersection;
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
2015-10-15 18:21:32 +00:00
|
|
|
}
|
2015-11-10 00:12:14 +00:00
|
|
|
} else // count == 1
|
|
|
|
{
|
|
|
|
if (checkPointProjection(first_intersection)) {
|
2015-10-15 18:21:32 +00:00
|
|
|
return 1;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2015-10-15 18:21:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
bool CappedCylinder::checkPointProjection(Vector3 *point) const {
|
2015-10-15 18:21:32 +00:00
|
|
|
double proj_length = axis.getDirection().dotProduct(point->sub(axis.getOrigin()));
|
|
|
|
return 0.0 <= proj_length && proj_length <= length;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CappedCylinder::save(PackStream *stream) const {
|
2015-10-15 18:21:32 +00:00
|
|
|
InfiniteCylinder::save(stream);
|
|
|
|
stream->write(&length);
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CappedCylinder::load(PackStream *stream) {
|
2015-10-15 18:21:32 +00:00
|
|
|
InfiniteCylinder::load(stream);
|
|
|
|
stream->read(&length);
|
|
|
|
}
|