overte/tests/physics/src/ShapeManagerTests.cpp
2018-05-04 16:26:41 -07:00

246 lines
7.7 KiB
C++

//
// ShapeManagerTests.cpp
// tests/physics/src
//
// Created by Andrew Meadows on 2014.10.30
// Copyright 2014 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 "ShapeManagerTests.h"
#include <iostream>
#include <ShapeManager.h>
#include <StreamUtils.h>
#include <Extents.h>
QTEST_MAIN(ShapeManagerTests)
void ShapeManagerTests::testShapeAccounting() {
ShapeManager shapeManager;
ShapeInfo info;
info.setBox(glm::vec3(1.0f, 1.0f, 1.0f));
int numReferences = shapeManager.getNumReferences(info);
QCOMPARE(numReferences, 0);
// create one shape and verify we get a valid pointer
const btCollisionShape* shape = shapeManager.getShape(info);
QCOMPARE(shape != nullptr, true);
// verify number of shapes
QCOMPARE(shapeManager.getNumShapes(), 1);
// reference the shape again and verify that we get the same pointer
const btCollisionShape* otherShape = shapeManager.getShape(info);
QCOMPARE(otherShape, shape);
// verify number of references
numReferences = shapeManager.getNumReferences(info);
int expectedNumReferences = 2;
QCOMPARE(numReferences, expectedNumReferences);
// release all references
bool released = shapeManager.releaseShape(shape);
numReferences--;
while (numReferences > 0) {
released = shapeManager.releaseShape(shape) && released;
numReferences--;
}
QCOMPARE(released, true);
// verify shape still exists (not yet garbage collected)
QCOMPARE(shapeManager.getNumShapes(), 1);
// verify shape's refcount is zero
numReferences = shapeManager.getNumReferences(info);
QCOMPARE(numReferences, 0);
// reference the shape again and verify refcount is updated
otherShape = shapeManager.getShape(info);
numReferences = shapeManager.getNumReferences(info);
QCOMPARE(numReferences, 1);
// verify that shape is not collected as garbage
shapeManager.collectGarbage();
QCOMPARE(shapeManager.getNumShapes(), 1);
numReferences = shapeManager.getNumReferences(info);
QCOMPARE(numReferences, 1);
// release reference and verify that it is collected as garbage
released = shapeManager.releaseShape(shape);
shapeManager.collectGarbage();
QCOMPARE(shapeManager.getNumShapes(), 0);
QCOMPARE(shapeManager.hasShape(shape), false);
// add the shape again and verify that it gets added again
otherShape = shapeManager.getShape(info);
numReferences = shapeManager.getNumReferences(info);
QCOMPARE(numReferences, 1);
}
void ShapeManagerTests::addManyShapes() {
ShapeManager shapeManager;
QVector<const btCollisionShape*> shapes;
int numSizes = 100;
float startSize = 1.0f;
float endSize = 99.0f;
float deltaSize = (endSize - startSize) / (float)numSizes;
ShapeInfo info;
for (int i = 0; i < numSizes; ++i) {
// make a sphere
float s = startSize + (float)i * deltaSize;
glm::vec3 scale(s, 1.23f + s, s - 0.573f);
info.setBox(0.5f * scale);
const btCollisionShape* shape = shapeManager.getShape(info);
shapes.push_back(shape);
QCOMPARE(shape != nullptr, true);
// make a box
float radius = 0.5f * s;
info.setSphere(radius);
shape = shapeManager.getShape(info);
shapes.push_back(shape);
QCOMPARE(shape != nullptr, true);
}
// verify shape count
int numShapes = shapeManager.getNumShapes();
QCOMPARE(numShapes, 2 * numSizes);
// release each shape by pointer
for (int i = 0; i < numShapes; ++i) {
const btCollisionShape* shape = shapes[i];
bool success = shapeManager.releaseShape(shape);
QCOMPARE(success, true);
}
// verify zero references
for (int i = 0; i < numShapes; ++i) {
const btCollisionShape* shape = shapes[i];
int numReferences = shapeManager.getNumReferences(shape);
QCOMPARE(numReferences, 0);
}
}
void ShapeManagerTests::addBoxShape() {
ShapeInfo info;
glm::vec3 halfExtents(1.23f, 4.56f, 7.89f);
info.setBox(halfExtents);
ShapeManager shapeManager;
const btCollisionShape* shape = shapeManager.getShape(info);
ShapeInfo otherInfo = info;
const btCollisionShape* otherShape = shapeManager.getShape(otherInfo);
QCOMPARE(shape, otherShape);
}
void ShapeManagerTests::addSphereShape() {
ShapeInfo info;
float radius = 1.23f;
info.setSphere(radius);
ShapeManager shapeManager;
const btCollisionShape* shape = shapeManager.getShape(info);
ShapeInfo otherInfo = info;
const btCollisionShape* otherShape = shapeManager.getShape(otherInfo);
QCOMPARE(shape, otherShape);
}
void ShapeManagerTests::addCylinderShape() {
/* TODO: reimplement Cylinder shape
ShapeInfo info;
float radius = 1.23f;
float height = 4.56f;
info.setCylinder(radius, height);
ShapeManager shapeManager;
const btCollisionShape* shape = shapeManager.getShape(info);
ShapeInfo otherInfo = info;
const btCollisionShape* otherShape = shapeManager.getShape(otherInfo);
QCOMPARE(shape, otherShape);
*/
}
void ShapeManagerTests::addCapsuleShape() {
/* TODO: reimplement Capsule shape
ShapeInfo info;
float radius = 1.23f;
float height = 4.56f;
info.setCapsule(radius, height);
ShapeManager shapeManager;
const btCollisionShape* shape = shapeManager.getShape(info);
ShapeInfo otherInfo = info;
const btCollisionShape* otherShape = shapeManager.getShape(otherInfo);
QCOMPARE(shape, otherShape);
*/
}
void ShapeManagerTests::addCompoundShape() {
// initialize some points for generating tetrahedral convex hulls
QVector<glm::vec3> tetrahedron;
tetrahedron.push_back(glm::vec3(1.0f, 1.0f, 1.0f));
tetrahedron.push_back(glm::vec3(1.0f, -1.0f, -1.0f));
tetrahedron.push_back(glm::vec3(-1.0f, 1.0f, -1.0f));
tetrahedron.push_back(glm::vec3(-1.0f, -1.0f, 1.0f));
int numHullPoints = tetrahedron.size();
// compute the points of the hulls
ShapeInfo::PointCollection pointCollection;
int numHulls = 5;
glm::vec3 offsetNormal(1.0f, 0.0f, 0.0f);
Extents extents;
for (int i = 0; i < numHulls; ++i) {
glm::vec3 offset = (float)(i - numHulls/2) * offsetNormal;
ShapeInfo::PointList pointList;
float radius = (float)(i + 1);
for (int j = 0; j < numHullPoints; ++j) {
glm::vec3 point = radius * tetrahedron[j] + offset;
pointList.push_back(point);
extents.addPoint(point);
}
pointCollection.push_back(pointList);
}
// create the ShapeInfo
ShapeInfo info;
glm::vec3 halfExtents = 0.5f * (extents.maximum - extents.minimum);
info.setParams(SHAPE_TYPE_COMPOUND, halfExtents);
info.setPointCollection(pointCollection);
// create the shape
ShapeManager shapeManager;
const btCollisionShape* shape = shapeManager.getShape(info);
QVERIFY(shape != nullptr);
// verify the shape is correct type
QCOMPARE(shape->getShapeType(), (int)COMPOUND_SHAPE_PROXYTYPE);
// verify the shape has correct number of children
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
QCOMPARE(compoundShape->getNumChildShapes(), numHulls);
// verify manager has only one shape
QCOMPARE(shapeManager.getNumShapes(), 1);
QCOMPARE(shapeManager.getNumReferences(info), 1);
// release the shape
shapeManager.releaseShape(shape);
QCOMPARE(shapeManager.getNumShapes(), 1);
QCOMPARE(shapeManager.getNumReferences(info), 0);
// collect garbage
shapeManager.collectGarbage();
QCOMPARE(shapeManager.getNumShapes(), 0);
QCOMPARE(shapeManager.getNumReferences(info), 0);
}