mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 14:03:55 +02:00
when EntityTree::updateEntityWithElement is called on an entity, call it on all the children of that entity
This commit is contained in:
parent
d86d69aeba
commit
7b08d047b1
11 changed files with 213 additions and 105 deletions
|
@ -37,7 +37,7 @@ const glm::vec3 DEFAULT_LOCAL_AABOX_CORNER(-0.5f);
|
|||
const glm::vec3 DEFAULT_LOCAL_AABOX_SCALE(1.0f);
|
||||
|
||||
AvatarData::AvatarData() :
|
||||
_sessionUUID(),
|
||||
SpatiallyNestable(NestableTypes::Avatar, QUuid()),
|
||||
_handPosition(0.0f),
|
||||
_targetScale(1.0f),
|
||||
_handState(0),
|
||||
|
|
|
@ -172,7 +172,7 @@ public:
|
|||
|
||||
virtual bool isMyAvatar() const { return false; }
|
||||
|
||||
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
||||
const QUuid& getSessionUUID() const { return getID(); }
|
||||
|
||||
glm::vec3 getHandPosition() const;
|
||||
void setHandPosition(const glm::vec3& handPosition);
|
||||
|
@ -327,7 +327,7 @@ public slots:
|
|||
|
||||
void setBillboardFromNetworkReply();
|
||||
void setJointMappingsFromNetworkReply();
|
||||
void setSessionUUID(const QUuid& sessionUUID) { _sessionUUID = sessionUUID; }
|
||||
void setSessionUUID(const QUuid& sessionUUID) { setID(sessionUUID); }
|
||||
|
||||
bool isPlaying();
|
||||
bool isPaused();
|
||||
|
@ -353,7 +353,6 @@ public slots:
|
|||
void stopPlaying();
|
||||
|
||||
protected:
|
||||
QUuid _sessionUUID;
|
||||
glm::vec3 _handPosition;
|
||||
|
||||
// Body scale
|
||||
|
|
83
libraries/entities/src/BoundingBoxRelatedProperties.cpp
Normal file
83
libraries/entities/src/BoundingBoxRelatedProperties.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
//
|
||||
// BoundingBoxRelatedProperties.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Seth Alves on 2015-9-24
|
||||
// Copyright 2013 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 "EntityItemProperties.h"
|
||||
#include "BoundingBoxRelatedProperties.h"
|
||||
#include "EntityTree.h"
|
||||
|
||||
BoundingBoxRelatedProperties::BoundingBoxRelatedProperties(EntityItemPointer entity) :
|
||||
position(entity->getPosition()),
|
||||
rotation(entity->getRotation()),
|
||||
registrationPoint(entity->getRegistrationPoint()),
|
||||
dimensions(entity->getDimensions()),
|
||||
parentID(entity->getParentID()) {
|
||||
}
|
||||
|
||||
BoundingBoxRelatedProperties::BoundingBoxRelatedProperties(EntityItemPointer entity,
|
||||
const EntityItemProperties& propertiesWithUpdates) :
|
||||
BoundingBoxRelatedProperties(entity) {
|
||||
|
||||
if (propertiesWithUpdates.parentIDChanged()) {
|
||||
parentID = propertiesWithUpdates.getParentID();
|
||||
}
|
||||
|
||||
bool parentFound = false;
|
||||
if (parentID != UNKNOWN_ENTITY_ID) {
|
||||
EntityTreePointer tree = entity->getTree();
|
||||
EntityItemPointer parentZone = tree->findEntityByID(parentID);
|
||||
if (parentZone) {
|
||||
parentFound = true;
|
||||
glm::vec3 localPosition = propertiesWithUpdates.containsPositionChange() ?
|
||||
propertiesWithUpdates.getPosition() :
|
||||
entity->getLocalPosition();
|
||||
|
||||
glm::quat localRotation = propertiesWithUpdates.rotationChanged() ?
|
||||
propertiesWithUpdates.getRotation() :
|
||||
entity->getLocalOrientation();
|
||||
|
||||
const Transform parentTransform = parentZone->getTransformToCenter();
|
||||
Transform parentDescaled(parentTransform.getRotation(), glm::vec3(1.0f), parentTransform.getTranslation());
|
||||
|
||||
Transform localTransform(localRotation, glm::vec3(1.0f), localPosition);
|
||||
Transform result;
|
||||
Transform::mult(result, parentDescaled, localTransform);
|
||||
position = result.getTranslation();
|
||||
rotation = result.getRotation();
|
||||
}
|
||||
}
|
||||
|
||||
if (!parentFound) {
|
||||
if (propertiesWithUpdates.containsPositionChange()) {
|
||||
position = propertiesWithUpdates.getPosition();
|
||||
}
|
||||
if (propertiesWithUpdates.rotationChanged()) {
|
||||
rotation = propertiesWithUpdates.getRotation();
|
||||
}
|
||||
}
|
||||
|
||||
if (propertiesWithUpdates.registrationPointChanged()) {
|
||||
registrationPoint = propertiesWithUpdates.getRegistrationPoint();
|
||||
}
|
||||
|
||||
if (propertiesWithUpdates.dimensionsChanged()) {
|
||||
dimensions = propertiesWithUpdates.getDimensions();
|
||||
}
|
||||
}
|
||||
|
||||
AACube BoundingBoxRelatedProperties::getMaximumAACube() const {
|
||||
// see EntityItem::getMaximumAACube for comments which explain the following.
|
||||
glm::vec3 scaledRegistrationPoint = (dimensions * registrationPoint);
|
||||
glm::vec3 registrationRemainder = (dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - registrationPoint));
|
||||
glm::vec3 furthestExtentFromRegistration = glm::max(scaledRegistrationPoint, registrationRemainder);
|
||||
float radius = glm::length(furthestExtentFromRegistration);
|
||||
glm::vec3 minimumCorner = position - glm::vec3(radius, radius, radius);
|
||||
return AACube(minimumCorner, radius * 2.0f);
|
||||
}
|
30
libraries/entities/src/BoundingBoxRelatedProperties.h
Normal file
30
libraries/entities/src/BoundingBoxRelatedProperties.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// BoundingBoxRelatedProperties.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Seth Alves on 2015-9-24
|
||||
// Copyright 2013 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"
|
||||
|
||||
#ifndef hifi_BoundingBoxRelatedProperties_h
|
||||
#define hifi_BoundingBoxRelatedProperties_h
|
||||
|
||||
class BoundingBoxRelatedProperties {
|
||||
public:
|
||||
BoundingBoxRelatedProperties(EntityItemPointer entity);
|
||||
BoundingBoxRelatedProperties(EntityItemPointer entity, const EntityItemProperties& propertiesWithUpdates);
|
||||
AACube getMaximumAACube() const;
|
||||
|
||||
glm::vec3 position;
|
||||
glm::quat rotation;
|
||||
glm::vec3 registrationPoint;
|
||||
glm::vec3 dimensions;
|
||||
EntityItemID parentID;
|
||||
};
|
||||
|
||||
#endif // hifi_BoundingBoxRelatedProperties_h
|
|
@ -37,7 +37,7 @@ int EntityItem::_maxActionsDataSize = 800;
|
|||
quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND;
|
||||
|
||||
EntityItem::EntityItem(const EntityItemID& entityItemID) :
|
||||
SpatiallyNestable(entityItemID),
|
||||
SpatiallyNestable(NestableTypes::Entity, entityItemID),
|
||||
_type(EntityTypes::Unknown),
|
||||
_lastSimulated(0),
|
||||
_lastUpdated(0),
|
||||
|
|
|
@ -143,8 +143,11 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
|
|||
if (!wantsLocked) {
|
||||
EntityItemProperties tempProperties;
|
||||
tempProperties.setLocked(wantsLocked);
|
||||
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, tempProperties);
|
||||
|
||||
BoundingBoxRelatedProperties newBBRelProperties(entity, tempProperties);
|
||||
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newBBRelProperties);
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
entity->setProperties(tempProperties);
|
||||
_isDirty = true;
|
||||
}
|
||||
}
|
||||
|
@ -205,8 +208,34 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
|
|||
quint64 entityScriptTimestampBefore = entity->getScriptTimestamp();
|
||||
QString collisionSoundURLBefore = entity->getCollisionSoundURL();
|
||||
uint32_t preFlags = entity->getDirtyFlags();
|
||||
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, properties);
|
||||
|
||||
BoundingBoxRelatedProperties newBBRelProperties(entity, properties);
|
||||
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newBBRelProperties);
|
||||
recurseTreeWithOperator(&theOperator);
|
||||
entity->setProperties(properties);
|
||||
|
||||
// if the entity has children, run UpdateEntityOperator on them. If the children have children, recurse
|
||||
QQueue<SpatiallyNestablePointer> toProcess;
|
||||
foreach (SpatiallyNestablePointer child, entity->getChildren()) {
|
||||
if (child && child->getNestableType() == NestableTypes::Entity) {
|
||||
toProcess.enqueue(child);
|
||||
}
|
||||
}
|
||||
|
||||
while (!toProcess.empty()) {
|
||||
EntityItemPointer childEntity = std::static_pointer_cast<EntityItem>(toProcess.dequeue());
|
||||
BoundingBoxRelatedProperties newChildBBRelProperties(childEntity);
|
||||
UpdateEntityOperator theChildOperator(getThisPointer(),
|
||||
childEntity->getElement(),
|
||||
childEntity, newChildBBRelProperties);
|
||||
recurseTreeWithOperator(&theChildOperator);
|
||||
foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) {
|
||||
if (childChild && childChild->getNestableType() == NestableTypes::Entity) {
|
||||
toProcess.enqueue(childChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_isDirty = true;
|
||||
|
||||
uint32_t newFlags = entity->getDirtyFlags() & ~preFlags;
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include <OctreeRenderer.h> // for RenderArgs
|
||||
|
||||
class EntityItem;
|
||||
typedef std::shared_ptr<EntityItem> EntityItemPointer;
|
||||
typedef std::weak_ptr<EntityItem> EntityItemWeakPointer;
|
||||
using EntityItemPointer = std::shared_ptr<EntityItem>;
|
||||
using EntityItemWeakPointer = std::weak_ptr<EntityItem>;
|
||||
|
||||
inline uint qHash(const EntityItemPointer& a, uint seed) {
|
||||
return qHash(a.get(), seed);
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree,
|
||||
EntityTreeElementPointer containingElement,
|
||||
EntityItemPointer existingEntity,
|
||||
const EntityItemProperties& properties) :
|
||||
const BoundingBoxRelatedProperties& newProperties) :
|
||||
_tree(tree),
|
||||
_existingEntity(existingEntity),
|
||||
_containingElement(containingElement),
|
||||
_containingElementCube(containingElement->getAACube()),
|
||||
_properties(properties),
|
||||
_newProperties(newProperties),
|
||||
_entityItemID(existingEntity->getEntityItemID()),
|
||||
_foundOld(false),
|
||||
_foundNew(false),
|
||||
|
@ -44,83 +44,32 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree,
|
|||
_oldEntityCube = _existingEntity->getMaximumAACube();
|
||||
_oldEntityBox = _oldEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds
|
||||
|
||||
// If the old properties doesn't contain the properties required to calculate a bounding box,
|
||||
// get them from the existing entity. Registration point is required to correctly calculate
|
||||
// the bounding box.
|
||||
if (!_properties.registrationPointChanged()) {
|
||||
_properties.setRegistrationPoint(_existingEntity->getRegistrationPoint());
|
||||
}
|
||||
|
||||
// If the new properties has position OR dimension changes, but not both, we need to
|
||||
// get the old property value and set it in our properties in order for our bounds
|
||||
// calculations to work.
|
||||
if (_properties.containsPositionChange() && !_properties.containsDimensionsChange()) {
|
||||
glm::vec3 oldDimensions= _existingEntity->getDimensions();
|
||||
_properties.setDimensions(oldDimensions);
|
||||
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " ** setting properties dimensions - had position change, no dimension change **";
|
||||
}
|
||||
|
||||
}
|
||||
if (!_properties.containsPositionChange() && _properties.containsDimensionsChange()) {
|
||||
glm::vec3 oldPosition= _existingEntity->getPosition();
|
||||
_properties.setPosition(oldPosition);
|
||||
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " ** setting properties position - had dimensions change, no position change **";
|
||||
}
|
||||
}
|
||||
|
||||
// If our new properties don't have bounds details (no change to position, etc) or if this containing element would
|
||||
// be the best fit for our new properties, then just do the new portion of the store pass, since the change path will
|
||||
// If our new properties don't have bounds details (no change to position, etc) or if this containing element would
|
||||
// be the best fit for our new properties, then just do the new portion of the store pass, since the change path will
|
||||
// be the same for both parts of the update
|
||||
bool oldElementBestFit = _containingElement->bestFitBounds(_properties);
|
||||
|
||||
// if we don't have bounds properties, then use our old clamped box to determine best fit
|
||||
if (!_properties.containsBoundsProperties()) {
|
||||
oldElementBestFit = _containingElement->bestFitBounds(_oldEntityBox);
|
||||
bool oldElementBestFit = _containingElement->bestFitBounds(newProperties.getMaximumAACube());
|
||||
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " ** old Element best fit - no dimensions change, no position change **";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// For some reason we've seen a case where the original containing element isn't a best fit for the old properties
|
||||
// in this case we want to move it, even if the properties haven't changed.
|
||||
if (!_properties.containsBoundsProperties() && !oldElementBestFit) {
|
||||
if (!oldElementBestFit) {
|
||||
_newEntityCube = _oldEntityCube;
|
||||
_removeOld = true; // our properties are going to move us, so remember this for later processing
|
||||
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " **** UNUSUAL CASE **** no changes, but not best fit... consider it a move.... **";
|
||||
}
|
||||
|
||||
|
||||
} else if (!_properties.containsBoundsProperties() || oldElementBestFit) {
|
||||
} else {
|
||||
_foundOld = true;
|
||||
_newEntityCube = _oldEntityCube;
|
||||
_dontMove = true;
|
||||
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " **** TYPICAL NO MOVE CASE ****";
|
||||
qCDebug(entities) << " _properties.containsBoundsProperties():" << _properties.containsBoundsProperties();
|
||||
qCDebug(entities) << " oldElementBestFit:" << oldElementBestFit;
|
||||
}
|
||||
|
||||
} else {
|
||||
_newEntityCube = _properties.getMaximumAACube();
|
||||
_removeOld = true; // our properties are going to move us, so remember this for later processing
|
||||
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " **** TYPICAL MOVE CASE ****";
|
||||
qCDebug(entities) << " **** TYPICAL NO MOVE CASE **** oldElementBestFit:" << oldElementBestFit;
|
||||
}
|
||||
}
|
||||
|
||||
_newEntityBox = _newEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds
|
||||
|
||||
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " _entityItemID:" << _entityItemID;
|
||||
qCDebug(entities) << " _containingElementCube:" << _containingElementCube;
|
||||
|
@ -176,7 +125,7 @@ bool UpdateEntityOperator::subTreeContainsNewEntity(OctreeElementPointer element
|
|||
|
||||
bool UpdateEntityOperator::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
|
||||
// and of the following are true:
|
||||
|
@ -185,7 +134,7 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) {
|
|||
//
|
||||
// Note: it's often the case that the branch in question contains both the old entity
|
||||
// and the new entity.
|
||||
|
||||
|
||||
bool keepSearching = false; // assume we don't need to search any more
|
||||
|
||||
bool subtreeContainsOld = subTreeContainsOldEntity(element);
|
||||
|
@ -257,7 +206,8 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) {
|
|||
qCDebug(entities) << " NEW TREE CASE....";
|
||||
qCDebug(entities) << " entityTreeElement=" << entityTreeElement.get();
|
||||
qCDebug(entities) << " _containingElement=" << _containingElement.get();
|
||||
qCDebug(entities) << " entityTreeElement->bestFitBounds(_newEntityBox)=" << entityTreeElement->bestFitBounds(_newEntityBox);
|
||||
qCDebug(entities) << " entityTreeElement->bestFitBounds(_newEntityBox)="
|
||||
<< entityTreeElement->bestFitBounds(_newEntityBox);
|
||||
}
|
||||
|
||||
// If this element is the best fit for the new entity properties, then add/or update it
|
||||
|
@ -270,16 +220,9 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) {
|
|||
EntityTreeElementPointer oldElement = _existingEntity->getElement();
|
||||
// if we are the existing containing element, then we can just do the update of the entity properties
|
||||
if (entityTreeElement == oldElement) {
|
||||
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " *** This is the same OLD ELEMENT ***";
|
||||
}
|
||||
|
||||
// set the entity properties and mark our element as changed.
|
||||
_existingEntity->setProperties(_properties);
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " *** set properties ***";
|
||||
}
|
||||
} else {
|
||||
// otherwise, this is an add case.
|
||||
if (oldElement) {
|
||||
|
@ -290,11 +233,6 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) {
|
|||
}
|
||||
entityTreeElement->addEntityItem(_existingEntity);
|
||||
_tree->setContainingElement(_entityItemID, entityTreeElement);
|
||||
|
||||
_existingEntity->setProperties(_properties); // still need to update the properties!
|
||||
if (_wantDebug) {
|
||||
qCDebug(entities) << " *** ADDING ENTITY to ELEMENT and MAP and SETTING PROPERTIES ***";
|
||||
}
|
||||
}
|
||||
_foundNew = true; // we found the new element
|
||||
_removeOld = false; // and it has already been removed from the old
|
||||
|
@ -308,7 +246,6 @@ bool UpdateEntityOperator::preRecursion(OctreeElementPointer element) {
|
|||
qCDebug(entities) << "--------------------------------------------------";
|
||||
}
|
||||
|
||||
|
||||
return keepSearching; // if we haven't yet found it, keep looking
|
||||
}
|
||||
|
||||
|
@ -329,9 +266,9 @@ bool UpdateEntityOperator::postRecursion(OctreeElementPointer element) {
|
|||
}
|
||||
|
||||
// It's not OK to prune if we have the potential of deleting the original containig element.
|
||||
// because if we prune the containing element then new might end up reallocating the same memory later
|
||||
// because if we prune the containing element then new might end up reallocating the same memory later
|
||||
// and that will confuse our logic.
|
||||
//
|
||||
//
|
||||
// it's ok to prune if:
|
||||
// 1) we're not removing the old
|
||||
// 2) we are removing the old, but this subtree doesn't contain the old
|
||||
|
@ -340,17 +277,17 @@ bool UpdateEntityOperator::postRecursion(OctreeElementPointer element) {
|
|||
EntityTreeElementPointer entityTreeElement = std::static_pointer_cast<EntityTreeElement>(element);
|
||||
entityTreeElement->pruneChildren(); // take this opportunity to prune any empty leaves
|
||||
}
|
||||
|
||||
|
||||
return keepSearching; // if we haven't yet found it, keep looking
|
||||
}
|
||||
|
||||
OctreeElementPointer UpdateEntityOperator::possiblyCreateChildAt(OctreeElementPointer element, int childIndex) {
|
||||
OctreeElementPointer UpdateEntityOperator::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
|
||||
// Check to see if
|
||||
if (!_foundNew) {
|
||||
float childElementScale = element->getScale() / 2.0f; // all of our children will be half our scale
|
||||
|
||||
|
||||
// Note: because the entity's bounds might have been clamped to the domain. We want to check if the
|
||||
// bounds of the clamped box would fit in our child elements. It may be the case that the actual
|
||||
// bounds of the element would hang outside of the child elements cells.
|
||||
|
@ -365,5 +302,5 @@ OctreeElementPointer UpdateEntityOperator::possiblyCreateChildAt(OctreeElementPo
|
|||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef hifi_UpdateEntityOperator_h
|
||||
#define hifi_UpdateEntityOperator_h
|
||||
|
||||
#include "BoundingBoxRelatedProperties.h"
|
||||
#include "EntitiesLogging.h"
|
||||
#include "EntityItem.h"
|
||||
#include "EntityItemProperties.h"
|
||||
|
@ -21,7 +22,8 @@
|
|||
class UpdateEntityOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
UpdateEntityOperator(EntityTreePointer tree, EntityTreeElementPointer containingElement,
|
||||
EntityItemPointer existingEntity, const EntityItemProperties& properties);
|
||||
EntityItemPointer existingEntity, const BoundingBoxRelatedProperties& newProperties);
|
||||
|
||||
~UpdateEntityOperator();
|
||||
|
||||
virtual bool preRecursion(OctreeElementPointer element);
|
||||
|
@ -32,7 +34,7 @@ private:
|
|||
EntityItemPointer _existingEntity;
|
||||
EntityTreeElementPointer _containingElement;
|
||||
AACube _containingElementCube; // we temporarily store our cube here in case we need to delete the containing element
|
||||
EntityItemProperties _properties;
|
||||
BoundingBoxRelatedProperties _newProperties;
|
||||
EntityItemID _entityItemID;
|
||||
bool _foundOld;
|
||||
bool _foundNew;
|
||||
|
|
|
@ -32,10 +32,13 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
SpatiallyNestableConstPointer constThisPointer = shared_from_this();
|
||||
SpatiallyNestablePointer thisPointer = std::const_pointer_cast<SpatiallyNestable>(constThisPointer); // ermahgerd !!!
|
||||
|
||||
if (parent && parent->getID() == _parentID) {
|
||||
// parent pointer is up-to-date
|
||||
if (!_parentKnowsMe) {
|
||||
parent->beParentOfChild(shared_from_this());
|
||||
parent->beParentOfChild(thisPointer);
|
||||
_parentKnowsMe = true;
|
||||
}
|
||||
return parent;
|
||||
|
@ -43,7 +46,7 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const {
|
|||
|
||||
if (parent) {
|
||||
// we have a parent pointer but our _parentID doesn't indicate this parent.
|
||||
parent->forgetChild(shared_from_this());
|
||||
parent->forgetChild(thisPointer);
|
||||
_parentKnowsMe = false;
|
||||
_parent.reset();
|
||||
}
|
||||
|
@ -53,17 +56,17 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const {
|
|||
_parent = parentFinder->find(_parentID);
|
||||
parent = _parent.lock();
|
||||
if (parent) {
|
||||
parent->beParentOfChild(shared_from_this());
|
||||
parent->beParentOfChild(thisPointer);
|
||||
_parentKnowsMe = true;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
void SpatiallyNestable::beParentOfChild(SpatiallyNestableConstPointer newChild) const {
|
||||
void SpatiallyNestable::beParentOfChild(SpatiallyNestablePointer newChild) const {
|
||||
_children[newChild->getID()] = newChild;
|
||||
}
|
||||
|
||||
void SpatiallyNestable::forgetChild(SpatiallyNestableConstPointer newChild) const {
|
||||
void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const {
|
||||
_children.remove(newChild->getID());
|
||||
}
|
||||
|
||||
|
@ -153,3 +156,14 @@ const glm::vec3& SpatiallyNestable::getLocalScale() const {
|
|||
void SpatiallyNestable::setLocalScale(const glm::vec3& scale) {
|
||||
_transform.setScale(scale);
|
||||
}
|
||||
|
||||
QList<SpatiallyNestablePointer> SpatiallyNestable::getChildren() const {
|
||||
QList<SpatiallyNestablePointer> children;
|
||||
foreach (SpatiallyNestableWeakPointer childWP, _children.values()) {
|
||||
SpatiallyNestablePointer child = childWP.lock();
|
||||
if (child) {
|
||||
children << child;
|
||||
}
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
|
|
@ -24,11 +24,21 @@ using SpatiallyNestableWeakConstPointer = std::weak_ptr<const SpatiallyNestable>
|
|||
using SpatiallyNestablePointer = std::shared_ptr<SpatiallyNestable>;
|
||||
using SpatiallyNestableConstPointer = std::shared_ptr<const SpatiallyNestable>;
|
||||
|
||||
class SpatiallyNestable : public std::enable_shared_from_this<SpatiallyNestable> {
|
||||
|
||||
class NestableTypes {
|
||||
public:
|
||||
SpatiallyNestable() : _transform() { } // XXX get rid of this one?
|
||||
SpatiallyNestable(QUuid id) : _id(id), _transform() { }
|
||||
using NestableType = enum NestableType_t {
|
||||
Entity,
|
||||
Avatar
|
||||
};
|
||||
};
|
||||
|
||||
class SpatiallyNestable : public std::enable_shared_from_this<SpatiallyNestable> {
|
||||
public:
|
||||
// SpatiallyNestable() : _transform() { } // XXX get rid of this one?
|
||||
SpatiallyNestable(NestableTypes::NestableType nestableType, QUuid id) :
|
||||
_nestableType(nestableType),
|
||||
_id(id),
|
||||
_transform() { }
|
||||
virtual ~SpatiallyNestable() { }
|
||||
|
||||
virtual const QUuid& getID() const { return _id; }
|
||||
|
@ -68,16 +78,20 @@ public:
|
|||
virtual const glm::vec3& getLocalScale() const;
|
||||
virtual void setLocalScale(const glm::vec3& scale);
|
||||
|
||||
QList<SpatiallyNestablePointer> getChildren() const;
|
||||
NestableTypes::NestableType getNestableType() const { return _nestableType; }
|
||||
|
||||
protected:
|
||||
NestableTypes::NestableType _nestableType; // EntityItem or an AvatarData
|
||||
QUuid _id;
|
||||
QUuid _parentID; // what is this thing's transform relative to?
|
||||
quint16 _parentJointIndex; // which joint of the parent is this relative to?
|
||||
SpatiallyNestablePointer getParentPointer() const;
|
||||
mutable SpatiallyNestableWeakPointer _parent;
|
||||
|
||||
virtual void beParentOfChild(SpatiallyNestableConstPointer newChild) const;
|
||||
virtual void forgetChild(SpatiallyNestableConstPointer newChild) const;
|
||||
mutable QHash<QUuid, SpatiallyNestableWeakConstPointer> _children;
|
||||
virtual void beParentOfChild(SpatiallyNestablePointer newChild) const;
|
||||
virtual void forgetChild(SpatiallyNestablePointer newChild) const;
|
||||
mutable QHash<QUuid, SpatiallyNestableWeakPointer> _children;
|
||||
|
||||
private:
|
||||
Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform.
|
||||
|
|
Loading…
Reference in a new issue