mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-11 05:23:08 +02:00
renaming of AABox to AACube, introduction of actual AABox
This commit is contained in:
parent
9188b9ac59
commit
39ed7f7b65
26 changed files with 384 additions and 257 deletions
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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?
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include <AABox.h>
|
||||
#include <AACube.h>
|
||||
#include <SharedUtil.h>
|
||||
#include "VoxelConstants.h"
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include <QReadWriteLock>
|
||||
|
||||
#include <AABox.h>
|
||||
#include <AACube.h>
|
||||
#include <OctreeElement.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
|
Loading…
Reference in a new issue