mirror of
https://github.com/overte-org/overte.git
synced 2025-07-10 18:58:37 +02:00
Add unit tests for ray intersections with shapes.
This commit is contained in:
parent
ab3d582d79
commit
fa6aed3e01
2 changed files with 416 additions and 0 deletions
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
//#include <stdio.h>
|
//#include <stdio.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
@ -897,6 +898,405 @@ void ShapeColliderTests::sphereMissesAACube() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShapeColliderTests::rayHitsSphere() {
|
||||||
|
float startDistance = 3.0f;
|
||||||
|
glm::vec3 rayStart(-startDistance, 0.0f, 0.0f);
|
||||||
|
glm::vec3 rayDirection(1.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
float radius = 1.0f;
|
||||||
|
glm::vec3 center(0.0f);
|
||||||
|
|
||||||
|
SphereShape sphere(radius, center);
|
||||||
|
|
||||||
|
// very simple ray along xAxis
|
||||||
|
{
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&sphere, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should intersect sphere" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
float expectedDistance = startDistance - radius;
|
||||||
|
float relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
if (relativeError > EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray sphere intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ray along a diagonal axis
|
||||||
|
{
|
||||||
|
rayStart = glm::vec3(startDistance, startDistance, 0.0f);
|
||||||
|
rayDirection = - glm::normalize(rayStart);
|
||||||
|
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&sphere, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should intersect sphere" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
float expectedDistance = SQUARE_ROOT_OF_2 * startDistance - radius;
|
||||||
|
float relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
if (relativeError > EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray sphere intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotated and displaced ray and sphere
|
||||||
|
{
|
||||||
|
startDistance = 7.41f;
|
||||||
|
radius = 3.917f;
|
||||||
|
|
||||||
|
glm::vec3 axis = glm::normalize(glm::vec3(1.0f, 2.0f, 3.0f));
|
||||||
|
glm::quat rotation = glm::angleAxis(0.987654321f, axis);
|
||||||
|
glm::vec3 translation(35.7f, 2.46f, -1.97f);
|
||||||
|
|
||||||
|
glm::vec3 unrotatedRayDirection(-1.0f, 0.0f, 0.0f);
|
||||||
|
glm::vec3 untransformedRayStart(startDistance, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
rayStart = rotation * (untransformedRayStart + translation);
|
||||||
|
rayDirection = rotation * unrotatedRayDirection;
|
||||||
|
|
||||||
|
sphere.setRadius(radius);
|
||||||
|
sphere.setPosition(rotation * translation);
|
||||||
|
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&sphere, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should intersect sphere" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
float expectedDistance = startDistance - radius;
|
||||||
|
float relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
if (relativeError > EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray sphere intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeColliderTests::rayBarelyHitsSphere() {
|
||||||
|
float radius = 1.0f;
|
||||||
|
glm::vec3 center(0.0f);
|
||||||
|
float delta = 2.0f * EPSILON;
|
||||||
|
|
||||||
|
float startDistance = 3.0f;
|
||||||
|
glm::vec3 rayStart(-startDistance, radius - delta, 0.0f);
|
||||||
|
glm::vec3 rayDirection(1.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
SphereShape sphere(radius, center);
|
||||||
|
|
||||||
|
// very simple ray along xAxis
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&sphere, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should just barely hit sphere" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// translate and rotate the whole system...
|
||||||
|
glm::vec3 axis = glm::normalize(glm::vec3(1.0f, 2.0f, 3.0f));
|
||||||
|
glm::quat rotation = glm::angleAxis(0.987654321f, axis);
|
||||||
|
glm::vec3 translation(35.7f, 2.46f, -1.97f);
|
||||||
|
|
||||||
|
rayStart = rotation * (rayStart + translation);
|
||||||
|
rayDirection = rotation * rayDirection;
|
||||||
|
sphere.setPosition(rotation * translation);
|
||||||
|
|
||||||
|
// ...and test again
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&sphere, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should just barely hit sphere" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ShapeColliderTests::rayBarelyMissesSphere() {
|
||||||
|
// same as the barely-hits case, but this time we move the ray away from sphere
|
||||||
|
float radius = 1.0f;
|
||||||
|
glm::vec3 center(0.0f);
|
||||||
|
float delta = 2.0f * EPSILON;
|
||||||
|
|
||||||
|
float startDistance = 3.0f;
|
||||||
|
glm::vec3 rayStart(-startDistance, radius + delta, 0.0f);
|
||||||
|
glm::vec3 rayDirection(1.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
SphereShape sphere(radius, center);
|
||||||
|
|
||||||
|
// very simple ray along xAxis
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&sphere, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should just barely miss sphere" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// translate and rotate the whole system...
|
||||||
|
glm::vec3 axis = glm::normalize(glm::vec3(1.0f, 2.0f, 3.0f));
|
||||||
|
glm::quat rotation = glm::angleAxis(0.987654321f, axis);
|
||||||
|
glm::vec3 translation(35.7f, 2.46f, -1.97f);
|
||||||
|
|
||||||
|
rayStart = rotation * (rayStart + translation);
|
||||||
|
rayDirection = rotation * rayDirection;
|
||||||
|
sphere.setPosition(rotation * translation);
|
||||||
|
|
||||||
|
// ...and test again
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&sphere, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should just barely miss sphere" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeColliderTests::rayHitsCapsule() {
|
||||||
|
float startDistance = 3.0f;
|
||||||
|
float radius = 1.0f;
|
||||||
|
float halfHeight = 2.0f;
|
||||||
|
glm::vec3 center(0.0f);
|
||||||
|
CapsuleShape capsule(radius, halfHeight);
|
||||||
|
|
||||||
|
{ // simple test along xAxis
|
||||||
|
// toward capsule center
|
||||||
|
glm::vec3 rayStart(startDistance, 0.0f, 0.0f);
|
||||||
|
glm::vec3 rayDirection(-1.0f, 0.0f, 0.0f);
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should hit capsule" << std::endl;
|
||||||
|
}
|
||||||
|
float expectedDistance = startDistance - radius;
|
||||||
|
float relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
if (relativeError > EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray capsule intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// toward top of cylindrical wall
|
||||||
|
rayStart.y = halfHeight;
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should hit capsule" << std::endl;
|
||||||
|
}
|
||||||
|
relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
if (relativeError > EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray capsule intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// toward top cap
|
||||||
|
float delta = 2.0f * EPSILON;
|
||||||
|
rayStart.y = halfHeight + delta;
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should hit capsule" << std::endl;
|
||||||
|
}
|
||||||
|
relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
if (relativeError > EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray capsule intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float EDGE_CASE_SLOP_FACTOR = 20.0f;
|
||||||
|
|
||||||
|
// toward tip of top cap
|
||||||
|
rayStart.y = halfHeight + radius - delta;
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should hit capsule" << std::endl;
|
||||||
|
}
|
||||||
|
expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
||||||
|
relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
// for edge cases we allow a LOT of error
|
||||||
|
if (relativeError > EDGE_CASE_SLOP_FACTOR * EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray capsule intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// toward tip of bottom cap
|
||||||
|
rayStart.y = - halfHeight - radius + delta;
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should hit capsule" << std::endl;
|
||||||
|
}
|
||||||
|
expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
||||||
|
relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
// for edge cases we allow a LOT of error
|
||||||
|
if (relativeError > EDGE_CASE_SLOP_FACTOR * EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray capsule intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// toward edge of capsule cylindrical face
|
||||||
|
rayStart.y = 0.0f;
|
||||||
|
rayStart.z = radius - delta;
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should hit capsule" << std::endl;
|
||||||
|
}
|
||||||
|
expectedDistance = startDistance - radius * sqrtf(2.0f * delta); // using small angle approximation of cosine
|
||||||
|
relativeError = fabsf(distance - expectedDistance) / startDistance;
|
||||||
|
// for edge cases we allow a LOT of error
|
||||||
|
if (relativeError > EDGE_CASE_SLOP_FACTOR * EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray capsule intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: test at steep angles near cylinder/cap junction
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeColliderTests::rayMissesCapsule() {
|
||||||
|
// same as edge case hit tests, but shifted in the opposite direction
|
||||||
|
float startDistance = 3.0f;
|
||||||
|
float radius = 1.0f;
|
||||||
|
float halfHeight = 2.0f;
|
||||||
|
glm::vec3 center(0.0f);
|
||||||
|
CapsuleShape capsule(radius, halfHeight);
|
||||||
|
|
||||||
|
{ // simple test along xAxis
|
||||||
|
// toward capsule center
|
||||||
|
glm::vec3 rayStart(startDistance, 0.0f, 0.0f);
|
||||||
|
glm::vec3 rayDirection(-1.0f, 0.0f, 0.0f);
|
||||||
|
float delta = 2.0f * EPSILON;
|
||||||
|
|
||||||
|
// over top cap
|
||||||
|
rayStart.y = halfHeight + radius + delta;
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should miss capsule" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// below bottom cap
|
||||||
|
rayStart.y = - halfHeight - radius - delta;
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should miss capsule" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// past edge of capsule cylindrical face
|
||||||
|
rayStart.y = 0.0f;
|
||||||
|
rayStart.z = radius + delta;
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&capsule, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should miss capsule" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: test at steep angles near edge
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeColliderTests::rayHitsPlane() {
|
||||||
|
// make a simple plane
|
||||||
|
float planeDistanceFromOrigin = 3.579;
|
||||||
|
glm::vec3 planePosition(0.0f, planeDistanceFromOrigin, 0.0f);
|
||||||
|
PlaneShape plane;
|
||||||
|
plane.setPosition(planePosition);
|
||||||
|
|
||||||
|
// make a simple ray
|
||||||
|
float startDistance = 1.234f;
|
||||||
|
glm::vec3 rayStart(-startDistance, 0.0f, 0.0f);
|
||||||
|
glm::vec3 rayDirection = glm::normalize(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&plane, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should hit plane" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
float expectedDistance = SQUARE_ROOT_OF_3 * planeDistanceFromOrigin;
|
||||||
|
float relativeError = fabsf(distance - expectedDistance) / planeDistanceFromOrigin;
|
||||||
|
if (relativeError > EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray plane intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate the whole system and try again
|
||||||
|
float angle = 37.8f;
|
||||||
|
glm::vec3 axis = glm::normalize( glm::vec3(-7.0f, 2.8f, 9.3f) );
|
||||||
|
glm::quat rotation = glm::angleAxis(angle, axis);
|
||||||
|
|
||||||
|
plane.setPosition(rotation * planePosition);
|
||||||
|
plane.setRotation(rotation);
|
||||||
|
rayStart = rotation * rayStart;
|
||||||
|
rayDirection = rotation * rayDirection;
|
||||||
|
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (!ShapeCollider::findRayIntersectionWithShape(&plane, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should hit plane" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedDistance = SQUARE_ROOT_OF_3 * planeDistanceFromOrigin;
|
||||||
|
relativeError = fabsf(distance - expectedDistance) / planeDistanceFromOrigin;
|
||||||
|
if (relativeError > EPSILON) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray plane intersection distance error = " << relativeError << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeColliderTests::rayMissesPlane() {
|
||||||
|
// make a simple plane
|
||||||
|
float planeDistanceFromOrigin = 3.579;
|
||||||
|
glm::vec3 planePosition(0.0f, planeDistanceFromOrigin, 0.0f);
|
||||||
|
PlaneShape plane;
|
||||||
|
plane.setPosition(planePosition);
|
||||||
|
|
||||||
|
{ // parallel rays should miss
|
||||||
|
float startDistance = 1.234f;
|
||||||
|
glm::vec3 rayStart(-startDistance, 0.0f, 0.0f);
|
||||||
|
glm::vec3 rayDirection = glm::normalize(glm::vec3(-1.0f, 0.0f, -1.0f));
|
||||||
|
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&plane, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should miss plane" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate the whole system and try again
|
||||||
|
float angle = 37.8f;
|
||||||
|
glm::vec3 axis = glm::normalize( glm::vec3(-7.0f, 2.8f, 9.3f) );
|
||||||
|
glm::quat rotation = glm::angleAxis(angle, axis);
|
||||||
|
|
||||||
|
plane.setPosition(rotation * planePosition);
|
||||||
|
plane.setRotation(rotation);
|
||||||
|
rayStart = rotation * rayStart;
|
||||||
|
rayDirection = rotation * rayDirection;
|
||||||
|
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&plane, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should miss plane" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // make a simple ray that points away from plane
|
||||||
|
float startDistance = 1.234f;
|
||||||
|
glm::vec3 rayStart(-startDistance, 0.0f, 0.0f);
|
||||||
|
glm::vec3 rayDirection = glm::normalize(glm::vec3(-1.0f, -1.0f, -1.0f));
|
||||||
|
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&plane, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should miss plane" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rotate the whole system and try again
|
||||||
|
float angle = 37.8f;
|
||||||
|
glm::vec3 axis = glm::normalize( glm::vec3(-7.0f, 2.8f, 9.3f) );
|
||||||
|
glm::quat rotation = glm::angleAxis(angle, axis);
|
||||||
|
|
||||||
|
plane.setPosition(rotation * planePosition);
|
||||||
|
plane.setRotation(rotation);
|
||||||
|
rayStart = rotation * rayStart;
|
||||||
|
rayDirection = rotation * rayDirection;
|
||||||
|
|
||||||
|
distance = FLT_MAX;
|
||||||
|
if (ShapeCollider::findRayIntersectionWithShape(&plane, rayStart, rayDirection, distance)) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: ray should miss plane" << std::endl;
|
||||||
|
}
|
||||||
|
if (distance != FLT_MAX) {
|
||||||
|
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: distance should be unchanged after intersection miss" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShapeColliderTests::runAllTests() {
|
void ShapeColliderTests::runAllTests() {
|
||||||
sphereMissesSphere();
|
sphereMissesSphere();
|
||||||
|
@ -911,4 +1311,12 @@ void ShapeColliderTests::runAllTests() {
|
||||||
sphereTouchesAACubeFaces();
|
sphereTouchesAACubeFaces();
|
||||||
sphereTouchesAACubeEdges();
|
sphereTouchesAACubeEdges();
|
||||||
sphereMissesAACube();
|
sphereMissesAACube();
|
||||||
|
|
||||||
|
rayHitsSphere();
|
||||||
|
rayBarelyHitsSphere();
|
||||||
|
rayBarelyMissesSphere();
|
||||||
|
rayHitsCapsule();
|
||||||
|
rayMissesCapsule();
|
||||||
|
rayHitsPlane();
|
||||||
|
rayMissesPlane();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,14 @@ namespace ShapeColliderTests {
|
||||||
void sphereTouchesAACubeEdges();
|
void sphereTouchesAACubeEdges();
|
||||||
void sphereMissesAACube();
|
void sphereMissesAACube();
|
||||||
|
|
||||||
|
void rayHitsSphere();
|
||||||
|
void rayBarelyHitsSphere();
|
||||||
|
void rayBarelyMissesSphere();
|
||||||
|
void rayHitsCapsule();
|
||||||
|
void rayMissesCapsule();
|
||||||
|
void rayHitsPlane();
|
||||||
|
void rayMissesPlane();
|
||||||
|
|
||||||
void runAllTests();
|
void runAllTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue