mirror of
https://github.com/JulianGro/overte.git
synced 2025-05-08 23:19:35 +02:00
93 lines
3.7 KiB
C++
93 lines
3.7 KiB
C++
//
|
|
// AddEntityOperator.cpp
|
|
// libraries/entities/src
|
|
//
|
|
// Created by Brad Hefta-Gaub on 8/11/2014.
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "EntityItem.h"
|
|
#include "EntityTree.h"
|
|
#include "EntityTreeElement.h"
|
|
|
|
#include "AddEntityOperator.h"
|
|
|
|
AddEntityOperator::AddEntityOperator(EntityTreePointer tree, EntityItemPointer newEntity) :
|
|
_tree(tree),
|
|
_newEntity(newEntity),
|
|
_foundNew(false),
|
|
_changeTime(usecTimestampNow()),
|
|
_newEntityBox()
|
|
{
|
|
// caller must have verified existence of newEntity
|
|
assert(_newEntity);
|
|
|
|
bool success;
|
|
auto queryCube = _newEntity->getQueryAACube(success);
|
|
_newEntityBox = queryCube.clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE);
|
|
}
|
|
|
|
bool AddEntityOperator::preRecursion(OctreeElementPointer element) {
|
|
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
|
|
|
// In Pre-recursion, we're generally deciding whether or not we want to recurse this
|
|
// path of the tree. For this operation, we want to recurse the branch of the tree if
|
|
// any of the following are true:
|
|
// * We have not yet found the location for the new entity, and this branch contains the bounds of the new entity
|
|
|
|
bool keepSearching = false; // assume we don't need to search any more
|
|
|
|
// If we haven't yet found the new entity, and this subTreeContains our new
|
|
// entity, then we need to keep searching.
|
|
if (!_foundNew && element->getAACube().contains(_newEntityBox)) {
|
|
|
|
// If this element is the best fit for the new entity properties, then add/or update it
|
|
if (entityTreeElement->bestFitBounds(_newEntityBox)) {
|
|
|
|
entityTreeElement->addEntityItem(_newEntity);
|
|
_tree->setContainingElement(_newEntity->getEntityItemID(), entityTreeElement);
|
|
|
|
_foundNew = true;
|
|
keepSearching = false;
|
|
} else {
|
|
keepSearching = true;
|
|
}
|
|
}
|
|
|
|
return keepSearching; // if we haven't yet found it, keep looking
|
|
}
|
|
|
|
bool AddEntityOperator::postRecursion(OctreeElementPointer element) {
|
|
// Post-recursion is the unwinding process. For this operation, while we
|
|
// unwind we want to mark the path as being dirty if we changed it below.
|
|
// We might have two paths, one for the old entity and one for the new entity.
|
|
bool keepSearching = !_foundNew;
|
|
|
|
// As we unwind, if we're in either of these two paths, we mark our element
|
|
// as dirty.
|
|
if ((_foundNew && element->getAACube().contains(_newEntityBox))) {
|
|
element->markWithChangedTime();
|
|
}
|
|
return keepSearching; // if we haven't yet found it, keep looking
|
|
}
|
|
|
|
OctreeElementPointer AddEntityOperator::possiblyCreateChildAt(OctreeElementPointer element, int childIndex) {
|
|
// If we're getting called, it's because there was no child element at this index while recursing.
|
|
// We only care if this happens while still searching for the new entity location.
|
|
// Check to see if
|
|
if (!_foundNew) {
|
|
float childElementScale = element->getAACube().getScale() / 2.0f; // all of our children will be half our scale
|
|
// if the scale of our desired cube is smaller than our children, then consider making a child
|
|
if (_newEntityBox.getLargestDimension() <= childElementScale) {
|
|
int indexOfChildContainingNewEntity = element->getMyChildContaining(_newEntityBox);
|
|
|
|
if (childIndex == indexOfChildContainingNewEntity) {
|
|
return element->addChildAtIndex(childIndex);
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|