mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 17:53:32 +02:00
Merge pull request #2984 from ZappoMan/octreeWireformatImprovements
Octree wireformat improvements checkpoint
This commit is contained in:
commit
3cc67f5229
7 changed files with 943 additions and 2 deletions
|
@ -50,11 +50,16 @@ ModelTreeElement* ModelTreeElement::addChildAtIndex(int index) {
|
|||
}
|
||||
|
||||
|
||||
// TODO: This will attempt to store as many models as will fit in the packetData, if an individual model won't
|
||||
// fit, but some models did fit, then the element outputs what can fit. Once the general Octree::encodeXXX()
|
||||
// process supports partial encoding of an octree element, this will need to be updated to handle spanning its
|
||||
// contents across multiple packets.
|
||||
bool ModelTreeElement::appendElementData(OctreePacketData* packetData, EncodeBitstreamParams& params) const {
|
||||
bool success = true; // assume the best...
|
||||
|
||||
// write our models out... first determine which of the models are in view based on our params
|
||||
uint16_t numberOfModels = 0;
|
||||
uint16_t actualNumberOfModels = 0;
|
||||
QVector<uint16_t> indexesOfModelsToInclude;
|
||||
|
||||
for (uint16_t i = 0; i < _modelItems->size(); i++) {
|
||||
|
@ -72,17 +77,33 @@ bool ModelTreeElement::appendElementData(OctreePacketData* packetData, EncodeBit
|
|||
}
|
||||
}
|
||||
|
||||
int numberOfModelsOffset = packetData->getUncompressedByteOffset();
|
||||
success = packetData->appendValue(numberOfModels);
|
||||
|
||||
if (success) {
|
||||
foreach (uint16_t i, indexesOfModelsToInclude) {
|
||||
const ModelItem& model = (*_modelItems)[i];
|
||||
|
||||
LevelDetails modelLevel = packetData->startLevel();
|
||||
|
||||
success = model.appendModelData(packetData);
|
||||
|
||||
if (success) {
|
||||
packetData->endLevel(modelLevel);
|
||||
actualNumberOfModels++;
|
||||
}
|
||||
if (!success) {
|
||||
packetData->discardLevel(modelLevel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
success = packetData->updatePriorBytes(numberOfModelsOffset,
|
||||
(const unsigned char*)&actualNumberOfModels, sizeof(actualNumberOfModels));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -433,6 +454,7 @@ int ModelTreeElement::readElementDataFromBuffer(const unsigned char* data, int b
|
|||
if (bytesLeftToRead >= (int)sizeof(numberOfModels)) {
|
||||
// read our models in....
|
||||
numberOfModels = *(uint16_t*)dataAt;
|
||||
|
||||
dataAt += sizeof(numberOfModels);
|
||||
bytesLeftToRead -= (int)sizeof(numberOfModels);
|
||||
bytesRead += sizeof(numberOfModels);
|
||||
|
|
|
@ -602,7 +602,6 @@ public:
|
|||
|
||||
bool findRayIntersectionOp(OctreeElement* element, void* extraData) {
|
||||
RayArgs* args = static_cast<RayArgs*>(extraData);
|
||||
|
||||
bool keepSearching = true;
|
||||
if (element->findRayIntersection(args->origin, args->direction, keepSearching,
|
||||
args->element, args->distance, args->face, args->intersectedObject)) {
|
||||
|
@ -1336,14 +1335,23 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
|
|||
}
|
||||
}
|
||||
|
||||
// write the color data...
|
||||
// write the child element data...
|
||||
if (continueThisLevel && params.includeColor) {
|
||||
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
|
||||
if (oneAtBit(childrenColoredBits, i)) {
|
||||
OctreeElement* childElement = element->getChildAtIndex(i);
|
||||
if (childElement) {
|
||||
|
||||
int bytesBeforeChild = packetData->getUncompressedSize();
|
||||
|
||||
// TODO: we want to support the ability for a childElement to "partially" write it's data.
|
||||
// for example, consider the case of the model server where the entire contents of the
|
||||
// element may be larger than can fit in a single MTU/packetData. In this case, we want
|
||||
// to allow the appendElementData() to respond that it produced partial data, which should be
|
||||
// written, but that the childElement needs to be reprocessed in an additional pass or passes
|
||||
// to be completed. In the case that an element was partially written, we need to
|
||||
continueThisLevel = childElement->appendElementData(packetData, params);
|
||||
|
||||
int bytesAfterChild = packetData->getUncompressedSize();
|
||||
|
||||
if (!continueThisLevel) {
|
||||
|
|
418
libraries/shared/src/PropertyFlags.h
Normal file
418
libraries/shared/src/PropertyFlags.h
Normal file
|
@ -0,0 +1,418 @@
|
|||
//
|
||||
// PropertyFlags.h
|
||||
// libraries/shared/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 6/3/14.
|
||||
// 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
|
||||
//
|
||||
//
|
||||
// TODO:
|
||||
// * consider adding iterator to enumerate the properties that have been set?
|
||||
|
||||
#ifndef hifi_PropertyFlags_h
|
||||
#define hifi_PropertyFlags_h
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
|
||||
#include <QBitArray>
|
||||
#include <QByteArray>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
|
||||
template<typename Enum>class PropertyFlags {
|
||||
public:
|
||||
typedef Enum enum_type;
|
||||
inline PropertyFlags() :
|
||||
_maxFlag(INT_MIN), _minFlag(INT_MAX), _trailingFlipped(false) { };
|
||||
inline PropertyFlags(const PropertyFlags& other) :
|
||||
_flags(other._flags), _maxFlag(other._maxFlag), _minFlag(other._minFlag),
|
||||
_trailingFlipped(other._trailingFlipped) {}
|
||||
inline PropertyFlags(Enum flag) :
|
||||
_maxFlag(INT_MIN), _minFlag(INT_MAX), _trailingFlipped(false) { setHasProperty(flag); }
|
||||
|
||||
void clear() { _flags.clear(); _maxFlag = INT_MIN; _minFlag = INT_MAX; _trailingFlipped = false; }
|
||||
|
||||
Enum firstFlag() const { return (Enum)_minFlag; }
|
||||
Enum lastFlag() const { return (Enum)_maxFlag; }
|
||||
|
||||
void setHasProperty(Enum flag, bool value = true);
|
||||
bool getHasProperty(Enum flag);
|
||||
QByteArray encode();
|
||||
void decode(const QByteArray& fromEncoded);
|
||||
|
||||
|
||||
bool operator==(const PropertyFlags& other) const { return _flags == other._flags; }
|
||||
bool operator!=(const PropertyFlags& other) const { return _flags != other._flags; }
|
||||
bool operator!() const { return _flags.size() == 0; }
|
||||
|
||||
PropertyFlags& operator=(const PropertyFlags& other);
|
||||
|
||||
PropertyFlags& operator|=(PropertyFlags other);
|
||||
PropertyFlags& operator|=(Enum flag);
|
||||
|
||||
PropertyFlags& operator&=(PropertyFlags other);
|
||||
PropertyFlags& operator&=(Enum flag);
|
||||
|
||||
PropertyFlags& operator+=(PropertyFlags other);
|
||||
PropertyFlags& operator+=(Enum flag);
|
||||
|
||||
PropertyFlags& operator-=(PropertyFlags other);
|
||||
PropertyFlags& operator-=(Enum flag);
|
||||
|
||||
PropertyFlags& operator<<=(PropertyFlags other);
|
||||
PropertyFlags& operator<<=(Enum flag);
|
||||
|
||||
PropertyFlags operator|(PropertyFlags other) const;
|
||||
PropertyFlags operator|(Enum flag) const;
|
||||
|
||||
PropertyFlags operator&(PropertyFlags other) const;
|
||||
PropertyFlags operator&(Enum flag) const;
|
||||
|
||||
PropertyFlags operator+(PropertyFlags other) const;
|
||||
PropertyFlags operator+(Enum flag) const;
|
||||
|
||||
PropertyFlags operator-(PropertyFlags other) const;
|
||||
PropertyFlags operator-(Enum flag) const;
|
||||
|
||||
PropertyFlags operator<<(PropertyFlags other) const;
|
||||
PropertyFlags operator<<(Enum flag) const;
|
||||
|
||||
// NOTE: due to the nature of the compact storage of these property flags, and the fact that the upper bound of the
|
||||
// enum is not know, these operators will only perform their bitwise operations on the set of properties that have
|
||||
// been previously set
|
||||
PropertyFlags& operator^=(PropertyFlags other);
|
||||
PropertyFlags& operator^=(Enum flag);
|
||||
PropertyFlags operator^(PropertyFlags other) const;
|
||||
PropertyFlags operator^(Enum flag) const;
|
||||
PropertyFlags operator~() const;
|
||||
|
||||
void debugDumpBits();
|
||||
|
||||
|
||||
private:
|
||||
void shinkIfNeeded();
|
||||
|
||||
QBitArray _flags;
|
||||
int _maxFlag;
|
||||
int _minFlag;
|
||||
bool _trailingFlipped; /// are the trailing properties flipping in their state (e.g. assumed true, instead of false)
|
||||
};
|
||||
|
||||
template<typename Enum> PropertyFlags<Enum>& operator<<(PropertyFlags<Enum>& out, const PropertyFlags<Enum>& other) {
|
||||
return out <<= other;
|
||||
}
|
||||
|
||||
template<typename Enum> PropertyFlags<Enum>& operator<<(PropertyFlags<Enum>& out, Enum flag) {
|
||||
return out <<= flag;
|
||||
}
|
||||
|
||||
|
||||
template<typename Enum> inline void PropertyFlags<Enum>::setHasProperty(Enum flag, bool value) {
|
||||
// keep track of our min flag
|
||||
if (flag < _minFlag) {
|
||||
if (value) {
|
||||
_minFlag = flag;
|
||||
}
|
||||
}
|
||||
if (flag > _maxFlag) {
|
||||
if (value) {
|
||||
_maxFlag = flag;
|
||||
_flags.resize(_maxFlag + 1);
|
||||
} else {
|
||||
return; // bail early, we're setting a flag outside of our current _maxFlag to false, which is already the default
|
||||
}
|
||||
}
|
||||
_flags.setBit(flag, value);
|
||||
|
||||
if (flag == _maxFlag && !value) {
|
||||
shinkIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Enum> inline bool PropertyFlags<Enum>::getHasProperty(Enum flag) {
|
||||
if (flag > _maxFlag) {
|
||||
return _trailingFlipped; // usually false
|
||||
}
|
||||
return _flags.testBit(flag);
|
||||
}
|
||||
|
||||
const int BITS_PER_BYTE = 8;
|
||||
|
||||
template<typename Enum> inline QByteArray PropertyFlags<Enum>::encode() {
|
||||
QByteArray output;
|
||||
|
||||
if (_maxFlag < _minFlag) {
|
||||
output.fill(0, 1);
|
||||
return output; // no flags... nothing to encode
|
||||
}
|
||||
|
||||
// we should size the array to the correct size.
|
||||
int lengthInBytes = (_maxFlag / (BITS_PER_BYTE - 1)) + 1;
|
||||
|
||||
output.fill(0, lengthInBytes);
|
||||
|
||||
// next pack the number of header bits in, the first N-1 to be set to 1, the last to be set to 0
|
||||
for(int i = 0; i < lengthInBytes; i++) {
|
||||
int outputIndex = i;
|
||||
int bitValue = (i < (lengthInBytes - 1) ? 1 : 0);
|
||||
char original = output.at(outputIndex / BITS_PER_BYTE);
|
||||
int shiftBy = BITS_PER_BYTE - ((outputIndex % BITS_PER_BYTE) + 1);
|
||||
char thisBit = ( bitValue << shiftBy);
|
||||
output[i / BITS_PER_BYTE] = (original | thisBit);
|
||||
}
|
||||
|
||||
// finally pack the the actual bits from the bit array
|
||||
for(int i = lengthInBytes; i < (lengthInBytes + _maxFlag + 1); i++) {
|
||||
int flagIndex = i - lengthInBytes;
|
||||
int outputIndex = i;
|
||||
int bitValue = ( _flags[flagIndex] ? 1 : 0);
|
||||
char original = output.at(outputIndex / BITS_PER_BYTE);
|
||||
int shiftBy = BITS_PER_BYTE - ((outputIndex % BITS_PER_BYTE) + 1);
|
||||
char thisBit = ( bitValue << shiftBy);
|
||||
output[i / BITS_PER_BYTE] = (original | thisBit);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
template<typename Enum> inline void PropertyFlags<Enum>::decode(const QByteArray& fromEncodedBytes) {
|
||||
|
||||
clear(); // we are cleared out!
|
||||
|
||||
// first convert the ByteArray into a BitArray...
|
||||
QBitArray encodedBits;
|
||||
int bitCount = BITS_PER_BYTE * fromEncodedBytes.count();
|
||||
encodedBits.resize(bitCount);
|
||||
|
||||
for(int byte = 0; byte < fromEncodedBytes.count(); byte++) {
|
||||
char originalByte = fromEncodedBytes.at(byte);
|
||||
for(int bit = 0; bit < BITS_PER_BYTE; bit++) {
|
||||
int shiftBy = BITS_PER_BYTE - (bit + 1);
|
||||
char maskBit = ( 1 << shiftBy);
|
||||
bool bitValue = originalByte & maskBit;
|
||||
encodedBits.setBit(byte * BITS_PER_BYTE + bit, bitValue);
|
||||
}
|
||||
}
|
||||
|
||||
// next, read the leading bits to determine the correct number of bytes to decode (may not match the QByteArray)
|
||||
int encodedByteCount = 0;
|
||||
int bitAt;
|
||||
for (bitAt = 0; bitAt < bitCount; bitAt++) {
|
||||
if (encodedBits.at(bitAt)) {
|
||||
encodedByteCount++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
encodedByteCount++; // always at least one byte
|
||||
int expectedBitCount = encodedByteCount * BITS_PER_BYTE;
|
||||
|
||||
// Now, keep reading...
|
||||
int flagsStartAt = bitAt + 1;
|
||||
for (bitAt = flagsStartAt; bitAt < expectedBitCount; bitAt++) {
|
||||
if (encodedBits.at(bitAt)) {
|
||||
setHasProperty((Enum)(bitAt - flagsStartAt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Enum> inline void PropertyFlags<Enum>::debugDumpBits() {
|
||||
qDebug() << "_minFlag=" << _minFlag;
|
||||
qDebug() << "_maxFlag=" << _maxFlag;
|
||||
qDebug() << "_trailingFlipped=" << _trailingFlipped;
|
||||
for(int i = 0; i < _flags.size(); i++) {
|
||||
qDebug() << "bit[" << i << "]=" << _flags.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator=(const PropertyFlags& other) {
|
||||
_flags = other._flags;
|
||||
_maxFlag = other._maxFlag;
|
||||
_minFlag = other._minFlag;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator|=(PropertyFlags other) {
|
||||
_flags |= other._flags;
|
||||
_maxFlag = std::max(_maxFlag, other._maxFlag);
|
||||
_minFlag = std::min(_minFlag, other._minFlag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator|=(Enum flag) {
|
||||
PropertyFlags other(flag);
|
||||
_flags |= other._flags;
|
||||
_maxFlag = std::max(_maxFlag, other._maxFlag);
|
||||
_minFlag = std::min(_minFlag, other._minFlag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator&=(PropertyFlags other) {
|
||||
_flags &= other._flags;
|
||||
shinkIfNeeded();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator&=(Enum flag) {
|
||||
PropertyFlags other(flag);
|
||||
_flags &= other._flags;
|
||||
shinkIfNeeded();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator^=(PropertyFlags other) {
|
||||
_flags ^= other._flags;
|
||||
shinkIfNeeded();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator^=(Enum flag) {
|
||||
PropertyFlags other(flag);
|
||||
_flags ^= other._flags;
|
||||
shinkIfNeeded();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator+=(PropertyFlags other) {
|
||||
for(int flag = (int)other.firstFlag(); flag <= (int)other.lastFlag(); flag++) {
|
||||
if (other.getHasProperty((Enum)flag)) {
|
||||
setHasProperty((Enum)flag, true);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator+=(Enum flag) {
|
||||
setHasProperty(flag, true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator-=(PropertyFlags other) {
|
||||
for(int flag = (int)other.firstFlag(); flag <= (int)other.lastFlag(); flag++) {
|
||||
if (other.getHasProperty((Enum)flag)) {
|
||||
setHasProperty((Enum)flag, false);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator-=(Enum flag) {
|
||||
setHasProperty(flag, false);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator<<=(PropertyFlags other) {
|
||||
for(int flag = (int)other.firstFlag(); flag <= (int)other.lastFlag(); flag++) {
|
||||
if (other.getHasProperty((Enum)flag)) {
|
||||
setHasProperty((Enum)flag, true);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum>& PropertyFlags<Enum>::operator<<=(Enum flag) {
|
||||
setHasProperty(flag, true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator|(PropertyFlags other) const {
|
||||
PropertyFlags result(*this);
|
||||
result |= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator|(Enum flag) const {
|
||||
PropertyFlags result(*this);
|
||||
PropertyFlags other(flag);
|
||||
result |= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator&(PropertyFlags other) const {
|
||||
PropertyFlags result(*this);
|
||||
result &= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator&(Enum flag) const {
|
||||
PropertyFlags result(*this);
|
||||
PropertyFlags other(flag);
|
||||
result &= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator^(PropertyFlags other) const {
|
||||
PropertyFlags result(*this);
|
||||
result ^= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator^(Enum flag) const {
|
||||
PropertyFlags result(*this);
|
||||
PropertyFlags other(flag);
|
||||
result ^= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator+(PropertyFlags other) const {
|
||||
PropertyFlags result(*this);
|
||||
result += other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator+(Enum flag) const {
|
||||
PropertyFlags result(*this);
|
||||
result.setHasProperty(flag, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator-(PropertyFlags other) const {
|
||||
PropertyFlags result(*this);
|
||||
result -= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator-(Enum flag) const {
|
||||
PropertyFlags result(*this);
|
||||
result.setHasProperty(flag, false);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator<<(PropertyFlags other) const {
|
||||
PropertyFlags result(*this);
|
||||
result <<= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator<<(Enum flag) const {
|
||||
PropertyFlags result(*this);
|
||||
result.setHasProperty(flag, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline PropertyFlags<Enum> PropertyFlags<Enum>::operator~() const {
|
||||
PropertyFlags result(*this);
|
||||
result._flags = ~_flags;
|
||||
result._trailingFlipped = !_trailingFlipped;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Enum> inline void PropertyFlags<Enum>::shinkIfNeeded() {
|
||||
bool maxFlagWas = _maxFlag;
|
||||
while (_maxFlag >= 0) {
|
||||
if (_flags.testBit(_maxFlag)) {
|
||||
break;
|
||||
}
|
||||
_maxFlag--;
|
||||
}
|
||||
if (maxFlagWas != _maxFlag) {
|
||||
_flags.resize(_maxFlag + 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // hifi_PropertyFlags_h
|
||||
|
39
tests/octree/CMakeLists.txt
Normal file
39
tests/octree/CMakeLists.txt
Normal file
|
@ -0,0 +1,39 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
if (WIN32)
|
||||
cmake_policy (SET CMP0020 NEW)
|
||||
endif (WIN32)
|
||||
|
||||
set(TARGET_NAME octree-tests)
|
||||
|
||||
set(ROOT_DIR ../..)
|
||||
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
|
||||
|
||||
# setup for find modules
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/")
|
||||
|
||||
#find_package(Qt5Network REQUIRED)
|
||||
#find_package(Qt5Script REQUIRED)
|
||||
#find_package(Qt5Widgets REQUIRED)
|
||||
|
||||
include(${MACRO_DIR}/SetupHifiProject.cmake)
|
||||
setup_hifi_project(${TARGET_NAME} TRUE)
|
||||
|
||||
include(${MACRO_DIR}/AutoMTC.cmake)
|
||||
auto_mtc(${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
#qt5_use_modules(${TARGET_NAME} Network Script Widgets)
|
||||
|
||||
#include glm
|
||||
include(${MACRO_DIR}/IncludeGLM.cmake)
|
||||
include_glm(${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
# link in the shared libraries
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
||||
link_hifi_library(octree ${TARGET_NAME} ${ROOT_DIR})
|
||||
|
||||
IF (WIN32)
|
||||
#target_link_libraries(${TARGET_NAME} Winmm Ws2_32)
|
||||
ENDIF(WIN32)
|
||||
|
416
tests/octree/src/OctreeTests.cpp
Normal file
416
tests/octree/src/OctreeTests.cpp
Normal file
|
@ -0,0 +1,416 @@
|
|||
//
|
||||
// OctreeTests.h
|
||||
// tests/physics/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 06/04/2014.
|
||||
// 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 <QDebug>
|
||||
|
||||
#include <PropertyFlags.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "OctreeTests.h"
|
||||
|
||||
enum ModelPropertyList {
|
||||
PROP_PAGED_PROPERTY,
|
||||
PROP_CUSTOM_PROPERTIES_INCLUDED,
|
||||
PROP_VISIBLE,
|
||||
PROP_POSITION,
|
||||
PROP_RADIUS,
|
||||
PROP_MODEL_URL,
|
||||
PROP_ROTATION,
|
||||
PROP_COLOR,
|
||||
PROP_SCRIPT,
|
||||
PROP_ANIMATION_URL,
|
||||
PROP_ANIMATION_FPS,
|
||||
PROP_ANIMATION_FRAME_INDEX,
|
||||
PROP_ANIMATION_PLAYING,
|
||||
PROP_SHOULD_BE_DELETED
|
||||
};
|
||||
|
||||
typedef PropertyFlags<ModelPropertyList> ModelPropertyFlags;
|
||||
|
||||
enum ParticlePropertyList {
|
||||
PARTICLE_PROP_PAGED_PROPERTY,
|
||||
PARTICLE_PROP_CUSTOM_PROPERTIES_INCLUDED,
|
||||
PARTICLE_PROP_VISIBLE,
|
||||
PARTICLE_PROP_POSITION,
|
||||
PARTICLE_PROP_RADIUS,
|
||||
PARTICLE_PROP_MODEL_URL,
|
||||
PARTICLE_PROP_ROTATION,
|
||||
PARTICLE_PROP_COLOR,
|
||||
PARTICLE_PROP_SCRIPT,
|
||||
PARTICLE_PROP_ANIMATION_URL,
|
||||
PARTICLE_PROP_ANIMATION_FPS,
|
||||
PARTICLE_PROP_ANIMATION_FRAME_INDEX,
|
||||
PARTICLE_PROP_ANIMATION_PLAYING,
|
||||
PARTICLE_PROP_SHOULD_BE_DELETED,
|
||||
PARTICLE_PROP_VELOCITY,
|
||||
PARTICLE_PROP_GRAVITY,
|
||||
PARTICLE_PROP_DAMPING,
|
||||
PARTICLE_PROP_MASS,
|
||||
PARTICLE_PROP_LIFETIME,
|
||||
PARTICLE_PROP_PAUSE_SIMULATION,
|
||||
};
|
||||
|
||||
typedef PropertyFlags<ParticlePropertyList> ParticlePropertyFlags;
|
||||
|
||||
|
||||
void OctreeTests::propertyFlagsTests() {
|
||||
qDebug() << "******************************************************************************************";
|
||||
qDebug() << "OctreeTests::propertyFlagsTests()";
|
||||
|
||||
{
|
||||
qDebug() << "Test 1: ModelProperties: using setHasProperty()";
|
||||
ModelPropertyFlags props;
|
||||
props.setHasProperty(PROP_VISIBLE);
|
||||
props.setHasProperty(PROP_POSITION);
|
||||
props.setHasProperty(PROP_RADIUS);
|
||||
props.setHasProperty(PROP_MODEL_URL);
|
||||
props.setHasProperty(PROP_ROTATION);
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 2: ParticlePropertyFlags: using setHasProperty()";
|
||||
ParticlePropertyFlags props2;
|
||||
props2.setHasProperty(PARTICLE_PROP_VISIBLE);
|
||||
props2.setHasProperty(PARTICLE_PROP_ANIMATION_URL);
|
||||
props2.setHasProperty(PARTICLE_PROP_ANIMATION_FPS);
|
||||
props2.setHasProperty(PARTICLE_PROP_ANIMATION_FRAME_INDEX);
|
||||
props2.setHasProperty(PARTICLE_PROP_ANIMATION_PLAYING);
|
||||
props2.setHasProperty(PARTICLE_PROP_PAUSE_SIMULATION);
|
||||
|
||||
QByteArray encoded = props2.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
|
||||
qDebug() << "Test 2b: remove flag with setHasProperty() PARTICLE_PROP_PAUSE_SIMULATION";
|
||||
|
||||
props2.setHasProperty(PARTICLE_PROP_PAUSE_SIMULATION, false);
|
||||
|
||||
encoded = props2.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 3: ParticlePropertyFlags: using | operator";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE)
|
||||
| ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
|
||||
| ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
|
||||
| ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
|
||||
| ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING)
|
||||
| ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
|
||||
qDebug() << "Test 3b: remove flag with -= PARTICLE_PROP_PAUSE_SIMULATION";
|
||||
props -= PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 3c: ParticlePropertyFlags: using |= operator";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
props |= PARTICLE_PROP_VISIBLE;
|
||||
props |= PARTICLE_PROP_ANIMATION_URL;
|
||||
props |= PARTICLE_PROP_ANIMATION_FPS;
|
||||
props |= PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
props |= PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
props |= PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 4: ParticlePropertyFlags: using + operator";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE)
|
||||
+ ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
|
||||
+ ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
|
||||
+ ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
|
||||
+ ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING)
|
||||
+ ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 4b: ParticlePropertyFlags: using += operator";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
props += PARTICLE_PROP_VISIBLE;
|
||||
props += PARTICLE_PROP_ANIMATION_URL;
|
||||
props += PARTICLE_PROP_ANIMATION_FPS;
|
||||
props += PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
props += PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
props += PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 5: ParticlePropertyFlags: using = ... << operator";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE)
|
||||
<< ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
|
||||
<< ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
|
||||
<< ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
|
||||
<< ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING)
|
||||
<< ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 5b: ParticlePropertyFlags: using <<= operator";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
props <<= PARTICLE_PROP_VISIBLE;
|
||||
props <<= PARTICLE_PROP_ANIMATION_URL;
|
||||
props <<= PARTICLE_PROP_ANIMATION_FPS;
|
||||
props <<= PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
props <<= PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
props <<= PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 5c: ParticlePropertyFlags: using << enum operator";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
props << PARTICLE_PROP_VISIBLE;
|
||||
props << PARTICLE_PROP_ANIMATION_URL;
|
||||
props << PARTICLE_PROP_ANIMATION_FPS;
|
||||
props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
props << PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
props << PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 5d: ParticlePropertyFlags: using << flags operator ";
|
||||
ParticlePropertyFlags props;
|
||||
ParticlePropertyFlags props2;
|
||||
|
||||
props << PARTICLE_PROP_VISIBLE;
|
||||
props << PARTICLE_PROP_ANIMATION_URL;
|
||||
props << PARTICLE_PROP_ANIMATION_FPS;
|
||||
|
||||
props2 << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
props2 << PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
props2 << PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
props << props2;
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 6: ParticlePropertyFlags comparison";
|
||||
ParticlePropertyFlags propsA;
|
||||
|
||||
qDebug() << "!propsA:" << (!propsA) << "{ expect true }";
|
||||
|
||||
propsA << PARTICLE_PROP_VISIBLE;
|
||||
propsA << PARTICLE_PROP_ANIMATION_URL;
|
||||
propsA << PARTICLE_PROP_ANIMATION_FPS;
|
||||
propsA << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
propsA << PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
propsA << PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
qDebug() << "!propsA:" << (!propsA) << "{ expect false }";
|
||||
|
||||
ParticlePropertyFlags propsB;
|
||||
qDebug() << "!propsB:" << (!propsB) << "{ expect true }";
|
||||
|
||||
|
||||
propsB << PARTICLE_PROP_VISIBLE;
|
||||
propsB << PARTICLE_PROP_ANIMATION_URL;
|
||||
propsB << PARTICLE_PROP_ANIMATION_FPS;
|
||||
propsB << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
propsB << PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
propsB << PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
qDebug() << "!propsB:" << (!propsB) << "{ expect false }";
|
||||
|
||||
qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect true }";
|
||||
qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect false }";
|
||||
|
||||
|
||||
qDebug() << "AFTER propsB -= PARTICLE_PROP_PAUSE_SIMULATION...";
|
||||
propsB -= PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect false }";
|
||||
qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect true }";
|
||||
|
||||
qDebug() << "AFTER propsB = propsA...";
|
||||
propsB = propsA;
|
||||
|
||||
qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect true }";
|
||||
qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect false }";
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 7: ParticlePropertyFlags testing individual properties";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
qDebug() << "ParticlePropertyFlags props;";
|
||||
QByteArray encoded = props.encode();
|
||||
qDebug() << "props... encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
|
||||
qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE))
|
||||
<< "{ expect false }";
|
||||
|
||||
qDebug() << "props << PARTICLE_PROP_VISIBLE;";
|
||||
props << PARTICLE_PROP_VISIBLE;
|
||||
|
||||
encoded = props.encode();
|
||||
qDebug() << "props... encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE))
|
||||
<< "{ expect true }";
|
||||
|
||||
qDebug() << "props << PARTICLE_PROP_ANIMATION_URL;";
|
||||
props << PARTICLE_PROP_ANIMATION_URL;
|
||||
|
||||
encoded = props.encode();
|
||||
qDebug() << "props... encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE))
|
||||
<< "{ expect true }";
|
||||
|
||||
qDebug() << "props << ... more ...";
|
||||
props << PARTICLE_PROP_ANIMATION_FPS;
|
||||
props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
props << PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
props << PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
encoded = props.encode();
|
||||
qDebug() << "props... encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE))
|
||||
<< "{ expect true }";
|
||||
|
||||
qDebug() << "ParticlePropertyFlags propsB = props & PARTICLE_PROP_VISIBLE;";
|
||||
ParticlePropertyFlags propsB = props & PARTICLE_PROP_VISIBLE;
|
||||
|
||||
qDebug() << "propsB.getHasProperty(PARTICLE_PROP_VISIBLE)" << (propsB.getHasProperty(PARTICLE_PROP_VISIBLE))
|
||||
<< "{ expect true }";
|
||||
|
||||
encoded = propsB.encode();
|
||||
qDebug() << "propsB... encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
|
||||
qDebug() << "ParticlePropertyFlags propsC = ~propsB;";
|
||||
ParticlePropertyFlags propsC = ~propsB;
|
||||
|
||||
qDebug() << "propsC.getHasProperty(PARTICLE_PROP_VISIBLE)" << (propsC.getHasProperty(PARTICLE_PROP_VISIBLE))
|
||||
<< "{ expect false }";
|
||||
|
||||
encoded = propsC.encode();
|
||||
qDebug() << "propsC... encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
}
|
||||
|
||||
{
|
||||
qDebug() << "Test 8: ParticlePropertyFlags: decode tests";
|
||||
ParticlePropertyFlags props;
|
||||
|
||||
props << PARTICLE_PROP_VISIBLE;
|
||||
props << PARTICLE_PROP_ANIMATION_URL;
|
||||
props << PARTICLE_PROP_ANIMATION_FPS;
|
||||
props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
|
||||
props << PARTICLE_PROP_ANIMATION_PLAYING;
|
||||
props << PARTICLE_PROP_PAUSE_SIMULATION;
|
||||
|
||||
QByteArray encoded = props.encode();
|
||||
qDebug() << "encoded=";
|
||||
outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
|
||||
|
||||
qDebug() << "encoded.size()=" << encoded.size();
|
||||
|
||||
ParticlePropertyFlags propsDecoded;
|
||||
propsDecoded.decode(encoded);
|
||||
|
||||
qDebug() << "propsDecoded == props:" << (propsDecoded == props) << "{ expect true }";
|
||||
|
||||
QByteArray encodedAfterDecoded = propsDecoded.encode();
|
||||
|
||||
qDebug() << "encodedAfterDecoded=";
|
||||
outputBufferBits((const unsigned char*)encodedAfterDecoded.constData(), encodedAfterDecoded.size());
|
||||
|
||||
qDebug() << "fill encoded byte array with extra garbage (as if it was bitstream with more content)";
|
||||
QByteArray extraContent;
|
||||
extraContent.fill(0xba, 10);
|
||||
encoded.append(extraContent);
|
||||
qDebug() << "encoded.size()=" << encoded.size() << "includes extra garbage";
|
||||
|
||||
ParticlePropertyFlags propsDecodedExtra;
|
||||
propsDecodedExtra.decode(encoded);
|
||||
|
||||
qDebug() << "propsDecodedExtra == props:" << (propsDecodedExtra == props) << "{ expect true }";
|
||||
|
||||
QByteArray encodedAfterDecodedExtra = propsDecodedExtra.encode();
|
||||
|
||||
qDebug() << "encodedAfterDecodedExtra=";
|
||||
outputBufferBits((const unsigned char*)encodedAfterDecodedExtra.constData(), encodedAfterDecodedExtra.size());
|
||||
|
||||
}
|
||||
|
||||
qDebug() << "******************************************************************************************";
|
||||
}
|
||||
|
||||
void OctreeTests::runAllTests() {
|
||||
propertyFlagsTests();
|
||||
}
|
22
tests/octree/src/OctreeTests.h
Normal file
22
tests/octree/src/OctreeTests.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// OctreeTests.h
|
||||
// tests/physics/src
|
||||
//
|
||||
// Created by Brad Hefta-Gaub on 06/04/2014.
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_OctreeTests_h
|
||||
#define hifi_OctreeTests_h
|
||||
|
||||
namespace OctreeTests {
|
||||
|
||||
void propertyFlagsTests();
|
||||
|
||||
void runAllTests();
|
||||
}
|
||||
|
||||
#endif // hifi_OctreeTests_h
|
16
tests/octree/src/main.cpp
Normal file
16
tests/octree/src/main.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// main.cpp
|
||||
// tests/octree/src
|
||||
//
|
||||
// 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 "OctreeTests.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
OctreeTests::runAllTests();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue