mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
287 lines
10 KiB
C++
287 lines
10 KiB
C++
//
|
|
// SpaceTests.cpp
|
|
// tests/physics/src
|
|
//
|
|
// Created by Andrew Meadows on 2017.01.26
|
|
// Copyright 2017 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "SpaceTests.h"
|
|
|
|
#include <iostream>
|
|
|
|
#include <workload/Space.h>
|
|
#include <StreamUtils.h>
|
|
#include <SharedUtil.h>
|
|
|
|
|
|
const float INV_SQRT_3 = 1.0f / sqrtf(3.0f);
|
|
|
|
QTEST_MAIN(SpaceTests)
|
|
|
|
void SpaceTests::testOverlaps() {
|
|
QSKIP("Test removed due to being completely broken, please fix me!");
|
|
|
|
#if 0
|
|
// This seems to be completely broken and doesn't work on the current code.
|
|
// Leaving it as a historical reference, in case it's useful later.
|
|
|
|
workload::Space space;
|
|
using Changes = std::vector<workload::Space::Change>;
|
|
using Views = std::vector<workload::Space::View>;
|
|
|
|
glm::vec3 viewCenter(0.0f, 0.0f, 0.0f);
|
|
float near = 1.0f;
|
|
float mid = 2.0f;
|
|
float far = 3.0f;
|
|
|
|
Views views;
|
|
views.push_back(workload::Space::View(viewCenter, near, mid, far));
|
|
space.setViews(views);
|
|
|
|
int32_t proxyId = 0;
|
|
const float DELTA = 0.001f;
|
|
float proxyRadius = 0.5f;
|
|
glm::vec3 proxyPosition = viewCenter + glm::vec3(0.0f, 0.0f, far + proxyRadius + DELTA);
|
|
workload::Space::Sphere proxySphere(proxyPosition, proxyRadius);
|
|
|
|
{ // create very_far proxy
|
|
proxyId = space.createProxy(proxySphere);
|
|
QVERIFY(space.getNumObjects() == 1);
|
|
|
|
Changes changes;
|
|
space.categorizeAndGetChanges(changes);
|
|
QVERIFY(changes.size() == 0);
|
|
}
|
|
|
|
{ // move proxy far
|
|
float newRadius = 1.0f;
|
|
glm::vec3 newPosition = viewCenter + glm::vec3(0.0f, 0.0f, far + newRadius - DELTA);
|
|
workload::Space::Sphere newSphere(newPosition, newRadius);
|
|
std::vector<workload::Space::ProxyUpdate> updates;
|
|
updates.push_back(workload::Space::ProxyUpdate(proxyId, newSphere));
|
|
space.updateProxies(updates);
|
|
Changes changes;
|
|
space.categorizeAndGetChanges(changes);
|
|
QVERIFY(changes.size() == 1);
|
|
QVERIFY(changes[0].proxyId == proxyId);
|
|
QVERIFY(changes[0].region == workload::Space::REGION_FAR);
|
|
QVERIFY(changes[0].prevRegion == workload::Space::REGION_UNKNOWN);
|
|
}
|
|
|
|
{ // move proxy mid
|
|
float newRadius = 1.0f;
|
|
glm::vec3 newPosition = viewCenter + glm::vec3(0.0f, 0.0f, mid + newRadius - DELTA);
|
|
workload::Space::Sphere newSphere(newPosition, newRadius);
|
|
std::vector<workload::Space::ProxyUpdate> updates;
|
|
updates.push_back(workload::Space::ProxyUpdate(proxyId, newSphere));
|
|
space.updateProxies(updates);
|
|
Changes changes;
|
|
space.categorizeAndGetChanges(changes);
|
|
QVERIFY(changes.size() == 1);
|
|
QVERIFY(changes[0].proxyId == proxyId);
|
|
QVERIFY(changes[0].region == workload::Space::REGION_MIDDLE);
|
|
QVERIFY(changes[0].prevRegion == workload::Space::REGION_FAR);
|
|
}
|
|
|
|
{ // move proxy near
|
|
float newRadius = 1.0f;
|
|
glm::vec3 newPosition = viewCenter + glm::vec3(0.0f, 0.0f, near + newRadius - DELTA);
|
|
workload::Space::Sphere newSphere(newPosition, newRadius);
|
|
std::vector<workload::Space::ProxyUpdate> updates;
|
|
updates.push_back(workload::Space::ProxyUpdate(proxyId, newSphere));
|
|
space.updateProxies(updates);
|
|
Changes changes;
|
|
space.categorizeAndGetChanges(changes);
|
|
QVERIFY(changes.size() == 1);
|
|
QVERIFY(changes[0].proxyId == proxyId);
|
|
QVERIFY(changes[0].region == workload::Space::REGION_NEAR);
|
|
QVERIFY(changes[0].prevRegion == workload::Space::REGION_MIDDLE);
|
|
}
|
|
|
|
{ // delete proxy
|
|
// NOTE: atm deleting a proxy doesn't result in a "Change"
|
|
std::vector<int32_t> deadProxies;
|
|
deadProxies.push_back(proxyId);
|
|
space.deleteProxies(deadProxies);
|
|
Changes changes;
|
|
space.categorizeAndGetChanges(changes);
|
|
QVERIFY(changes.size() == 0);
|
|
QVERIFY(space.getNumObjects() == 0);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#ifdef MANUAL_TEST
|
|
|
|
const float WORLD_WIDTH = 1000.0f;
|
|
const float MIN_RADIUS = 1.0f;
|
|
const float MAX_RADIUS = 100.0f;
|
|
|
|
float randomFloat() {
|
|
return 2.0f * ((float)rand() / (float)RAND_MAX) - 1.0f;
|
|
}
|
|
|
|
glm::vec3 randomVec3() {
|
|
glm::vec3 v(randomFloat(), randomFloat(), randomFloat());
|
|
return v;
|
|
}
|
|
|
|
void generateSpheres(uint32_t numProxies, std::vector<workload::Space::Sphere>& spheres) {
|
|
spheres.reserve(numProxies);
|
|
for (uint32_t i = 0; i < numProxies; ++i) {
|
|
workload::Space::Sphere sphere(
|
|
WORLD_WIDTH * randomFloat(),
|
|
WORLD_WIDTH * randomFloat(),
|
|
WORLD_WIDTH * randomFloat(),
|
|
(MIN_RADIUS + (MAX_RADIUS - MIN_RADIUS)) * randomFloat());
|
|
spheres.push_back(sphere);
|
|
}
|
|
}
|
|
|
|
void generatePositions(uint32_t numProxies, std::vector<glm::vec3>& positions) {
|
|
positions.reserve(numProxies);
|
|
for (uint32_t i = 0; i < numProxies; ++i) {
|
|
positions.push_back(WORLD_WIDTH * randomVec3());
|
|
}
|
|
}
|
|
|
|
void generateRadiuses(uint32_t numRadiuses, std::vector<float>& radiuses) {
|
|
radiuses.reserve(numRadiuses);
|
|
for (uint32_t i = 0; i < numRadiuses; ++i) {
|
|
radiuses.push_back(MIN_RADIUS + (MAX_RADIUS - MIN_RADIUS) * randomFloat());
|
|
}
|
|
}
|
|
|
|
void SpaceTests::benchmark() {
|
|
uint32_t numProxies[] = { 100, 1000, 10000, 100000 };
|
|
uint32_t numTests = 4;
|
|
std::vector<uint64_t> timeToAddAll;
|
|
std::vector<uint64_t> timeToMoveView;
|
|
std::vector<uint64_t> timeToMoveProxies;
|
|
std::vector<uint64_t> timeToRemoveAll;
|
|
for (uint32_t i = 0; i < numTests; ++i) {
|
|
|
|
workload::Space space;
|
|
|
|
{ // build the views
|
|
std::vector<glm::vec3> viewPositions;
|
|
viewPositions.push_back(glm::vec3(0.0f, 0.0f, 0.0f));
|
|
viewPositions.push_back(glm::vec3(0.0f, 0.0f, 0.1f * WORLD_WIDTH));
|
|
float radius0 = 0.25f * WORLD_WIDTH;
|
|
float radius1 = 0.50f * WORLD_WIDTH;
|
|
float radius2 = 0.75f * WORLD_WIDTH;
|
|
std::vector<workload::Space::View> views;
|
|
views.push_back(workload::Space::View(viewPositions[0], radius0, radius1, radius2));
|
|
views.push_back(workload::Space::View(viewPositions[1], radius0, radius1, radius2));
|
|
space.setViews(views);
|
|
}
|
|
|
|
// build the proxies
|
|
uint32_t n = numProxies[i];
|
|
std::vector<workload::Space::Sphere> proxySpheres;
|
|
generateSpheres(n, proxySpheres);
|
|
std::vector<int32_t> proxyKeys;
|
|
proxyKeys.reserve(n);
|
|
|
|
// measure time to put proxies in the space
|
|
uint64_t startTime = usecTimestampNow();
|
|
for (uint32_t j = 0; j < n; ++j) {
|
|
int32_t key = space.createProxy(proxySpheres[j]);
|
|
proxyKeys.push_back(key);
|
|
}
|
|
uint64_t usec = usecTimestampNow() - startTime;
|
|
timeToAddAll.push_back(usec);
|
|
|
|
{
|
|
// build the views
|
|
std::vector<glm::vec3> viewPositions;
|
|
viewPositions.push_back(glm::vec3(1.0f, 2.0f, 3.0f));
|
|
viewPositions.push_back(glm::vec3(1.0f, 2.0f, 3.0f + 0.1f * WORLD_WIDTH));
|
|
float radius0 = 0.25f * WORLD_WIDTH;
|
|
float radius1 = 0.50f * WORLD_WIDTH;
|
|
float radius2 = 0.75f * WORLD_WIDTH;
|
|
std::vector<workload::Space::View> views;
|
|
views.push_back(workload::Space::View(viewPositions[0], radius0, radius1, radius2));
|
|
views.push_back(workload::Space::View(viewPositions[1], radius0, radius1, radius2));
|
|
space.setViews(views);
|
|
}
|
|
|
|
// measure time to categorizeAndGetChanges everything
|
|
std::vector<workload::Space::Change> changes;
|
|
startTime = usecTimestampNow();
|
|
space.categorizeAndGetChanges(changes);
|
|
usec = usecTimestampNow() - startTime;
|
|
timeToMoveView.push_back(usec);
|
|
|
|
// move every 10th proxy around
|
|
const float proxySpeed = 1.0f;
|
|
std::vector<workload::Space::Sphere> newSpheres;
|
|
uint32_t numMovingProxies = n / 10;
|
|
uint32_t jstep = n / numMovingProxies;
|
|
uint32_t maxJ = numMovingProxies * jstep - 1;
|
|
glm::vec3 direction;
|
|
for (uint32_t j = 0; j < maxJ - jstep; j += jstep) {
|
|
glm::vec3 position = (glm::vec3)proxySpheres[j];
|
|
glm::vec3 destination = (glm::vec3)proxySpheres[j + jstep];
|
|
direction = glm::normalize(destination - position);
|
|
glm::vec3 newPosition = position + proxySpeed * direction;
|
|
newSpheres.push_back(workload::Space::Sphere(newPosition, proxySpheres[j].w));
|
|
}
|
|
glm::vec3 position = (glm::vec3)proxySpheres[maxJ = jstep];
|
|
glm::vec3 destination = (glm::vec3)proxySpheres[0];
|
|
direction = glm::normalize(destination - position);
|
|
direction = position + proxySpeed * direction;
|
|
newSpheres.push_back(workload::Space::Sphere(direction, proxySpheres[0].w));
|
|
uint32_t k = 0;
|
|
startTime = usecTimestampNow();
|
|
for (uint32_t j = 0; j < maxJ; j += jstep) {
|
|
space.updateProxy(proxyKeys[j], newSpheres[k++]);
|
|
}
|
|
changes.clear();
|
|
space.categorizeAndGetChanges(changes);
|
|
usec = usecTimestampNow() - startTime;
|
|
timeToMoveProxies.push_back(usec);
|
|
|
|
// measure time to remove proxies from space
|
|
startTime = usecTimestampNow();
|
|
for (uint32_t j = 0; j < n; ++j) {
|
|
space.deleteProxy(proxyKeys[j]);
|
|
}
|
|
usec = usecTimestampNow() - startTime;
|
|
timeToRemoveAll.push_back(usec);
|
|
}
|
|
|
|
std::cout << "[numProxies, timeToAddAll] = [" << std::endl;
|
|
for (uint32_t i = 0; i < timeToAddAll.size(); ++i) {
|
|
uint32_t n = numProxies[i];
|
|
std::cout << " " << n << ", " << timeToAddAll[i] << std::endl;
|
|
}
|
|
std::cout << "];" << std::endl;
|
|
|
|
std::cout << "[numProxies, timeToMoveView] = [" << std::endl;
|
|
for (uint32_t i = 0; i < timeToMoveView.size(); ++i) {
|
|
uint32_t n = numProxies[i];
|
|
std::cout << " " << n << ", " << timeToMoveView[i] << std::endl;
|
|
}
|
|
std::cout << "];" << std::endl;
|
|
|
|
std::cout << "[numProxies, timeToMoveProxies] = [" << std::endl;
|
|
for (uint32_t i = 0; i < timeToMoveProxies.size(); ++i) {
|
|
uint32_t n = numProxies[i];
|
|
std::cout << " " << n << "/10, " << timeToMoveProxies[i] << std::endl;
|
|
}
|
|
std::cout << "];" << std::endl;
|
|
|
|
std::cout << "[numProxies, timeToRemoveAll] = [" << std::endl;
|
|
for (uint32_t i = 0; i < timeToRemoveAll.size(); ++i) {
|
|
uint32_t n = numProxies[i];
|
|
std::cout << " " << n << ", " << timeToRemoveAll[i] << std::endl;
|
|
}
|
|
std::cout << "];" << std::endl;
|
|
}
|
|
|
|
#endif // MANUAL_TEST
|