renaming of AABox to AACube, introduction of actual AABox

This commit is contained in:
ZappoMan 2014-05-23 10:45:04 -07:00
parent 9188b9ac59
commit 39ed7f7b65
26 changed files with 384 additions and 257 deletions

View file

@ -2076,10 +2076,10 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inViewServers++;
@ -2142,10 +2142,10 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inView = true;
} else {

View file

@ -73,6 +73,42 @@ Model* ModelTreeRenderer::getModel(const ModelItem& modelItem) {
return model;
}
void calculateRotatedExtents(Extents& extents, const glm::quat& rotation) {
glm::vec3 bottomLeftNear(extents.minimum.x, extents.minimum.y, extents.minimum.z);
glm::vec3 bottomRightNear(extents.maximum.x, extents.minimum.y, extents.minimum.z);
glm::vec3 bottomLeftFar(extents.minimum.x, extents.minimum.y, extents.maximum.z);
glm::vec3 bottomRightFar(extents.maximum.x, extents.minimum.y, extents.maximum.z);
glm::vec3 topLeftNear(extents.minimum.x, extents.maximum.y, extents.minimum.z);
glm::vec3 topRightNear(extents.maximum.x, extents.maximum.y, extents.minimum.z);
glm::vec3 topLeftFar(extents.minimum.x, extents.maximum.y, extents.maximum.z);
glm::vec3 topRightFar(extents.maximum.x, extents.maximum.y, extents.maximum.z);
glm::vec3 bottomLeftNearRotated = rotation * bottomLeftNear;
glm::vec3 bottomRightNearRotated = rotation * bottomRightNear;
glm::vec3 bottomLeftFarRotated = rotation * bottomLeftFar;
glm::vec3 bottomRightFarRotated = rotation * bottomRightFar;
glm::vec3 topLeftNearRotated = rotation * topLeftNear;
glm::vec3 topRightNearRotated = rotation * topRightNear;
glm::vec3 topLeftFarRotated = rotation * topLeftFar;
glm::vec3 topRightFarRotated = rotation * topRightFar;
extents.minimum = glm::min(bottomLeftNearRotated,
glm::min(bottomRightNearRotated,
glm::min(bottomLeftFarRotated,
glm::min(bottomRightFarRotated,
glm::min(topLeftNearRotated,
glm::min(topRightNearRotated,
glm::min(topLeftFarRotated,topRightFarRotated)))))));
extents.maximum = glm::max(bottomLeftNearRotated,
glm::max(bottomRightNearRotated,
glm::max(bottomLeftFarRotated,
glm::max(bottomRightFarRotated,
glm::max(topLeftNearRotated,
glm::max(topRightNearRotated,
glm::max(topLeftFarRotated,topRightFarRotated)))))));
}
void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) {
args->_elementsTouched++;
// actually render it here...
@ -91,7 +127,7 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
if (!isShadowMode && displayElementProxy && numberOfModels > 0) {
glm::vec3 elementCenter = modelTreeElement->getAABox().calcCenter() * (float)TREE_SCALE;
glm::vec3 elementCenter = modelTreeElement->getAACube().calcCenter() * (float)TREE_SCALE;
float elementSize = modelTreeElement->getScale() * (float)TREE_SCALE;
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
@ -157,9 +193,9 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
for (uint16_t i = 0; i < numberOfModels; i++) {
ModelItem& modelItem = modelItems[i];
// render modelItem aspoints
AABox modelBox = modelItem.getAABox();
modelBox.scale(TREE_SCALE);
if (args->_viewFrustum->boxInFrustum(modelBox) != ViewFrustum::OUTSIDE) {
AACube modelCube = modelItem.getAACube();
modelCube.scale(TREE_SCALE);
if (args->_viewFrustum->cubeInFrustum(modelCube) != ViewFrustum::OUTSIDE) {
glm::vec3 position = modelItem.getPosition() * (float)TREE_SCALE;
float radius = modelItem.getRadius() * (float)TREE_SCALE;
float size = modelItem.getSize() * (float)TREE_SCALE;
@ -206,10 +242,45 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
model->render(alpha, modelRenderMode);
if (!isShadowMode && displayModelBounds) {
glColor3f(0.0f, 1.0f, 0.0f);
glm::vec3 unRotatedMinimum = model->getUnscaledMeshExtents().minimum;
glm::vec3 unRotatedMaximum = model->getUnscaledMeshExtents().maximum;
glm::vec3 unRotatedExtents = unRotatedMaximum - unRotatedMinimum;
float width = unRotatedExtents.x;
float height = unRotatedExtents.y;
float depth = unRotatedExtents.z;
Extents rotatedExtents = model->getUnscaledMeshExtents();
calculateRotatedExtents(rotatedExtents, rotation);
glm::vec3 rotatedSize = rotatedExtents.maximum - rotatedExtents.minimum;
const glm::vec3& modelScale = model->getScale();
glPushMatrix();
glTranslatef(position.x, position.y, position.z);
// draw the orignal bounding cube
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glutWireCube(size);
//glColor4f(1.0f, 1.0f, 0.0f, 0.5f);
//glutWireSphere(radius, 15, 15);
// draw the rotated bounding cube
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
glPushMatrix();
glScalef(rotatedSize.x * modelScale.x, rotatedSize.y * modelScale.y, rotatedSize.z * modelScale.z);
glutWireCube(1.0);
glPopMatrix();
// draw the model relative bounding box
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
glScalef(width * modelScale.x, height * modelScale.y, depth * modelScale.z);
glColor3f(0.0f, 1.0f, 0.0f);
glutWireCube(1.0);
glPopMatrix();
}

View file

@ -987,8 +987,9 @@ void Model::scaleToFit() {
// size is our "target size in world space"
// we need to set our model scale so that the extents of the mesh, fit in a cube that size...
glm::vec3 dimensions = modelMeshExtents.maximum - modelMeshExtents.minimum;
float maxDimension = glm::max(glm::max(dimensions.x, dimensions.y), dimensions.z);
float maxScale = _scaleToFitLargestDimension / maxDimension;
const float SQRT_THREE = 1.733; // sqrt(3)
float maxDimensionRotated = SQRT_THREE * glm::max(glm::max(dimensions.x, dimensions.y), dimensions.z);
float maxScale = _scaleToFitLargestDimension / maxDimensionRotated;
glm::vec3 scale(maxScale, maxScale, maxScale);
setScaleInternal(scale);
_scaledToFit = true;

View file

@ -81,7 +81,7 @@ void NodeBounds::draw() {
glm::vec3 location(rootDetails.x, rootDetails.y, rootDetails.z);
location *= (float)TREE_SCALE;
AABox serverBounds(location, rootDetails.s * TREE_SCALE);
AACube serverBounds(location, rootDetails.s * TREE_SCALE);
glm::vec3 center = serverBounds.getVertex(BOTTOM_RIGHT_NEAR)
+ ((serverBounds.getVertex(TOP_LEFT_FAR) - serverBounds.getVertex(BOTTOM_RIGHT_NEAR)) / 2.0f);

View file

@ -293,7 +293,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE);
serverDetails << " jurisdiction: "
<< qPrintable(rootCodeHex)

View file

@ -198,7 +198,7 @@ public:
float getSize() const { return _radius * 2.0f; }
/// get maximum dimension in domain scale units (0.0 - 1.0)
AABox getAABox() const { return AABox(getMinimumPoint(), getSize()); }
AACube getAACube() const { return AACube(getMinimumPoint(), getSize()); }
// model related properties
bool hasModel() const { return !_modelURL.isEmpty(); }

View file

@ -116,8 +116,8 @@ void ModelTree::storeModel(const ModelItem& model, const SharedNodePointer& send
// if we didn't find it in the tree, then store it...
if (!theOperator.wasFound()) {
AABox modelBox = model.getAABox();
ModelTreeElement* element = (ModelTreeElement*)getOrCreateChildElementContaining(model.getAABox());
AACube modelCube = model.getAACube();
ModelTreeElement* element = (ModelTreeElement*)getOrCreateChildElementContaining(model.getAACube());
element->storeModel(model);
// In the case where we stored it, we also need to mark the entire "path" down to the model as
@ -270,7 +270,7 @@ bool ModelTree::findNearPointOperation(OctreeElement* element, void* extraData)
ModelTreeElement* modelTreeElement = static_cast<ModelTreeElement*>(element);
glm::vec3 penetration;
bool sphereIntersection = modelTreeElement->getAABox().findSpherePenetration(args->position,
bool sphereIntersection = modelTreeElement->getAACube().findSpherePenetration(args->position,
args->targetRadius, penetration);
// If this modelTreeElement contains the point, then search it...
@ -320,7 +320,7 @@ public:
bool ModelTree::findInSphereOperation(OctreeElement* element, void* extraData) {
FindAllNearPointArgs* args = static_cast<FindAllNearPointArgs*>(extraData);
glm::vec3 penetration;
bool sphereIntersection = element->getAABox().findSpherePenetration(args->position,
bool sphereIntersection = element->getAACube().findSpherePenetration(args->position,
args->targetRadius, penetration);
// If this element contains the point, then search it...
@ -343,31 +343,31 @@ void ModelTree::findModels(const glm::vec3& center, float radius, QVector<const
foundModels.swap(args.models);
}
class FindModelsInBoxArgs {
class FindModelsInCubeArgs {
public:
FindModelsInBoxArgs(const AABox& box)
: _box(box), _foundModels() {
FindModelsInCubeArgs(const AACube& cube)
: _cube(cube), _foundModels() {
}
AABox _box;
AACube _cube;
QVector<ModelItem*> _foundModels;
};
bool ModelTree::findInBoxForUpdateOperation(OctreeElement* element, void* extraData) {
FindModelsInBoxArgs* args = static_cast< FindModelsInBoxArgs*>(extraData);
const AABox& elementBox = element->getAABox();
if (elementBox.touches(args->_box)) {
bool ModelTree::findInCubeForUpdateOperation(OctreeElement* element, void* extraData) {
FindModelsInCubeArgs* args = static_cast< FindModelsInCubeArgs*>(extraData);
const AACube& elementCube = element->getAACube();
if (elementCube.touches(args->_cube)) {
ModelTreeElement* modelTreeElement = static_cast<ModelTreeElement*>(element);
modelTreeElement->getModelsForUpdate(args->_box, args->_foundModels);
modelTreeElement->getModelsForUpdate(args->_cube, args->_foundModels);
return true;
}
return false;
}
void ModelTree::findModelsForUpdate(const AABox& box, QVector<ModelItem*> foundModels) {
FindModelsInBoxArgs args(box);
void ModelTree::findModelsForUpdate(const AACube& cube, QVector<ModelItem*> foundModels) {
FindModelsInCubeArgs args(cube);
lockForRead();
recurseTreeWithOperation(findInBoxForUpdateOperation, &args);
recurseTreeWithOperation(findInCubeForUpdateOperation, &args);
unlock();
// swap the two lists of model pointers instead of copy
foundModels.swap(args._foundModels);
@ -507,7 +507,7 @@ void ModelTree::update() {
bool shouldDie = args._movingModels[i].getShouldDie();
// if the particle is still inside our total bounds, then re-add it
AABox treeBounds = getRoot()->getAABox();
AACube treeBounds = getRoot()->getAACube();
if (!shouldDie && treeBounds.contains(args._movingModels[i].getPosition())) {
storeModel(args._movingModels[i]);

View file

@ -58,11 +58,11 @@ public:
/// \remark Side effect: any initial contents in foundModels will be lost
void findModels(const glm::vec3& center, float radius, QVector<const ModelItem*>& foundModels);
/// finds all models that touch a box
/// \param box the query box
/// finds all models that touch a cube
/// \param cube the query cube
/// \param foundModels[out] vector of non-const ModelItem*
/// \remark Side effect: any initial contents in models will be lost
void findModelsForUpdate(const AABox& box, QVector<ModelItem*> foundModels);
void findModelsForUpdate(const AACube& cube, QVector<ModelItem*> foundModels);
void addNewlyCreatedHook(NewlyCreatedModelHook* hook);
void removeNewlyCreatedHook(NewlyCreatedModelHook* hook);
@ -86,7 +86,7 @@ private:
static bool findByIDOperation(OctreeElement* element, void* extraData);
static bool findAndDeleteOperation(OctreeElement* element, void* extraData);
static bool findAndUpdateModelItemIDOperation(OctreeElement* element, void* extraData);
static bool findInBoxForUpdateOperation(OctreeElement* element, void* extraData);
static bool findInCubeForUpdateOperation(OctreeElement* element, void* extraData);
void notifyNewlyCreatedModel(const ModelItem& newModel, const SharedNodePointer& senderNode);

View file

@ -57,9 +57,9 @@ bool ModelTreeElement::appendElementData(OctreePacketData* packetData, EncodeBit
for (uint16_t i = 0; i < _modelItems->size(); i++) {
if (params.viewFrustum) {
const ModelItem& model = (*_modelItems)[i];
AABox modelBox = model.getAABox();
modelBox.scale(TREE_SCALE);
if (params.viewFrustum->boxInFrustum(modelBox) != ViewFrustum::OUTSIDE) {
AACube modelCube = model.getAACube();
modelCube.scale(TREE_SCALE);
if (params.viewFrustum->cubeInFrustum(modelCube) != ViewFrustum::OUTSIDE) {
indexesOfModelsToInclude << i;
numberOfModels++;
}
@ -86,18 +86,18 @@ bool ModelTreeElement::appendElementData(OctreePacketData* packetData, EncodeBit
bool ModelTreeElement::containsModelBounds(const ModelItem& model) const {
glm::vec3 clampedMin = glm::clamp(model.getMinimumPoint(), 0.0f, 1.0f);
glm::vec3 clampedMax = glm::clamp(model.getMaximumPoint(), 0.0f, 1.0f);
return _box.contains(clampedMin) && _box.contains(clampedMax);
return _cube.contains(clampedMin) && _cube.contains(clampedMax);
}
bool ModelTreeElement::bestFitModelBounds(const ModelItem& model) const {
glm::vec3 clampedMin = glm::clamp(model.getMinimumPoint(), 0.0f, 1.0f);
glm::vec3 clampedMax = glm::clamp(model.getMaximumPoint(), 0.0f, 1.0f);
if (_box.contains(clampedMin) && _box.contains(clampedMax)) {
if (_cube.contains(clampedMin) && _cube.contains(clampedMax)) {
int childForMinimumPoint = getMyChildContainingPoint(clampedMin);
int childForMaximumPoint = getMyChildContainingPoint(clampedMax);
// if this is a really small box, then it's close enough!
if (_box.getScale() <= SMALLEST_REASONABLE_OCTREE_ELEMENT_SCALE) {
if (_cube.getScale() <= SMALLEST_REASONABLE_OCTREE_ELEMENT_SCALE) {
return true;
}
// If I contain both the minimum and maximum point, but two different children of mine
@ -282,18 +282,18 @@ void ModelTreeElement::getModels(const glm::vec3& searchPosition, float searchRa
}
}
void ModelTreeElement::getModelsForUpdate(const AABox& box, QVector<ModelItem*>& foundModels) {
void ModelTreeElement::getModelsForUpdate(const AACube& box, QVector<ModelItem*>& foundModels) {
QList<ModelItem>::iterator modelItr = _modelItems->begin();
QList<ModelItem>::iterator modelEnd = _modelItems->end();
AABox modelBox;
AACube modelCube;
while(modelItr != modelEnd) {
ModelItem* model = &(*modelItr);
float radius = model->getRadius();
// NOTE: we actually do box-box collision queries here, which is sloppy but good enough for now
// TODO: decide whether to replace modelBox-box query with sphere-box (requires a square root
// NOTE: we actually do cube-cube collision queries here, which is sloppy but good enough for now
// TODO: decide whether to replace modelCube-cube query with sphere-cube (requires a square root
// but will be slightly more accurate).
modelBox.setBox(model->getPosition() - glm::vec3(radius), 2.f * radius);
if (modelBox.touches(_box)) {
modelCube.setBox(model->getPosition() - glm::vec3(radius), 2.f * radius);
if (modelCube.touches(_cube)) {
foundModels.push_back(model);
}
++modelItr;

View file

@ -125,7 +125,7 @@ public:
/// finds all models that touch a box
/// \param box the query box
/// \param models[out] vector of non-const ModelItem*
void getModelsForUpdate(const AABox& box, QVector<ModelItem*>& foundModels);
void getModelsForUpdate(const AACube& box, QVector<ModelItem*>& foundModels);
const ModelItem* getModelWithID(uint32_t id) const;

View file

@ -9,27 +9,31 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "AABox.h"
#include "AACube.h"
#include "GeometryUtil.h"
#include "SharedUtil.h"
#include "AABox.h"
#include "GeometryUtil.h"
AABox::AABox(const glm::vec3& corner, float size) :
_corner(corner), _scale(size) {
_corner(corner), _scale(size, size, size) {
};
AABox::AABox() : _corner(0,0,0), _scale(0) {
AABox::AABox(const glm::vec3& corner, const glm::vec3& dimensions) :
_corner(corner), _scale(dimensions) {
};
AABox::AABox() : _corner(0.0f, 0.0f, 0.0f), _scale(0.0f, 0.0f, 0.0f) {
};
glm::vec3 AABox::calcCenter() const {
glm::vec3 center(_corner);
center += (glm::vec3(_scale, _scale, _scale) * 0.5f);
center += (_scale * 0.5f);
return center;
}
glm::vec3 AABox::calcTopFarLeft() const {
glm::vec3 topFarLeft(_corner);
topFarLeft += glm::vec3(_scale, _scale, _scale);
topFarLeft += _scale;
return topFarLeft;
};
@ -41,26 +45,31 @@ void AABox::scale(float scale) {
glm::vec3 AABox::getVertex(BoxVertex vertex) const {
switch (vertex) {
case BOTTOM_LEFT_NEAR:
return _corner + glm::vec3(_scale, 0, 0);
return _corner + glm::vec3(_scale.x, 0, 0);
case BOTTOM_RIGHT_NEAR:
return _corner;
case TOP_RIGHT_NEAR:
return _corner + glm::vec3(0, _scale, 0);
return _corner + glm::vec3(0, _scale.y, 0);
case TOP_LEFT_NEAR:
return _corner + glm::vec3(_scale, _scale, 0);
return _corner + glm::vec3(_scale.x, _scale.y, 0);
case BOTTOM_LEFT_FAR:
return _corner + glm::vec3(_scale, 0, _scale);
return _corner + glm::vec3(_scale.x, 0, _scale.z);
case BOTTOM_RIGHT_FAR:
return _corner + glm::vec3(0, 0, _scale);
return _corner + glm::vec3(0, 0, _scale.z);
case TOP_RIGHT_FAR:
return _corner + glm::vec3(0, _scale, _scale);
return _corner + glm::vec3(0, _scale.y, _scale.z);
default: //quiet windows warnings
case TOP_LEFT_FAR:
return _corner + glm::vec3(_scale, _scale, _scale);
return _corner + _scale;
}
}
void AABox::setBox(const glm::vec3& corner, float scale) {
_corner = corner;
_scale = glm::vec3(scale, scale, scale);
}
void AABox::setBox(const glm::vec3& corner, const glm::vec3& scale) {
_corner = corner;
_scale = scale;
}
@ -68,13 +77,13 @@ void AABox::setBox(const glm::vec3& corner, float scale) {
glm::vec3 AABox::getVertexP(const glm::vec3& normal) const {
glm::vec3 result = _corner;
if (normal.x > 0) {
result.x += _scale;
result.x += _scale.x;
}
if (normal.y > 0) {
result.y += _scale;
result.y += _scale.y;
}
if (normal.z > 0) {
result.z += _scale;
result.z += _scale.z;
}
return result;
}
@ -83,15 +92,15 @@ glm::vec3 AABox::getVertexN(const glm::vec3& normal) const {
glm::vec3 result = _corner;
if (normal.x < 0) {
result.x += _scale;
result.x += _scale.x;
}
if (normal.y < 0) {
result.y += _scale;
result.y += _scale.y;
}
if (normal.z < 0) {
result.z += _scale;
result.z += _scale.z;
}
return result;
@ -103,9 +112,9 @@ static bool isWithin(float value, float corner, float size) {
}
bool AABox::contains(const glm::vec3& point) const {
return isWithin(point.x, _corner.x, _scale) &&
isWithin(point.y, _corner.y, _scale) &&
isWithin(point.z, _corner.z, _scale);
return isWithin(point.x, _corner.x, _scale.x) &&
isWithin(point.y, _corner.y, _scale.y) &&
isWithin(point.z, _corner.z, _scale.z);
}
bool AABox::contains(const AABox& otherBox) const {
@ -119,11 +128,33 @@ bool AABox::contains(const AABox& otherBox) const {
}
bool AABox::touches(const AABox& otherBox) const {
glm::vec3 relativeCenter = _corner - otherBox._corner + (glm::vec3(_scale - otherBox._scale) * 0.5f);
float totalHalfScale = 0.5f * (_scale + otherBox._scale);
return fabs(relativeCenter.x) <= totalHalfScale &&
fabs(relativeCenter.y) <= totalHalfScale &&
fabs(relativeCenter.z) <= totalHalfScale;
glm::vec3 relativeCenter = _corner - otherBox._corner + ((_scale - otherBox._scale) * 0.5f);
glm::vec3 totalHalfScale = (_scale + otherBox._scale) * 0.5f;
return fabs(relativeCenter.x) <= totalHalfScale.x &&
fabs(relativeCenter.y) <= totalHalfScale.y &&
fabs(relativeCenter.z) <= totalHalfScale.z;
}
bool AABox::contains(const AACube& otherCube) const {
for (int v = BOTTOM_LEFT_NEAR; v < TOP_LEFT_FAR; v++) {
glm::vec3 vertex = otherCube.getVertex((BoxVertex)v);
if (!contains(vertex)) {
return false;
}
}
return true;
}
bool AABox::touches(const AACube& otherCube) const {
glm::vec3 relativeCenter = _corner - otherCube.getCorner() + ((_scale - otherCube.getDimensions()) * 0.5f);
glm::vec3 totalHalfScale = (_scale + otherCube.getDimensions()) * 0.5f;
return fabs(relativeCenter.x) <= totalHalfScale.x &&
fabs(relativeCenter.y) <= totalHalfScale.y &&
fabs(relativeCenter.z) <= totalHalfScale.z;
}
// determines whether a value is within the expanded extents
@ -132,9 +163,9 @@ static bool isWithinExpanded(float value, float corner, float size, float expans
}
bool AABox::expandedContains(const glm::vec3& point, float expansion) const {
return isWithinExpanded(point.x, _corner.x, _scale, expansion) &&
isWithinExpanded(point.y, _corner.y, _scale, expansion) &&
isWithinExpanded(point.z, _corner.z, _scale, expansion);
return isWithinExpanded(point.x, _corner.x, _scale.x, expansion) &&
isWithinExpanded(point.y, _corner.y, _scale.y, expansion) &&
isWithinExpanded(point.z, _corner.z, _scale.z, expansion);
}
// finds the intersection between a ray and the facing plane on one axis
@ -156,7 +187,7 @@ bool AABox::expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& e
}
// check each axis
glm::vec3 expandedCorner = _corner - glm::vec3(expansion, expansion, expansion);
glm::vec3 expandedSize = glm::vec3(_scale, _scale, _scale) + glm::vec3(expansion, expansion, expansion) * 2.0f;
glm::vec3 expandedSize = _scale + glm::vec3(expansion, expansion, expansion) * 2.0f;
glm::vec3 direction = end - start;
float axisDistance;
return (findIntersection(start.x, direction.x, expandedCorner.x, expandedSize.x, axisDistance) &&
@ -181,23 +212,23 @@ bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct
}
// check each axis
float axisDistance;
if ((findIntersection(origin.x, direction.x, _corner.x, _scale, axisDistance) && axisDistance >= 0 &&
isWithin(origin.y + axisDistance*direction.y, _corner.y, _scale) &&
isWithin(origin.z + axisDistance*direction.z, _corner.z, _scale))) {
if ((findIntersection(origin.x, direction.x, _corner.x, _scale.x, axisDistance) && axisDistance >= 0 &&
isWithin(origin.y + axisDistance*direction.y, _corner.y, _scale.y) &&
isWithin(origin.z + axisDistance*direction.z, _corner.z, _scale.z))) {
distance = axisDistance;
face = direction.x > 0 ? MIN_X_FACE : MAX_X_FACE;
return true;
}
if ((findIntersection(origin.y, direction.y, _corner.y, _scale, axisDistance) && axisDistance >= 0 &&
isWithin(origin.x + axisDistance*direction.x, _corner.x, _scale) &&
isWithin(origin.z + axisDistance*direction.z, _corner.z, _scale))) {
if ((findIntersection(origin.y, direction.y, _corner.y, _scale.y, axisDistance) && axisDistance >= 0 &&
isWithin(origin.x + axisDistance*direction.x, _corner.x, _scale.x) &&
isWithin(origin.z + axisDistance*direction.z, _corner.z, _scale.z))) {
distance = axisDistance;
face = direction.y > 0 ? MIN_Y_FACE : MAX_Y_FACE;
return true;
}
if ((findIntersection(origin.z, direction.z, _corner.z, _scale, axisDistance) && axisDistance >= 0 &&
isWithin(origin.y + axisDistance*direction.y, _corner.y, _scale) &&
isWithin(origin.x + axisDistance*direction.x, _corner.x, _scale))) {
if ((findIntersection(origin.z, direction.z, _corner.z, _scale.z, axisDistance) && axisDistance >= 0 &&
isWithin(origin.y + axisDistance*direction.y, _corner.y, _scale.y) &&
isWithin(origin.x + axisDistance*direction.x, _corner.x, _scale.x))) {
distance = axisDistance;
face = direction.z > 0 ? MIN_Z_FACE : MAX_Z_FACE;
return true;
@ -260,28 +291,28 @@ glm::vec3 AABox::getClosestPointOnFace(const glm::vec3& point, BoxFace face) con
switch (face) {
case MIN_X_FACE:
return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z),
glm::vec3(_corner.x, _corner.y + _scale, _corner.z + _scale));
glm::vec3(_corner.x, _corner.y + _scale.y, _corner.z + _scale.z));
case MAX_X_FACE:
return glm::clamp(point, glm::vec3(_corner.x + _scale, _corner.y, _corner.z),
glm::vec3(_corner.x + _scale, _corner.y + _scale, _corner.z + _scale));
return glm::clamp(point, glm::vec3(_corner.x + _scale.x, _corner.y, _corner.z),
glm::vec3(_corner.x + _scale.x, _corner.y + _scale.y, _corner.z + _scale.z));
case MIN_Y_FACE:
return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z),
glm::vec3(_corner.x + _scale, _corner.y, _corner.z + _scale));
glm::vec3(_corner.x + _scale.x, _corner.y, _corner.z + _scale.z));
case MAX_Y_FACE:
return glm::clamp(point, glm::vec3(_corner.x, _corner.y + _scale, _corner.z),
glm::vec3(_corner.x + _scale, _corner.y + _scale, _corner.z + _scale));
return glm::clamp(point, glm::vec3(_corner.x, _corner.y + _scale.y, _corner.z),
glm::vec3(_corner.x + _scale.x, _corner.y + _scale.y, _corner.z + _scale.z));
case MIN_Z_FACE:
return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z),
glm::vec3(_corner.x + _scale, _corner.y + _scale, _corner.z));
glm::vec3(_corner.x + _scale.z, _corner.y + _scale.y, _corner.z));
default: //quiet windows warnings
case MAX_Z_FACE:
return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z + _scale),
glm::vec3(_corner.x + _scale, _corner.y + _scale, _corner.z + _scale));
return glm::clamp(point, glm::vec3(_corner.x, _corner.y, _corner.z + _scale.z),
glm::vec3(_corner.x + _scale.x, _corner.y + _scale.y, _corner.z + _scale.z));
}
}
@ -331,7 +362,7 @@ glm::vec3 AABox::getClosestPointOnFace(const glm::vec4& origin, const glm::vec4&
glm::vec4 thirdAxisMaxPlane = getPlane((BoxFace)(thirdAxis * 2 + 1));
glm::vec4 offset = glm::vec4(0.0f, 0.0f, 0.0f,
glm::dot(glm::vec3(secondAxisMaxPlane + thirdAxisMaxPlane), glm::vec3(_scale, _scale, _scale)) * 0.5f);
glm::dot(glm::vec3(secondAxisMaxPlane + thirdAxisMaxPlane), _scale) * 0.5f);
glm::vec4 diagonals[] = { secondAxisMinPlane + thirdAxisMaxPlane + offset,
secondAxisMaxPlane + thirdAxisMaxPlane + offset };
@ -355,12 +386,12 @@ glm::vec3 AABox::getClosestPointOnFace(const glm::vec4& origin, const glm::vec4&
glm::vec4 AABox::getPlane(BoxFace face) const {
switch (face) {
case MIN_X_FACE: return glm::vec4(-1.0f, 0.0f, 0.0f, _corner.x);
case MAX_X_FACE: return glm::vec4(1.0f, 0.0f, 0.0f, -_corner.x - _scale);
case MAX_X_FACE: return glm::vec4(1.0f, 0.0f, 0.0f, -_corner.x - _scale.x);
case MIN_Y_FACE: return glm::vec4(0.0f, -1.0f, 0.0f, _corner.y);
case MAX_Y_FACE: return glm::vec4(0.0f, 1.0f, 0.0f, -_corner.y - _scale);
case MAX_Y_FACE: return glm::vec4(0.0f, 1.0f, 0.0f, -_corner.y - _scale.y);
case MIN_Z_FACE: return glm::vec4(0.0f, 0.0f, -1.0f, _corner.z);
default: //quiet windows warnings
case MAX_Z_FACE: return glm::vec4(0.0f, 0.0f, 1.0f, -_corner.z - _scale);
case MAX_Z_FACE: return glm::vec4(0.0f, 0.0f, 1.0f, -_corner.z - _scale.z);
}
}

View file

@ -17,60 +17,43 @@
#include <glm/glm.hpp>
enum BoxFace {
MIN_X_FACE,
MAX_X_FACE,
MIN_Y_FACE,
MAX_Y_FACE,
MIN_Z_FACE,
MAX_Z_FACE,
UNKNOWN_FACE
};
#include "BoxBase.h"
enum BoxVertex {
BOTTOM_LEFT_NEAR = 0,
BOTTOM_RIGHT_NEAR = 1,
TOP_RIGHT_NEAR = 2,
TOP_LEFT_NEAR = 3,
BOTTOM_LEFT_FAR = 4,
BOTTOM_RIGHT_FAR = 5,
TOP_RIGHT_FAR = 6,
TOP_LEFT_FAR = 7
};
const int FACE_COUNT = 6;
class AACube;
class AABox {
public:
AABox(const glm::vec3& corner, float size);
AABox(const glm::vec3& corner, const glm::vec3& dimensions);
AABox();
~AABox() {};
void setBox(const glm::vec3& corner, float scale);
void setBox(const glm::vec3& corner, const glm::vec3& scale);
// for use in frustum computations
glm::vec3 getVertexP(const glm::vec3& normal) const;
glm::vec3 getVertexN(const glm::vec3& normal) const;
void setBox(const glm::vec3& corner, float scale);
glm::vec3 getVertexP(const glm::vec3& normal) const;
glm::vec3 getVertexN(const glm::vec3& normal) const;
void scale(float scale);
const glm::vec3& getCorner() const { return _corner; }
const glm::vec3& getScale() const { return _scale; }
const glm::vec3& getDimensions() const { return _scale; }
void scale(float scale);
glm::vec3 calcCenter() const;
glm::vec3 calcTopFarLeft() const;
glm::vec3 getVertex(BoxVertex vertex) const;
bool contains(const glm::vec3& point) const;
bool contains(const AABox& otherBox) const;
bool touches(const AABox& otherBox) const;
const glm::vec3& getCorner() const { return _corner; };
float getScale() const { return _scale; }
bool contains(const AACube& otherCube) const;
bool touches(const AACube& otherCube) const;
glm::vec3 calcCenter() const;
glm::vec3 calcTopFarLeft() const;
glm::vec3 getVertex(BoxVertex vertex) const;
bool contains(const glm::vec3& point) const;
bool contains(const AABox& otherBox) const;
bool touches(const AABox& otherBox) const;
bool expandedContains(const glm::vec3& point, float expansion) const;
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const;
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) const;
bool expandedContains(const glm::vec3& point, float expansion) const;
bool expandedIntersectsSegment(const glm::vec3& start, const glm::vec3& end, float expansion) const;
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const;
bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const;
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration) const;
private:
glm::vec3 getClosestPointOnFace(const glm::vec3& point, BoxFace face) const;
@ -80,7 +63,7 @@ private:
static BoxFace getOppositeFace(BoxFace face);
glm::vec3 _corner;
float _scale;
glm::vec3 _scale;
};
#endif // hifi_AABox_h

View file

@ -583,7 +583,7 @@ OctreeElement* Octree::getOrCreateChildElementAt(float x, float y, float z, floa
return getRoot()->getOrCreateChildElementAt(x, y, z, s);
}
OctreeElement* Octree::getOrCreateChildElementContaining(const AABox& box) {
OctreeElement* Octree::getOrCreateChildElementContaining(const AACube& box) {
return getRoot()->getOrCreateChildElementContaining(box);
}
@ -601,7 +601,7 @@ public:
bool findRayIntersectionOp(OctreeElement* element, void* extraData) {
RayArgs* args = static_cast<RayArgs*>(extraData);
AABox box = element->getAABox();
AACube box = element->getAACube();
float distance;
BoxFace face;
if (!box.findRayIntersection(args->origin, args->direction, distance, face)) {
@ -664,7 +664,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
SphereArgs* args = static_cast<SphereArgs*>(extraData);
// coarse check against bounds
const AABox& box = element->getAABox();
const AACube& box = element->getAACube();
if (!box.expandedContains(args->center, args->radius)) {
return false;
}
@ -743,7 +743,7 @@ bool findCapsulePenetrationOp(OctreeElement* element, void* extraData) {
CapsuleArgs* args = static_cast<CapsuleArgs*>(extraData);
// coarse check against bounds
const AABox& box = element->getAABox();
const AACube& box = element->getAACube();
if (!box.expandedIntersectsSegment(args->start, args->end, args->radius)) {
return false;
}
@ -764,7 +764,7 @@ bool findShapeCollisionsOp(OctreeElement* element, void* extraData) {
ShapeArgs* args = static_cast<ShapeArgs*>(extraData);
// coarse check against bounds
AABox cube = element->getAABox();
AACube cube = element->getAACube();
cube.scale(TREE_SCALE);
if (!cube.expandedContains(args->shape->getPosition(), args->shape->getBoundingRadius())) {
return false;
@ -858,7 +858,7 @@ public:
// Find the smallest colored voxel enclosing a point (if there is one)
bool getElementEnclosingOperation(OctreeElement* element, void* extraData) {
GetElementEnclosingArgs* args = static_cast<GetElementEnclosingArgs*>(extraData);
AABox elementBox = element->getAABox();
AACube elementBox = element->getAACube();
if (elementBox.contains(args->point)) {
if (element->hasContent() && element->isLeaf()) {
// we've reached a solid leaf containing the point, return the element.
@ -1117,7 +1117,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
// If the user also asked for occlusion culling, check if this element is occluded, but only if it's not a leaf.
// leaf occlusion is handled down below when we check child nodes
if (params.wantOcclusionCulling && !element->isLeaf()) {
AABox voxelBox = element->getAABox();
AACube voxelBox = element->getAACube();
voxelBox.scale(TREE_SCALE);
OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(params.viewFrustum->getProjectedPolygon(voxelBox));
@ -1250,7 +1250,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElement* element,
if (params.wantOcclusionCulling && childElement->isLeaf()) {
// Don't check occlusion here, just add them to our distance ordered array...
AABox voxelBox = childElement->getAABox();
AACube voxelBox = childElement->getAACube();
voxelBox.scale(TREE_SCALE);
OctreeProjectedPolygon* voxelPolygon = new OctreeProjectedPolygon(
params.viewFrustum->getProjectedPolygon(voxelBox));

View file

@ -236,7 +236,7 @@ public:
OctreeElement* getOctreeEnclosingElementAt(float x, float y, float z, float s) const;
OctreeElement* getOrCreateChildElementAt(float x, float y, float z, float s);
OctreeElement* getOrCreateChildElementContaining(const AABox& box);
OctreeElement* getOrCreateChildElementContaining(const AACube& box);
void recurseTreeWithOperation(RecurseOctreeOperation operation, void* extraData = NULL);
void recurseTreeWithPostOperation(RecurseOctreeOperation operation, void* extraData = NULL);

View file

@ -19,7 +19,7 @@
#include <PerfStat.h>
#include <assert.h>
#include "AABox.h"
#include "AACube.h"
#include "OctalCode.h"
#include "OctreeConstants.h"
#include "OctreeElement.h"
@ -93,7 +93,7 @@ void OctreeElement::init(unsigned char * octalCode) {
_isDirty = true;
_shouldRender = false;
_sourceUUIDKey = 0;
calculateAABox();
calculateAACube();
markWithChangedTime();
}
@ -190,15 +190,15 @@ void OctreeElement::setShouldRender(bool shouldRender) {
}
}
void OctreeElement::calculateAABox() {
void OctreeElement::calculateAACube() {
glm::vec3 corner;
// copy corner into box
// copy corner into cube
copyFirstVertexForCode(getOctalCode(),(float*)&corner);
// this tells you the "size" of the voxel
float voxelScale = 1 / powf(2, numberOfThreeBitSectionsInCode(getOctalCode()));
_box.setBox(corner,voxelScale);
_cube.setBox(corner,voxelScale);
}
void OctreeElement::deleteChildAtIndex(int childIndex) {
@ -1178,7 +1178,7 @@ void OctreeElement::printDebugDetails(const char* label) const {
QString resultString;
resultString.sprintf("%s - Voxel at corner=(%f,%f,%f) size=%f\n isLeaf=%s isDirty=%s shouldRender=%s\n children=", label,
_box.getCorner().x, _box.getCorner().y, _box.getCorner().z, _box.getScale(),
_cube.getCorner().x, _cube.getCorner().y, _cube.getCorner().z, _cube.getScale(),
debug::valueOf(isLeaf()), debug::valueOf(isDirty()), debug::valueOf(getShouldRender()));
elementDebug << resultString;
@ -1192,9 +1192,9 @@ float OctreeElement::getEnclosingRadius() const {
}
ViewFrustum::location OctreeElement::inFrustum(const ViewFrustum& viewFrustum) const {
AABox box = _box; // use temporary box so we can scale it
box.scale(TREE_SCALE);
return viewFrustum.boxInFrustum(box);
AACube cube = _cube; // use temporary cube so we can scale it
cube.scale(TREE_SCALE);
return viewFrustum.cubeInFrustum(cube);
}
// There are two types of nodes for which we want to "render"
@ -1228,27 +1228,27 @@ bool OctreeElement::calculateShouldRender(const ViewFrustum* viewFrustum, float
// does as much math as possible in voxel scale and then scales up to TREE_SCALE at end
float OctreeElement::furthestDistanceToCamera(const ViewFrustum& viewFrustum) const {
glm::vec3 furthestPoint;
viewFrustum.getFurthestPointFromCameraVoxelScale(getAABox(), furthestPoint);
viewFrustum.getFurthestPointFromCameraVoxelScale(getAACube(), furthestPoint);
glm::vec3 temp = viewFrustum.getPositionVoxelScale() - furthestPoint;
float distanceToFurthestPoint = sqrtf(glm::dot(temp, temp));
return distanceToFurthestPoint * (float)TREE_SCALE;
}
float OctreeElement::distanceToCamera(const ViewFrustum& viewFrustum) const {
glm::vec3 center = _box.calcCenter() * (float)TREE_SCALE;
glm::vec3 center = _cube.calcCenter() * (float)TREE_SCALE;
glm::vec3 temp = viewFrustum.getPosition() - center;
float distanceToVoxelCenter = sqrtf(glm::dot(temp, temp));
return distanceToVoxelCenter;
}
float OctreeElement::distanceSquareToPoint(const glm::vec3& point) const {
glm::vec3 temp = point - _box.calcCenter();
glm::vec3 temp = point - _cube.calcCenter();
float distanceSquare = glm::dot(temp, temp);
return distanceSquare;
}
float OctreeElement::distanceToPoint(const glm::vec3& point) const {
glm::vec3 temp = point - _box.calcCenter();
glm::vec3 temp = point - _cube.calcCenter();
float distance = sqrtf(glm::dot(temp, temp));
return distance;
}
@ -1304,7 +1304,7 @@ void OctreeElement::notifyUpdateHooks() {
bool OctreeElement::findSpherePenetration(const glm::vec3& center, float radius,
glm::vec3& penetration, void** penetratedObject) const {
return _box.findSpherePenetration(center, radius, penetration);
return _cube.findSpherePenetration(center, radius, penetration);
}
@ -1323,7 +1323,7 @@ OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float
return this;
}
// otherwise, we need to find which of our children we should recurse
glm::vec3 ourCenter = _box.calcCenter();
glm::vec3 ourCenter = _cube.calcCenter();
int childIndex = CHILD_UNKNOWN;
// left half
@ -1381,31 +1381,31 @@ OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float
}
OctreeElement* OctreeElement::getOrCreateChildElementContaining(const AABox& box) {
OctreeElement* OctreeElement::getOrCreateChildElementContaining(const AACube& cube) {
OctreeElement* child = NULL;
float ourScale = getScale();
float boxScale = box.getScale();
float cubeScale = cube.getScale();
if(boxScale > ourScale) {
if(cubeScale > ourScale) {
qDebug("UNEXPECTED -- OctreeElement::getOrCreateChildElementContaining() "
"boxScale=[%f] > ourScale=[%f] ", boxScale, ourScale);
"cubeScale=[%f] > ourScale=[%f] ", cubeScale, ourScale);
}
// Determine which of our children the minimum and maximum corners of the box live in...
glm::vec3 boxCornerMinimum = box.getCorner();
glm::vec3 boxCornerMaximum = box.calcTopFarLeft();
// Determine which of our children the minimum and maximum corners of the cube live in...
glm::vec3 cubeCornerMinimum = cube.getCorner();
glm::vec3 cubeCornerMaximum = cube.calcTopFarLeft();
int childIndexBoxMinimum = getMyChildContainingPoint(boxCornerMinimum);
int childIndexBoxMaximum = getMyChildContainingPoint(boxCornerMaximum);
int childIndexCubeMinimum = getMyChildContainingPoint(cubeCornerMinimum);
int childIndexCubeMaximum = getMyChildContainingPoint(cubeCornerMaximum);
// If the minimum and maximum corners of the box are in two different children's boxes, then we are the containing element
if (childIndexBoxMinimum != childIndexBoxMaximum) {
// If the minimum and maximum corners of the cube are in two different children's cubes, then we are the containing element
if (childIndexCubeMinimum != childIndexCubeMaximum) {
return this;
}
// otherwise, they are the same and that child should be considered as the correct element
int childIndex = childIndexBoxMinimum; // both the same...
int childIndex = childIndexCubeMinimum; // both the same...
// Now, check if we have a child at that location
child = getChildAtIndex(childIndex);
@ -1419,11 +1419,11 @@ OctreeElement* OctreeElement::getOrCreateChildElementContaining(const AABox& box
}
// Now that we have the child to recurse down, let it answer the original question...
return child->getOrCreateChildElementContaining(box);
return child->getOrCreateChildElementContaining(cube);
}
int OctreeElement::getMyChildContainingPoint(const glm::vec3& point) const {
glm::vec3 ourCenter = _box.calcCenter();
glm::vec3 ourCenter = _cube.calcCenter();
int childIndex = CHILD_UNKNOWN;
// left half
if (point.x > ourCenter.x) {

View file

@ -20,7 +20,7 @@
#include <SharedUtil.h>
#include "AABox.h"
#include "AACube.h"
#include "ViewFrustum.h"
#include "OctreeConstants.h"
@ -116,9 +116,9 @@ public:
bool safeDeepDeleteChildAtIndex(int childIndex, int recursionCount = 0);
const AABox& getAABox() const { return _box; }
const glm::vec3& getCorner() const { return _box.getCorner(); }
float getScale() const { return _box.getScale(); }
const AACube& getAACube() const { return _cube; }
const glm::vec3& getCorner() const { return _cube.getCorner(); }
float getScale() const { return _cube.getScale(); }
int getLevel() const { return numberOfThreeBitSectionsInCode(getOctalCode()) + 1; }
float getEnclosingRadius() const;
@ -223,7 +223,7 @@ public:
OctreeElement* getOrCreateChildElementAt(float x, float y, float z, float s);
OctreeElement* getOrCreateChildElementContaining(const AABox& box);
OctreeElement* getOrCreateChildElementContaining(const AACube& box);
int getMyChildContainingPoint(const glm::vec3& point) const;
protected:
@ -240,11 +240,11 @@ protected:
void encodeThreeOffsets(int64_t offsetOne, int64_t offsetTwo, int64_t offsetThree);
void checkStoreFourChildren(OctreeElement* childOne, OctreeElement* childTwo, OctreeElement* childThree, OctreeElement* childFour);
#endif
void calculateAABox();
void calculateAACube();
void notifyDeleteHooks();
void notifyUpdateHooks();
AABox _box; /// Client and server, axis aligned box for bounds of this voxel, 48 bytes
AACube _cube; /// Client and server, axis aligned box for bounds of this voxel, 48 bytes
/// Client and server, buffer containing the octal code or a pointer to octal code for this node, 8 bytes
union octalCode_t {

View file

@ -95,10 +95,10 @@ void OctreeHeadlessViewer::queryOctree() {
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inViewServers++;
@ -161,10 +161,10 @@ void OctreeHeadlessViewer::queryOctree() {
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inView = true;
} else {

View file

@ -141,7 +141,7 @@ void ViewFrustum::calculate() {
// Set up our keyhole bounding box...
glm::vec3 corner = _position - _keyholeRadius;
_keyholeBoundingBox = AABox(corner,(_keyholeRadius * 2.0f));
_keyholeBoundingCube = AACube(corner,(_keyholeRadius * 2.0f));
}
void ViewFrustum::calculateOrthographic() {
@ -184,7 +184,7 @@ void ViewFrustum::calculateOrthographic() {
// Set up our keyhole bounding box...
glm::vec3 corner = _position - _keyholeRadius;
_keyholeBoundingBox = AABox(corner, (_keyholeRadius * 2.0f));
_keyholeBoundingCube = AACube(corner, (_keyholeRadius * 2.0f));
}
//enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE };
@ -231,6 +231,44 @@ ViewFrustum::location ViewFrustum::sphereInKeyhole(const glm::vec3& center, floa
}
// A box is inside a sphere if all of its corners are inside the sphere
// A box intersects a sphere if any of its edges (as rays) interesect the sphere
// A box is outside a sphere if none of its edges (as rays) interesect the sphere
ViewFrustum::location ViewFrustum::cubeInKeyhole(const AACube& cube) const {
// First check to see if the cube is in the bounding cube for the sphere, if it's not, then we can short circuit
// this and not check with sphere penetration which is more expensive
if (!_keyholeBoundingCube.contains(cube)) {
return OUTSIDE;
}
glm::vec3 penetration;
bool intersects = cube.findSpherePenetration(_position, _keyholeRadius, penetration);
ViewFrustum::location result = OUTSIDE;
// if the cube intersects the sphere, then it may also be inside... calculate further
if (intersects) {
result = INTERSECT;
// test all the corners, if they are all inside the sphere, the entire cube is in the sphere
bool allPointsInside = true; // assume the best
for (int v = BOTTOM_LEFT_NEAR; v < TOP_LEFT_FAR; v++) {
glm::vec3 vertex = cube.getVertex((BoxVertex)v);
if (!pointInKeyhole(vertex)) {
allPointsInside = false;
break;
}
}
if (allPointsInside) {
result = INSIDE;
}
}
return result;
}
// A box is inside a sphere if all of its corners are inside the sphere
// A box intersects a sphere if any of its edges (as rays) interesect the sphere
// A box is outside a sphere if none of its edges (as rays) interesect the sphere
@ -238,7 +276,7 @@ ViewFrustum::location ViewFrustum::boxInKeyhole(const AABox& box) const {
// First check to see if the box is in the bounding box for the sphere, if it's not, then we can short circuit
// this and not check with sphere penetration which is more expensive
if (!_keyholeBoundingBox.contains(box)) {
if (!_keyholeBoundingCube.contains(box)) {
return OUTSIDE;
}
@ -319,14 +357,14 @@ ViewFrustum::location ViewFrustum::sphereInFrustum(const glm::vec3& center, floa
}
ViewFrustum::location ViewFrustum::boxInFrustum(const AABox& box) const {
ViewFrustum::location ViewFrustum::cubeInFrustum(const AACube& cube) const {
ViewFrustum::location regularResult = INSIDE;
ViewFrustum::location keyholeResult = OUTSIDE;
// If we have a keyholeRadius, check that first, since it's cheaper
if (_keyholeRadius >= 0.0f) {
keyholeResult = boxInKeyhole(box);
keyholeResult = cubeInKeyhole(cube);
}
if (keyholeResult == INSIDE) {
return keyholeResult;
@ -338,10 +376,10 @@ ViewFrustum::location ViewFrustum::boxInFrustum(const AABox& box) const {
// also be able to test against the cone to the bounding sphere of the box.
for(int i=0; i < 6; i++) {
const glm::vec3& normal = _planes[i].getNormal();
const glm::vec3& boxVertexP = box.getVertexP(normal);
const glm::vec3& boxVertexP = cube.getVertexP(normal);
float planeToBoxVertexPDistance = _planes[i].distance(boxVertexP);
const glm::vec3& boxVertexN = box.getVertexN(normal);
const glm::vec3& boxVertexN = cube.getVertexN(normal);
float planeToBoxVertexNDistance = _planes[i].distance(boxVertexN);
if (planeToBoxVertexPDistance < 0) {
@ -610,7 +648,7 @@ glm::vec2 ViewFrustum::projectPoint(glm::vec3 point, bool& pointInView) const {
const int MAX_POSSIBLE_COMBINATIONS = 43;
const int hullVertexLookup[MAX_POSSIBLE_COMBINATIONS][MAX_PROJECTED_POLYGON_VERTEX_COUNT+1] = {
// Number of vertices in shadow polygon for the visible faces, then a list of the index of each vertice from the AABox
// Number of vertices in shadow polygon for the visible faces, then a list of the index of each vertice from the AACube
//0
{0}, // inside
@ -682,7 +720,7 @@ const int hullVertexLookup[MAX_POSSIBLE_COMBINATIONS][MAX_PROJECTED_POLYGON_VERT
{6, TOP_RIGHT_NEAR, TOP_RIGHT_FAR, BOTTOM_RIGHT_FAR, BOTTOM_LEFT_FAR, BOTTOM_LEFT_NEAR, TOP_LEFT_NEAR}, // back, top, left
};
OctreeProjectedPolygon ViewFrustum::getProjectedPolygon(const AABox& box) const {
OctreeProjectedPolygon ViewFrustum::getProjectedPolygon(const AACube& box) const {
const glm::vec3& bottomNearRight = box.getCorner();
glm::vec3 topFarLeft = box.calcTopFarLeft();
@ -749,7 +787,7 @@ OctreeProjectedPolygon ViewFrustum::getProjectedPolygon(const AABox& box) const
// Similar strategy to getProjectedPolygon() we use the knowledge of camera position relative to the
// axis-aligned voxels to determine which of the voxels vertices must be the furthest. No need for
// squares and square-roots. Just compares.
void ViewFrustum::getFurthestPointFromCamera(const AABox& box, glm::vec3& furthestPoint) const {
void ViewFrustum::getFurthestPointFromCamera(const AACube& box, glm::vec3& furthestPoint) const {
const glm::vec3& bottomNearRight = box.getCorner();
float scale = box.getScale();
float halfScale = scale * 0.5f;
@ -776,7 +814,7 @@ void ViewFrustum::getFurthestPointFromCamera(const AABox& box, glm::vec3& furthe
}
}
void ViewFrustum::getFurthestPointFromCameraVoxelScale(const AABox& box, glm::vec3& furthestPoint) const {
void ViewFrustum::getFurthestPointFromCameraVoxelScale(const AACube& box, glm::vec3& furthestPoint) const {
const glm::vec3& bottomNearRight = box.getCorner();
float scale = box.getScale();
float halfScale = scale * 0.5f;

View file

@ -18,6 +18,7 @@
#include <glm/gtc/quaternion.hpp>
#include "AABox.h"
#include "AACube.h"
#include "Plane.h"
#include "OctreeConstants.h"
#include "OctreeProjectedPolygon.h"
@ -94,6 +95,7 @@ public:
ViewFrustum::location pointInFrustum(const glm::vec3& point) const;
ViewFrustum::location sphereInFrustum(const glm::vec3& center, float radius) const;
ViewFrustum::location cubeInFrustum(const AACube& cube) const;
ViewFrustum::location boxInFrustum(const AABox& box) const;
// some frustum comparisons
@ -111,29 +113,30 @@ public:
void printDebugDetails() const;
glm::vec2 projectPoint(glm::vec3 point, bool& pointInView) const;
OctreeProjectedPolygon getProjectedPolygon(const AABox& box) const;
void getFurthestPointFromCamera(const AABox& box, glm::vec3& furthestPoint) const;
OctreeProjectedPolygon getProjectedPolygon(const AACube& box) const;
void getFurthestPointFromCamera(const AACube& box, glm::vec3& furthestPoint) const;
// assumes box is in voxel scale, not TREE_SCALE, will scale view frustum's position accordingly
void getFurthestPointFromCameraVoxelScale(const AABox& box, glm::vec3& furthestPoint) const;
void getFurthestPointFromCameraVoxelScale(const AACube& box, glm::vec3& furthestPoint) const;
private:
// Used for keyhole calculations
ViewFrustum::location pointInKeyhole(const glm::vec3& point) const;
ViewFrustum::location sphereInKeyhole(const glm::vec3& center, float radius) const;
ViewFrustum::location cubeInKeyhole(const AACube& cube) const;
ViewFrustum::location boxInKeyhole(const AABox& box) const;
void calculateOrthographic();
// camera location/orientation attributes
glm::vec3 _position; // the position in TREE_SCALE
glm::vec3 _positionVoxelScale; // the position in voxel scale
glm::quat _orientation;
glm::vec3 _position; // the position in TREE_SCALE
glm::vec3 _positionVoxelScale; // the position in voxel scale
glm::quat _orientation;
// calculated for orientation
glm::vec3 _direction;
glm::vec3 _up;
glm::vec3 _right;
glm::vec3 _direction;
glm::vec3 _up;
glm::vec3 _right;
// Lens attributes
bool _orthographic;
@ -148,23 +151,23 @@ private:
glm::quat _eyeOffsetOrientation;
// keyhole attributes
float _keyholeRadius;
AABox _keyholeBoundingBox;
float _keyholeRadius;
AACube _keyholeBoundingCube;
// Calculated values
glm::vec3 _offsetPosition;
glm::vec3 _offsetDirection;
glm::vec3 _offsetUp;
glm::vec3 _offsetRight;
glm::vec3 _farTopLeft;
glm::vec3 _farTopRight;
glm::vec3 _farBottomLeft;
glm::vec3 _farBottomRight;
glm::vec3 _nearTopLeft;
glm::vec3 _nearTopRight;
glm::vec3 _nearBottomLeft;
glm::vec3 _nearBottomRight;
glm::vec3 _offsetPosition;
glm::vec3 _offsetDirection;
glm::vec3 _offsetUp;
glm::vec3 _offsetRight;
glm::vec3 _farTopLeft;
glm::vec3 _farTopRight;
glm::vec3 _farBottomLeft;
glm::vec3 _farBottomRight;
glm::vec3 _nearTopLeft;
glm::vec3 _nearTopRight;
glm::vec3 _nearBottomLeft;
glm::vec3 _nearBottomRight;
enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE };
::Plane _planes[6]; // How will this be used?

View file

@ -237,7 +237,7 @@ bool ParticleTree::findNearPointOperation(OctreeElement* element, void* extraDat
ParticleTreeElement* particleTreeElement = static_cast<ParticleTreeElement*>(element);
glm::vec3 penetration;
bool sphereIntersection = particleTreeElement->getAABox().findSpherePenetration(args->position,
bool sphereIntersection = particleTreeElement->getAACube().findSpherePenetration(args->position,
args->targetRadius, penetration);
// If this particleTreeElement contains the point, then search it...
@ -287,7 +287,7 @@ public:
bool ParticleTree::findInSphereOperation(OctreeElement* element, void* extraData) {
FindAllNearPointArgs* args = static_cast<FindAllNearPointArgs*>(extraData);
glm::vec3 penetration;
bool sphereIntersection = element->getAABox().findSpherePenetration(args->position,
bool sphereIntersection = element->getAACube().findSpherePenetration(args->position,
args->targetRadius, penetration);
// If this element contains the point, then search it...
@ -310,31 +310,31 @@ void ParticleTree::findParticles(const glm::vec3& center, float radius, QVector<
foundParticles.swap(args.particles);
}
class FindParticlesInBoxArgs {
class FindParticlesInCubeArgs {
public:
FindParticlesInBoxArgs(const AABox& box)
: _box(box), _foundParticles() {
FindParticlesInCubeArgs(const AACube& cube)
: _cube(cube), _foundParticles() {
}
AABox _box;
AACube _cube;
QVector<Particle*> _foundParticles;
};
bool ParticleTree::findInBoxForUpdateOperation(OctreeElement* element, void* extraData) {
FindParticlesInBoxArgs* args = static_cast< FindParticlesInBoxArgs*>(extraData);
const AABox& elementBox = element->getAABox();
if (elementBox.touches(args->_box)) {
bool ParticleTree::findInCubeForUpdateOperation(OctreeElement* element, void* extraData) {
FindParticlesInCubeArgs* args = static_cast< FindParticlesInCubeArgs*>(extraData);
const AACube& elementBox = element->getAACube();
if (elementBox.touches(args->_cube)) {
ParticleTreeElement* particleTreeElement = static_cast<ParticleTreeElement*>(element);
particleTreeElement->getParticlesForUpdate(args->_box, args->_foundParticles);
particleTreeElement->getParticlesForUpdate(args->_cube, args->_foundParticles);
return true;
}
return false;
}
void ParticleTree::findParticlesForUpdate(const AABox& box, QVector<Particle*> foundParticles) {
FindParticlesInBoxArgs args(box);
void ParticleTree::findParticlesForUpdate(const AACube& cube, QVector<Particle*> foundParticles) {
FindParticlesInCubeArgs args(cube);
lockForRead();
recurseTreeWithOperation(findInBoxForUpdateOperation, &args);
recurseTreeWithOperation(findInCubeForUpdateOperation, &args);
unlock();
// swap the two lists of particle pointers instead of copy
foundParticles.swap(args._foundParticles);
@ -473,7 +473,7 @@ void ParticleTree::update() {
bool shouldDie = args._movingParticles[i].getShouldDie();
// if the particle is still inside our total bounds, then re-add it
AABox treeBounds = getRoot()->getAABox();
AACube treeBounds = getRoot()->getAACube();
if (!shouldDie && treeBounds.contains(args._movingParticles[i].getPosition())) {
storeParticle(args._movingParticles[i]);

View file

@ -60,7 +60,7 @@ public:
/// \param box the query box
/// \param foundParticles[out] vector of non-const Particle*
/// \remark Side effect: any initial contents in particles will be lost
void findParticlesForUpdate(const AABox& box, QVector<Particle*> foundParticles);
void findParticlesForUpdate(const AACube& box, QVector<Particle*> foundParticles);
void addNewlyCreatedHook(NewlyCreatedParticleHook* hook);
void removeNewlyCreatedHook(NewlyCreatedParticleHook* hook);
@ -84,7 +84,7 @@ private:
static bool findByIDOperation(OctreeElement* element, void* extraData);
static bool findAndDeleteOperation(OctreeElement* element, void* extraData);
static bool findAndUpdateParticleIDOperation(OctreeElement* element, void* extraData);
static bool findInBoxForUpdateOperation(OctreeElement* element, void* extraData);
static bool findInCubeForUpdateOperation(OctreeElement* element, void* extraData);
void notifyNewlyCreatedParticle(const Particle& newParticle, const SharedNodePointer& senderNode);

View file

@ -78,7 +78,7 @@ void ParticleTreeElement::update(ParticleTreeUpdateArgs& args) {
// If the particle wants to die, or if it's left our bounding box, then move it
// into the arguments moving particles. These will be added back or deleted completely
if (particle.getShouldDie() || !_box.contains(particle.getPosition())) {
if (particle.getShouldDie() || !_cube.contains(particle.getPosition())) {
args._movingParticles.push_back(particle);
// erase this particle
@ -244,18 +244,18 @@ void ParticleTreeElement::getParticles(const glm::vec3& searchPosition, float se
}
}
void ParticleTreeElement::getParticlesForUpdate(const AABox& box, QVector<Particle*>& foundParticles) {
void ParticleTreeElement::getParticlesForUpdate(const AACube& box, QVector<Particle*>& foundParticles) {
QList<Particle>::iterator particleItr = _particles->begin();
QList<Particle>::iterator particleEnd = _particles->end();
AABox particleBox;
AACube particleCube;
while(particleItr != particleEnd) {
Particle* particle = &(*particleItr);
float radius = particle->getRadius();
// NOTE: we actually do box-box collision queries here, which is sloppy but good enough for now
// TODO: decide whether to replace particleBox-box query with sphere-box (requires a square root
// but will be slightly more accurate).
particleBox.setBox(particle->getPosition() - glm::vec3(radius), 2.f * radius);
if (particleBox.touches(_box)) {
particleCube.setBox(particle->getPosition() - glm::vec3(radius), 2.f * radius);
if (particleCube.touches(_cube)) {
foundParticles.push_back(particle);
}
++particleItr;

View file

@ -114,7 +114,7 @@ public:
/// finds all particles that touch a box
/// \param box the query box
/// \param particles[out] vector of non-const Particle*
void getParticlesForUpdate(const AABox& box, QVector<Particle*>& foundParticles);
void getParticlesForUpdate(const AACube& box, QVector<Particle*>& foundParticles);
const Particle* getParticleWithID(uint32_t id) const;

View file

@ -14,7 +14,7 @@
#include <QtScript/QScriptEngine>
#include <AABox.h>
#include <AACube.h>
#include <SharedUtil.h>
#include "VoxelConstants.h"

View file

@ -224,15 +224,15 @@ bool VoxelTreeElement::collapseChildren() {
bool VoxelTreeElement::findSpherePenetration(const glm::vec3& center, float radius,
glm::vec3& penetration, void** penetratedObject) const {
if (_box.findSpherePenetration(center, radius, penetration)) {
if (_cube.findSpherePenetration(center, radius, penetration)) {
// if the caller wants details about the voxel, then return them here...
if (penetratedObject) {
VoxelDetail* voxelDetails = new VoxelDetail;
voxelDetails->x = _box.getCorner().x;
voxelDetails->y = _box.getCorner().y;
voxelDetails->z = _box.getCorner().z;
voxelDetails->s = _box.getScale();
voxelDetails->x = _cube.getCorner().x;
voxelDetails->y = _cube.getCorner().y;
voxelDetails->z = _cube.getCorner().z;
voxelDetails->s = _cube.getScale();
voxelDetails->red = getColor()[RED_INDEX];
voxelDetails->green = getColor()[GREEN_INDEX];
voxelDetails->blue = getColor()[BLUE_INDEX];

View file

@ -18,7 +18,7 @@
#include <QReadWriteLock>
#include <AABox.h>
#include <AACube.h>
#include <OctreeElement.h>
#include <SharedUtil.h>