Merge pull request #5554 from ZappoMan/aaboxOptimization

cache calculation of aabox and aacubes
This commit is contained in:
Howard Stearns 2015-08-12 12:09:33 -07:00
commit 2fbcede9b2
2 changed files with 71 additions and 52 deletions

View file

@ -1185,74 +1185,84 @@ void EntityItem::setDimensions(const glm::vec3& value) {
return; return;
} }
_transform.setScale(value); _transform.setScale(value);
requiresRecalcBoxes();
} }
/// The maximum bounding cube for the entity, independent of it's rotation. /// The maximum bounding cube for the entity, independent of it's rotation.
/// This accounts for the registration point (upon which rotation occurs around). /// This accounts for the registration point (upon which rotation occurs around).
/// ///
AACube EntityItem::getMaximumAACube() const { const AACube& EntityItem::getMaximumAACube() const {
// * we know that the position is the center of rotation if (_recalcMaxAACube) {
glm::vec3 centerOfRotation = getPosition(); // also where _registration point is // * 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 know that the registration point is the center of rotation
// * we can calculate the length of the furthest extent from the registration point // * 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) // as the dimensions * max (registrationPoint, (1.0,1.0,1.0) - registrationPoint)
glm::vec3 registrationPoint = (getDimensions() * getRegistrationPoint()); glm::vec3 registrationPoint = (getDimensions() * getRegistrationPoint());
glm::vec3 registrationRemainder = (getDimensions() * (glm::vec3(1.0f, 1.0f, 1.0f) - getRegistrationPoint())); glm::vec3 registrationRemainder = (getDimensions() * (glm::vec3(1.0f, 1.0f, 1.0f) - getRegistrationPoint()));
glm::vec3 furthestExtentFromRegistration = glm::max(registrationPoint, registrationRemainder); glm::vec3 furthestExtentFromRegistration = glm::max(registrationPoint, registrationRemainder);
// * we know that if you rotate in any direction you would create a sphere // * 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 // that has a radius of the length of furthest extent from registration point
float radius = glm::length(furthestExtentFromRegistration); float radius = glm::length(furthestExtentFromRegistration);
// * we know that the minimum bounding cube of this maximum possible sphere is // * we know that the minimum bounding cube of this maximum possible sphere is
// (center - radius) to (center + radius) // (center - radius) to (center + radius)
glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius); glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius);
AACube boundingCube(minimumCorner, radius * 2.0f); _maxAACube = AACube(minimumCorner, radius * 2.0f);
return boundingCube; _recalcMaxAACube = false;
}
return _maxAACube;
} }
/// The minimum bounding cube for the entity accounting for it's rotation. /// The minimum bounding cube for the entity accounting for it's rotation.
/// This accounts for the registration point (upon which rotation occurs around). /// This accounts for the registration point (upon which rotation occurs around).
/// ///
AACube EntityItem::getMinimumAACube() const { const AACube& EntityItem::getMinimumAACube() const {
// _position represents the position of the registration point. if (_recalcMinAACube) {
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; // _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 unrotatedMinRelativeToEntity = - (getDimensions() * getRegistrationPoint());
glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder; glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder;
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
// shift the extents to be relative to the position/registration point // shift the extents to be relative to the position/registration point
rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition()); rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition());
// the cube that best encompasses extents is... // the cube that best encompasses extents is...
AABox box(rotatedExtentsRelativeToRegistrationPoint); AABox box(rotatedExtentsRelativeToRegistrationPoint);
glm::vec3 centerOfBox = box.calcCenter(); glm::vec3 centerOfBox = box.calcCenter();
float longestSide = box.getLargestDimension(); float longestSide = box.getLargestDimension();
float halfLongestSide = longestSide / 2.0f; float halfLongestSide = longestSide / 2.0f;
glm::vec3 cornerOfCube = centerOfBox - glm::vec3(halfLongestSide, halfLongestSide, halfLongestSide); glm::vec3 cornerOfCube = centerOfBox - glm::vec3(halfLongestSide, halfLongestSide, halfLongestSide);
_minAACube = AACube(cornerOfCube, longestSide);
// old implementation... not correct!!! _recalcMinAACube = false;
return AACube(cornerOfCube, longestSide); }
return _minAACube;
} }
AABox EntityItem::getAABox() const { const AABox& EntityItem::getAABox() const {
// _position represents the position of the registration point. if (_recalcAABox) {
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint; // _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 unrotatedMinRelativeToEntity = - (getDimensions() * _registrationPoint);
glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder; glm::vec3 unrotatedMaxRelativeToEntity = getDimensions() * registrationRemainder;
Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; Extents unrotatedExtentsRelativeToRegistrationPoint = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation()); Extents rotatedExtentsRelativeToRegistrationPoint = unrotatedExtentsRelativeToRegistrationPoint.getRotated(getRotation());
// shift the extents to be relative to the position/registration point // shift the extents to be relative to the position/registration point
rotatedExtentsRelativeToRegistrationPoint.shiftBy(getPosition()); 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 // NOTE: This should only be used in cases of old bitstreams which only contain radius data

View file

@ -214,14 +214,16 @@ public:
void setTranformToCenter(const Transform& transform); void setTranformToCenter(const Transform& transform);
inline const Transform& getTransform() const { return _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) /// Position in meters (0.0 - TREE_SCALE)
inline const glm::vec3& getPosition() const { return _transform.getTranslation(); } 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 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 // Hyperlink related getters and setters
QString getHref() const { return _href; } QString getHref() const { return _href; }
@ -286,9 +288,9 @@ public:
quint64 getExpiry() const; quint64 getExpiry() const;
// position, size, and bounds related helpers // position, size, and bounds related helpers
AACube getMaximumAACube() const; const AACube& getMaximumAACube() const;
AACube getMinimumAACube() const; const AACube& getMinimumAACube() const;
AABox getAABox() const; /// axis aligned bounding box in world-frame (meters) const AABox& getAABox() const; /// axis aligned bounding box in world-frame (meters)
const QString& getScript() const { return _script; } const QString& getScript() const { return _script; }
void setScript(const QString& value) { _script = value; } void setScript(const QString& value) { _script = value; }
@ -303,7 +305,7 @@ public:
/// registration point as ratio of entity /// registration point as ratio of entity
void setRegistrationPoint(const glm::vec3& value) 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; } const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
void setAngularVelocity(const glm::vec3& value) { _angularVelocity = value; } void setAngularVelocity(const glm::vec3& value) { _angularVelocity = value; }
@ -434,6 +436,13 @@ protected:
quint64 _changedOnServer; quint64 _changedOnServer;
Transform _transform; 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 _glowLevel;
float _localRenderAlpha; float _localRenderAlpha;
float _density = ENTITY_ITEM_DEFAULT_DENSITY; // kg/m^3 float _density = ENTITY_ITEM_DEFAULT_DENSITY; // kg/m^3