mirror of
https://github.com/lubosz/overte.git
synced 2025-04-07 15:22:09 +02:00
add parabola test, performance optimization
This commit is contained in:
parent
90091d11e4
commit
bfcf4f7865
4 changed files with 162 additions and 46 deletions
|
@ -310,31 +310,66 @@ bool AABox::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& v
|
|||
for (int i = 0; i < 3; i++) {
|
||||
a = 0.5f * acceleration[i];
|
||||
b = velocity[i];
|
||||
{ // min
|
||||
c = origin[i] - _corner[i];
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = -1.0f;
|
||||
if (origin[i] < _corner[i]) {
|
||||
// If we're below _corner, we only need to check the min face
|
||||
{ // min
|
||||
c = origin[i] - _corner[i];
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // max
|
||||
c = origin[i] - (_corner[i] + _scale[i]);
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i + 1);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = 1.0f;
|
||||
} else if (origin[i] > _corner[i] + _scale[i]) {
|
||||
// If we're above _corner + _scale, we only need to check the max face
|
||||
{ // max
|
||||
c = origin[i] - (_corner[i] + _scale[i]);
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i + 1);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If we're inside on this axis, we could hit either face depending on our velocity and acceleration, so we need to check both
|
||||
{ // min
|
||||
c = origin[i] - _corner[i];
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // max
|
||||
c = origin[i] - (_corner[i] + _scale[i]);
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i + 1);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -306,31 +306,66 @@ bool AACube::findParabolaIntersection(const glm::vec3& origin, const glm::vec3&
|
|||
for (int i = 0; i < 3; i++) {
|
||||
a = 0.5f * acceleration[i];
|
||||
b = velocity[i];
|
||||
{ // min
|
||||
c = origin[i] - _corner[i];
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = -1.0f;
|
||||
if (origin[i] < _corner[i]) {
|
||||
// If we're below _corner, we only need to check the min face
|
||||
{ // min
|
||||
c = origin[i] - _corner[i];
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // max
|
||||
c = origin[i] - (_corner[i] + _scale);
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i + 1);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = 1.0f;
|
||||
} else if (origin[i] > _corner[i] + _scale) {
|
||||
// If we're above _corner + _scale, we only need to check the max face
|
||||
{ // max
|
||||
c = origin[i] - (_corner[i] + _scale);
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i + 1);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If we're inside on this axis, we could hit either face depending on our velocity and acceleration, so we need to check both
|
||||
{ // min
|
||||
c = origin[i] - _corner[i];
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
{ // max
|
||||
c = origin[i] - (_corner[i] + _scale);
|
||||
possibleDistances = { FLT_MAX, FLT_MAX };
|
||||
if (computeRealQuadraticRoots(a, b, c, possibleDistances)) {
|
||||
bool hit = false;
|
||||
checkPossibleParabolicIntersection(possibleDistances.first, i, minDistance, origin, velocity, acceleration, hit);
|
||||
checkPossibleParabolicIntersection(possibleDistances.second, i, minDistance, origin, velocity, acceleration, hit);
|
||||
if (hit) {
|
||||
minFace = BoxFace(2 * i + 1);
|
||||
minNormal = glm::vec3(0.0f);
|
||||
minNormal[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,3 +152,47 @@ void AACubeTests::touchesSphere() {
|
|||
}
|
||||
}
|
||||
|
||||
void AACubeTests::rayVsParabolaPerformance() {
|
||||
// Test performance of findRayIntersection vs. findParabolaIntersection
|
||||
// 100000 cubes with scale 500 in the +x +y +z quadrant
|
||||
const int NUM_CUBES = 100000;
|
||||
const float MAX_POS = 1000.0f;
|
||||
const float MAX_SCALE = 500.0f;
|
||||
int numRayHits = 0;
|
||||
int numParabolaHits = 0;
|
||||
std::vector<AACube> cubes;
|
||||
cubes.reserve(NUM_CUBES);
|
||||
for (int i = 0; i < NUM_CUBES; i++) {
|
||||
cubes.emplace_back(glm::vec3(randFloatInRange(0.0f, MAX_POS), randFloatInRange(0.0f, MAX_POS), randFloatInRange(0.0f, MAX_POS)), MAX_SCALE);
|
||||
}
|
||||
|
||||
glm::vec3 origin(0.0f);
|
||||
glm::vec3 direction = glm::normalize(glm::vec3(1.0f));
|
||||
float distance;
|
||||
BoxFace face;
|
||||
glm::vec3 normal;
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
for (auto& cube : cubes) {
|
||||
if (cube.findRayIntersection(origin, direction, distance, face, normal)) {
|
||||
numRayHits++;
|
||||
}
|
||||
}
|
||||
|
||||
auto rayTime = std::chrono::high_resolution_clock::now() - start;
|
||||
start = std::chrono::high_resolution_clock::now();
|
||||
direction = 10.0f * direction;
|
||||
glm::vec3 acceleration = glm::vec3(-0.0001f, -0.0001f, -0.0001f);
|
||||
for (auto& cube : cubes) {
|
||||
if (cube.findParabolaIntersection(origin, direction, acceleration, distance, face, normal)) {
|
||||
numParabolaHits++;
|
||||
}
|
||||
}
|
||||
auto parabolaTime = std::chrono::high_resolution_clock::now() - start;
|
||||
|
||||
qDebug() << "Ray vs. Parabola perfomance: rayHit%:" << numRayHits / ((float)NUM_CUBES) * 100.0f << ", rayTime:" << rayTime.count() <<
|
||||
", parabolaHit%:" << numParabolaHits / ((float)NUM_CUBES) * 100.0f << ", parabolaTime:" << parabolaTime.count() << ", parabolaTime/rayTime: " << (float)parabolaTime.count()/(float)rayTime.count();
|
||||
}
|
||||
|
||||
void AACubeTests::cleanupTestCase() {
|
||||
|
||||
}
|
|
@ -23,6 +23,8 @@ private slots:
|
|||
void ctorsAndSetters();
|
||||
void containsPoint();
|
||||
void touchesSphere();
|
||||
void rayVsParabolaPerformance();
|
||||
void cleanupTestCase();
|
||||
};
|
||||
|
||||
#endif // hifi_AACubeTests_h
|
||||
|
|
Loading…
Reference in a new issue