From 0990229c64b9c9418e9e1120c21f7907cae7fcaf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 11 Aug 2015 18:05:22 -0700 Subject: [PATCH] cache calculation of aabox and aacubes --- libraries/entities/src/EntityItem.cpp | 100 ++++++++++++++------------ libraries/entities/src/EntityItem.h | 23 ++++-- 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 205d1c339e..0ffcc00ead 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1185,74 +1185,84 @@ void EntityItem::setDimensions(const glm::vec3& value) { return; } _transform.setScale(value); + requiresRecalcBoxes(); } /// The maximum bounding cube for the entity, independent of it's rotation. /// This accounts for the registration point (upon which rotation occurs around). /// -AACube EntityItem::getMaximumAACube() const { - // * we know that the position is the center of rotation - glm::vec3 centerOfRotation = getPosition(); // also where _registration point is +const AACube& EntityItem::getMaximumAACube() const { + if (_recalcMaxAACube) { + // * we know that the position is the center of rotation + glm::vec3 centerOfRotation = getPosition(); // also where _registration point is - // * we know that the registration point is the center of rotation - // * we can calculate the length of the furthest extent from the registration point - // as the dimensions * max (registrationPoint, (1.0,1.0,1.0) - registrationPoint) - glm::vec3 registrationPoint = (getDimensions() * getRegistrationPoint()); - glm::vec3 registrationRemainder = (getDimensions() * (glm::vec3(1.0f, 1.0f, 1.0f) - getRegistrationPoint())); - glm::vec3 furthestExtentFromRegistration = glm::max(registrationPoint, registrationRemainder); + // * we know that the registration point is the center of rotation + // * we can calculate the length of the furthest extent from the registration point + // as the dimensions * max (registrationPoint, (1.0,1.0,1.0) - registrationPoint) + glm::vec3 registrationPoint = (getDimensions() * getRegistrationPoint()); + glm::vec3 registrationRemainder = (getDimensions() * (glm::vec3(1.0f, 1.0f, 1.0f) - getRegistrationPoint())); + glm::vec3 furthestExtentFromRegistration = glm::max(registrationPoint, registrationRemainder); - // * we know that if you rotate in any direction you would create a sphere - // that has a radius of the length of furthest extent from registration point - float radius = glm::length(furthestExtentFromRegistration); + // * we know that if you rotate in any direction you would create a sphere + // that has a radius of the length of furthest extent from registration point + float radius = glm::length(furthestExtentFromRegistration); - // * we know that the minimum bounding cube of this maximum possible sphere is - // (center - radius) to (center + radius) - glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius); + // * we know that the minimum bounding cube of this maximum possible sphere is + // (center - radius) to (center + radius) + glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius); - AACube boundingCube(minimumCorner, radius * 2.0f); - return boundingCube; + _maxAACube = AACube(minimumCorner, radius * 2.0f); + _recalcMaxAACube = false; + } + return _maxAACube; } /// The minimum bounding cube for the entity accounting for it's rotation. /// This accounts for the registration point (upon which rotation occurs around). /// -AACube EntityItem::getMinimumAACube() const { - // _position represents the position of the registration point. - glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; +const AACube& EntityItem::getMinimumAACube() const { + if (_recalcMinAACube) { + // _position represents the position of the registration point. + glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; - glm::vec3 unrotatedMinRelativeToEntity = - (getDimensions() * getRegistrationPoint()); - glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder; - Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; - Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); + glm::vec3 unrotatedMinRelativeToEntity = - (getDimensions() * getRegistrationPoint()); + glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder; + Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; + Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); - // shift the extents to be relative to the position/registration point - rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition()); + // shift the extents to be relative to the position/registration point + rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition()); - // the cube that best encompasses extents is... - AABox box(rotatedExtentsRelativeToRegistrationPoint); - glm::vec3 centerOfBox = box.calcCenter(); - float longestSide = box.getLargestDimension(); - float halfLongestSide = longestSide / 2.0f; - glm::vec3 cornerOfCube = centerOfBox - glm::vec3(halfLongestSide, halfLongestSide, halfLongestSide); + // the cube that best encompasses extents is... + AABox box(rotatedExtentsRelativeToRegistrationPoint); + glm::vec3 centerOfBox = box.calcCenter(); + float longestSide = box.getLargestDimension(); + float halfLongestSide = longestSide / 2.0f; + glm::vec3 cornerOfCube = centerOfBox - glm::vec3(halfLongestSide, halfLongestSide, halfLongestSide); - - // old implementation... not correct!!! - return AACube(cornerOfCube, longestSide); + _minAACube = AACube(cornerOfCube, longestSide); + _recalcMinAACube = false; + } + return _minAACube; } -AABox EntityItem::getAABox() const { - // _position represents the position of the registration point. - glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; +const AABox& EntityItem::getAABox() const { + if (_recalcAABox) { + // _position represents the position of the registration point. + glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; - glm::vec3 unrotatedMinRelativeToEntity = - (getDimensions() * _registrationPoint); - glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder; - Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; - Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); + glm::vec3 unrotatedMinRelativeToEntity = - (getDimensions() * _registrationPoint); + glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder; + Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; + Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); - // shift the extents to be relative to the position/registration point - rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition()); + // shift the extents to be relative to the position/registration point + rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition()); - return AABox(rotatedExtentsRelativeToRegistrationPoint); + _cachedAABox = AABox(rotatedExtentsRelativeToRegistrationPoint); + _recalcAABox = false; + } + return _cachedAABox; } // NOTE: This should only be used in cases of old bitstreams which only contain radius data diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 57f8883cea..e420d08709 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -214,14 +214,16 @@ public: void setTranformToCenter(const Transform& transform); inline const Transform& getTransform() const { return _transform; } - inline void setTransform(const Transform& transform) { _transform = transform; } + inline void setTransform(const Transform& transform) { _transform = transform; requiresRecalcBoxes(); } /// Position in meters (0.0 - TREE_SCALE) inline const glm::vec3& getPosition() const { return _transform.getTranslation(); } - inline void setPosition(const glm::vec3& value) { _transform.setTranslation(value); } + inline void setPosition(const glm::vec3& value) { _transform.setTranslation(value); requiresRecalcBoxes(); } inline const glm::quat& getRotation() const { return _transform.getRotation(); } - inline void setRotation(const glm::quat& rotation) { _transform.setRotation(rotation); } + inline void setRotation(const glm::quat& rotation) { _transform.setRotation(rotation); requiresRecalcBoxes(); } + + inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; } // Hyperlink related getters and setters QString getHref() const { return _href; } @@ -286,9 +288,9 @@ public: quint64 getExpiry() const; // position, size, and bounds related helpers - AACube getMaximumAACube() const; - AACube getMinimumAACube() const; - AABox getAABox() const; /// axis aligned bounding box in world-frame (meters) + const AACube& getMaximumAACube() const; + const AACube& getMinimumAACube() const; + const AABox& getAABox() const; /// axis aligned bounding box in world-frame (meters) const QString& getScript() const { return _script; } void setScript(const QString& value) { _script = value; } @@ -303,7 +305,7 @@ public: /// registration point as ratio of entity void setRegistrationPoint(const glm::vec3& value) - { _registrationPoint = glm::clamp(value, 0.0f, 1.0f); } + { _registrationPoint = glm::clamp(value, 0.0f, 1.0f); requiresRecalcBoxes(); } const glm::vec3& getAngularVelocity() const { return _angularVelocity; } void setAngularVelocity(const glm::vec3& value) { _angularVelocity = value; } @@ -434,6 +436,13 @@ protected: quint64 _changedOnServer; Transform _transform; + mutable AABox _cachedAABox; + mutable AACube _maxAACube; + mutable AACube _minAACube; + mutable bool _recalcAABox = true; + mutable bool _recalcMinAACube = true; + mutable bool _recalcMaxAACube = true; + float _glowLevel; float _localRenderAlpha; float _density = ENTITY_ITEM_DEFAULT_DENSITY; // kg/m^3