paysages3d/src/basics/CappedCylinder.cpp
2015-11-18 17:22:33 +01:00

61 lines
2 KiB
C++

#include "CappedCylinder.h"
#include "Vector3.h"
#include "PackStream.h"
CappedCylinder::CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length)
: InfiniteCylinder(InfiniteRay(base, direction), radius), length(length),
container(base.add(direction.scale(length * 0.5)), length * 0.5) {
}
int CappedCylinder::findRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
Vector3 *second_intersection) const {
if (not container.checkRayIntersection(ray)) {
// We don't hit the containing sphere at all
return 0;
} 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;
}
} else {
if (checkPointProjection(second_intersection)) {
*first_intersection = *second_intersection;
return 1;
} else {
return 0;
}
}
} else {
// count == 1
if (checkPointProjection(first_intersection)) {
return 1;
} else {
return 0;
}
}
}
}
bool CappedCylinder::checkPointProjection(Vector3 *point) const {
double proj_length = axis.getDirection().dotProduct(point->sub(axis.getOrigin()));
return 0.0 <= proj_length && proj_length <= length;
}
void CappedCylinder::save(PackStream *stream) const {
InfiniteCylinder::save(stream);
stream->write(&length);
}
void CappedCylinder::load(PackStream *stream) {
InfiniteCylinder::load(stream);
stream->read(&length);
}