#include "raycast.h"
#include "irr_v3d.h"
#include "irr_aabb3d.h"
+#include <quaternion.h>
#include "constants.h"
bool RaycastSort::operator() (const PointedThing &pt1,
const PointedThing &pt2) const
{
- // "nothing" can not be sorted
+ // "nothing" cannot be sorted
assert(pt1.type != POINTEDTHING_NOTHING);
assert(pt2.type != POINTEDTHING_NOTHING);
+ f32 pt1_distSq = pt1.distanceSq;
+
+ // Add some bonus when one of them is an object
+ if (pt1.type != pt2.type) {
+ if (pt1.type == POINTEDTHING_OBJECT)
+ pt1_distSq -= BS * BS;
+ else if (pt2.type == POINTEDTHING_OBJECT)
+ pt1_distSq += BS * BS;
+ }
+
// returns false if pt1 is nearer than pt2
- if (pt1.distanceSq < pt2.distanceSq) {
+ if (pt1_distSq < pt2.distanceSq) {
return false;
}
- if (pt1.distanceSq == pt2.distanceSq) {
+ if (pt1_distSq == pt2.distanceSq) {
// Sort them to allow only one order
if (pt1.type == POINTEDTHING_OBJECT)
return (pt2.type == POINTEDTHING_OBJECT
bool boxLineCollision(const aabb3f &box, const v3f &start,
- const v3f &dir, v3f *collision_point, v3s16 *collision_normal)
+ const v3f &dir, v3f *collision_point, v3f *collision_normal)
{
if (box.isPointInside(start)) {
*collision_point = start;
}
return false;
}
+
+bool boxLineCollision(const aabb3f &box, const v3f &rotation,
+ const v3f &start, const v3f &dir,
+ v3f *collision_point, v3f *collision_normal, v3f *raw_collision_normal)
+{
+ // Inversely transform the ray rather than rotating the box faces;
+ // this allows us to continue using a simple ray - AABB intersection
+ core::quaternion rot(rotation * core::DEGTORAD);
+ rot.makeInverse();
+
+ bool collision = boxLineCollision(box, rot * start, rot * dir, collision_point, collision_normal);
+ if (!collision) return collision;
+
+ // Transform the results back
+ rot.makeInverse();
+ *collision_point = rot * *collision_point;
+ *raw_collision_normal = *collision_normal;
+ *collision_normal = rot * *collision_normal;
+ return collision;
+}