mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 06:18:52 +02:00
location getters also return a success boolean so that callers can know if the value they are receiving is bad due to lack of information about an object's parent
This commit is contained in:
parent
270d5fc8e1
commit
c74f8bca49
27 changed files with 506 additions and 202 deletions
|
@ -11,9 +11,14 @@
|
||||||
|
|
||||||
#include "AssignmentParentFinder.h"
|
#include "AssignmentParentFinder.h"
|
||||||
|
|
||||||
SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID) const {
|
SpatiallyNestableWeakPointer AssignmentParentFinder::find(QUuid parentID, bool& success) const {
|
||||||
SpatiallyNestableWeakPointer parent;
|
SpatiallyNestableWeakPointer parent;
|
||||||
// search entities
|
// search entities
|
||||||
parent = _tree->findEntityByEntityItemID(parentID);
|
parent = _tree->findEntityByEntityItemID(parentID);
|
||||||
|
if (parent.lock()) {
|
||||||
|
success = true;
|
||||||
|
} else {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ class AssignmentParentFinder : public SpatialParentFinder {
|
||||||
public:
|
public:
|
||||||
AssignmentParentFinder(EntityTreePointer tree) : _tree(tree) { }
|
AssignmentParentFinder(EntityTreePointer tree) : _tree(tree) { }
|
||||||
virtual ~AssignmentParentFinder() { }
|
virtual ~AssignmentParentFinder() { }
|
||||||
virtual SpatiallyNestableWeakPointer find(QUuid parentID) const;
|
virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EntityTreePointer _tree;
|
EntityTreePointer _tree;
|
||||||
|
|
|
@ -21,7 +21,7 @@ class InterfaceParentFinder : public SpatialParentFinder {
|
||||||
public:
|
public:
|
||||||
InterfaceParentFinder() { }
|
InterfaceParentFinder() { }
|
||||||
virtual ~InterfaceParentFinder() { }
|
virtual ~InterfaceParentFinder() { }
|
||||||
virtual SpatiallyNestableWeakPointer find(QUuid parentID) const;
|
virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_InterfaceParentFinder_h
|
#endif // hifi_InterfaceParentFinder_h
|
||||||
|
|
|
@ -158,7 +158,9 @@ public:
|
||||||
void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; }
|
void setMotionState(AvatarMotionState* motionState) { _motionState = motionState; }
|
||||||
AvatarMotionState* getMotionState() { return _motionState; }
|
AvatarMotionState* getMotionState() { return _motionState; }
|
||||||
|
|
||||||
|
using SpatiallyNestable::setPosition;
|
||||||
virtual void setPosition(const glm::vec3& position) override;
|
virtual void setPosition(const glm::vec3& position) override;
|
||||||
|
using SpatiallyNestable::setOrientation;
|
||||||
virtual void setOrientation(const glm::quat& orientation) override;
|
virtual void setOrientation(const glm::quat& orientation) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -93,7 +93,11 @@ void AvatarData::nextAttitude(glm::vec3 position, glm::quat orientation) {
|
||||||
Transform trans;
|
Transform trans;
|
||||||
trans.setTranslation(position);
|
trans.setTranslation(position);
|
||||||
trans.setRotation(orientation);
|
trans.setRotation(orientation);
|
||||||
SpatiallyNestable::setTransform(trans);
|
bool success;
|
||||||
|
SpatiallyNestable::setTransform(trans, success);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "Warning -- AvatarData::nextAttitude failed";
|
||||||
|
}
|
||||||
avatarLock.unlock();
|
avatarLock.unlock();
|
||||||
updateAttitude();
|
updateAttitude();
|
||||||
}
|
}
|
||||||
|
@ -211,8 +215,9 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||||
setAtBit(bitItems, IS_EYE_TRACKER_CONNECTED);
|
setAtBit(bitItems, IS_EYE_TRACKER_CONNECTED);
|
||||||
}
|
}
|
||||||
// referential state
|
// referential state
|
||||||
SpatiallyNestablePointer parent = getParentPointer();
|
bool success;
|
||||||
if (parent) {
|
SpatiallyNestablePointer parent = getParentPointer(success);
|
||||||
|
if (parent && success) {
|
||||||
setAtBit(bitItems, HAS_REFERENTIAL);
|
setAtBit(bitItems, HAS_REFERENTIAL);
|
||||||
}
|
}
|
||||||
*destinationBuffer++ = bitItems;
|
*destinationBuffer++ = bitItems;
|
||||||
|
@ -1443,7 +1448,11 @@ QJsonObject AvatarData::toJson() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto recordingBasis = getRecordingBasis();
|
auto recordingBasis = getRecordingBasis();
|
||||||
Transform avatarTransform = getTransform();
|
bool success;
|
||||||
|
Transform avatarTransform = getTransform(success);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "Warning -- AvatarData::toJson couldn't get avatar transform";
|
||||||
|
}
|
||||||
avatarTransform.setScale(getTargetScale());
|
avatarTransform.setScale(getTargetScale());
|
||||||
if (recordingBasis) {
|
if (recordingBasis) {
|
||||||
root[JSON_AVATAR_BASIS] = Transform::toJson(*recordingBasis);
|
root[JSON_AVATAR_BASIS] = Transform::toJson(*recordingBasis);
|
||||||
|
|
|
@ -201,7 +201,9 @@ public:
|
||||||
float getBodyRoll() const;
|
float getBodyRoll() const;
|
||||||
void setBodyRoll(float bodyRoll);
|
void setBodyRoll(float bodyRoll);
|
||||||
|
|
||||||
|
using SpatiallyNestable::setPosition;
|
||||||
virtual void setPosition(const glm::vec3& position) override;
|
virtual void setPosition(const glm::vec3& position) override;
|
||||||
|
using SpatiallyNestable::setOrientation;
|
||||||
virtual void setOrientation(const glm::quat& orientation) override;
|
virtual void setOrientation(const glm::quat& orientation) override;
|
||||||
|
|
||||||
void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time.
|
void nextAttitude(glm::vec3 position, glm::quat orientation); // Can be safely called at any time.
|
||||||
|
|
|
@ -761,7 +761,12 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT
|
||||||
|
|
||||||
// Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2)
|
// Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2)
|
||||||
const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f;
|
const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f;
|
||||||
const float stretchFactor = log(1.0f + (entity->getMinimumAACube().getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2);
|
bool success;
|
||||||
|
auto minAACube = entity->getMinimumAACube(success);
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const float stretchFactor = log(1.0f + (minAACube.getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2);
|
||||||
AudioInjector::playSound(collisionSoundURL, volume, stretchFactor, position);
|
AudioInjector::playSound(collisionSoundURL, volume, stretchFactor, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,14 +56,20 @@ void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());
|
glm::vec4 cubeColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||||
|
|
||||||
|
bool success;
|
||||||
|
auto transToCenter = getTransformToCenter(success);
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_procedural->ready()) {
|
if (_procedural->ready()) {
|
||||||
batch.setModelTransform(getTransformToCenter()); // we want to include the scale as well
|
batch.setModelTransform(transToCenter); // we want to include the scale as well
|
||||||
_procedural->prepare(batch, getPosition(), getDimensions());
|
_procedural->prepare(batch, getPosition(), getDimensions());
|
||||||
auto color = _procedural->getColor(cubeColor);
|
auto color = _procedural->getColor(cubeColor);
|
||||||
batch._glColor4f(color.r, color.g, color.b, color.a);
|
batch._glColor4f(color.r, color.g, color.b, color.a);
|
||||||
DependencyManager::get<GeometryCache>()->renderCube(batch);
|
DependencyManager::get<GeometryCache>()->renderCube(batch);
|
||||||
} else {
|
} else {
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidCubeInstance(batch, getTransformToCenter(), cubeColor);
|
DependencyManager::get<DeferredLightingEffect>()->renderSolidCubeInstance(batch, transToCenter, cubeColor);
|
||||||
}
|
}
|
||||||
static const auto triCount = DependencyManager::get<GeometryCache>()->getCubeTriangleCount();
|
static const auto triCount = DependencyManager::get<GeometryCache>()->getCubeTriangleCount();
|
||||||
args->_details._trianglesRendered += triCount;
|
args->_details._trianglesRendered += triCount;
|
||||||
|
|
|
@ -28,7 +28,12 @@ namespace render {
|
||||||
|
|
||||||
template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload) {
|
template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload) {
|
||||||
if (payload && payload->entity) {
|
if (payload && payload->entity) {
|
||||||
return payload->entity->getAABox();
|
bool success;
|
||||||
|
auto result = payload->entity->getAABox(success);
|
||||||
|
if (!success) {
|
||||||
|
return render::Item::Bound();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return render::Item::Bound();
|
return render::Item::Bound();
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,12 @@ namespace render {
|
||||||
|
|
||||||
template <> const Item::Bound payloadGetBound(const RenderableModelEntityItemMeta::Pointer& payload) {
|
template <> const Item::Bound payloadGetBound(const RenderableModelEntityItemMeta::Pointer& payload) {
|
||||||
if (payload && payload->entity) {
|
if (payload && payload->entity) {
|
||||||
return payload->entity->getAABox();
|
bool success;
|
||||||
|
auto result = payload->entity->getAABox(success);
|
||||||
|
if (!success) {
|
||||||
|
return render::Item::Bound();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return render::Item::Bound();
|
return render::Item::Bound();
|
||||||
}
|
}
|
||||||
|
@ -338,10 +343,13 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
} else {
|
} else {
|
||||||
static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
auto shapeTransform = getTransformToCenter();
|
bool success;
|
||||||
|
auto shapeTransform = getTransformToCenter(success);
|
||||||
|
if (success) {
|
||||||
batch.setModelTransform(Transform()); // we want to include the scale as well
|
batch.setModelTransform(Transform()); // we want to include the scale as well
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderWireCubeInstance(batch, shapeTransform, greenColor);
|
DependencyManager::get<DeferredLightingEffect>()->renderWireCubeInstance(batch, shapeTransform, greenColor);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) {
|
Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) {
|
||||||
|
|
|
@ -236,9 +236,14 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
|
||||||
particlePrimitives->emplace_back(particle.position, glm::vec2(particle.lifetime, particle.seed));
|
particlePrimitives->emplace_back(particle.position, glm::vec2(particle.lifetime, particle.seed));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bounds = getAABox();
|
bool successb, successp, successr;
|
||||||
auto position = getPosition();
|
auto bounds = getAABox(successb);
|
||||||
auto rotation = getRotation();
|
auto position = getPosition(successp);
|
||||||
|
auto rotation = getOrientation(successr);
|
||||||
|
bool success = successb && successp && successr;
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Transform transform;
|
Transform transform;
|
||||||
transform.setTranslation(position);
|
transform.setTranslation(position);
|
||||||
transform.setRotation(rotation);
|
transform.setRotation(rotation);
|
||||||
|
|
|
@ -135,9 +135,11 @@ glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const {
|
||||||
|
|
||||||
glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const {
|
glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const {
|
||||||
glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units
|
glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units
|
||||||
glm::vec3 center = getCenterPosition();
|
bool success; // XXX Does this actually have to happen in world space?
|
||||||
glm::vec3 position = getPosition();
|
glm::vec3 center = getCenterPosition(success);
|
||||||
|
glm::vec3 position = getPosition(success);
|
||||||
glm::vec3 positionToCenter = center - position;
|
glm::vec3 positionToCenter = center - position;
|
||||||
|
|
||||||
positionToCenter -= getDimensions() * Vectors::HALF - getSurfacePositionAdjustment();
|
positionToCenter -= getDimensions() * Vectors::HALF - getSurfacePositionAdjustment();
|
||||||
glm::mat4 centerToCorner = glm::translate(glm::mat4(), positionToCenter);
|
glm::mat4 centerToCorner = glm::translate(glm::mat4(), positionToCenter);
|
||||||
glm::mat4 scaled = glm::scale(centerToCorner, scale);
|
glm::mat4 scaled = glm::scale(centerToCorner, scale);
|
||||||
|
@ -574,7 +576,12 @@ namespace render {
|
||||||
template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload) {
|
template <> const Item::Bound payloadGetBound(const PolyVoxPayload::Pointer& payload) {
|
||||||
if (payload && payload->_owner) {
|
if (payload && payload->_owner) {
|
||||||
auto polyVoxEntity = std::dynamic_pointer_cast<RenderablePolyVoxEntityItem>(payload->_owner);
|
auto polyVoxEntity = std::dynamic_pointer_cast<RenderablePolyVoxEntityItem>(payload->_owner);
|
||||||
return polyVoxEntity->getAABox();
|
bool success;
|
||||||
|
auto result = polyVoxEntity->getAABox(success);
|
||||||
|
if (!success) {
|
||||||
|
return render::Item::Bound();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return render::Item::Bound();
|
return render::Item::Bound();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,11 @@ void RenderableSphereEntityItem::render(RenderArgs* args) {
|
||||||
|
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
glm::vec4 sphereColor(toGlm(getXColor()), getLocalRenderAlpha());
|
glm::vec4 sphereColor(toGlm(getXColor()), getLocalRenderAlpha());
|
||||||
Transform modelTransform = getTransformToCenter();
|
bool success;
|
||||||
|
Transform modelTransform = getTransformToCenter(success);
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
modelTransform.postScale(SPHERE_ENTITY_SCALE);
|
modelTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||||
if (_procedural->ready()) {
|
if (_procedural->ready()) {
|
||||||
batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation
|
batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation
|
||||||
|
|
|
@ -45,7 +45,11 @@ void RenderableTextEntityItem::render(RenderArgs* args) {
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
|
|
||||||
Transform transformToTopLeft = getTransformToCenter();
|
bool success;
|
||||||
|
Transform transformToTopLeft = getTransformToCenter(success);
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (getFaceCamera()) {
|
if (getFaceCamera()) {
|
||||||
//rotate about vertical to face the camera
|
//rotate about vertical to face the camera
|
||||||
glm::vec3 dPosition = args->_viewFrustum->getPosition() - getPosition();
|
glm::vec3 dPosition = args->_viewFrustum->getPosition() - getPosition();
|
||||||
|
|
|
@ -185,7 +185,11 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
|
||||||
|
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
batch.setModelTransform(getTransformToCenter());
|
bool success;
|
||||||
|
batch.setModelTransform(getTransformToCenter(success));
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
bool textured = false, culled = false, emissive = false;
|
bool textured = false, culled = false, emissive = false;
|
||||||
if (_texture) {
|
if (_texture) {
|
||||||
batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture);
|
batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture);
|
||||||
|
|
|
@ -135,7 +135,11 @@ void RenderableZoneEntityItem::render(RenderArgs* args) {
|
||||||
gpu::Batch& batch = *args->_batch;
|
gpu::Batch& batch = *args->_batch;
|
||||||
batch.setModelTransform(Transform());
|
batch.setModelTransform(Transform());
|
||||||
|
|
||||||
auto shapeTransform = getTransformToCenter();
|
bool success;
|
||||||
|
auto shapeTransform = getTransformToCenter(success);
|
||||||
|
if (!success) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||||
if (getShapeType() == SHAPE_TYPE_SPHERE) {
|
if (getShapeType() == SHAPE_TYPE_SPHERE) {
|
||||||
shapeTransform.postScale(SPHERE_ENTITY_SCALE);
|
shapeTransform.postScale(SPHERE_ENTITY_SCALE);
|
||||||
|
@ -190,7 +194,12 @@ namespace render {
|
||||||
|
|
||||||
template <> const Item::Bound payloadGetBound(const RenderableZoneEntityItemMeta::Pointer& payload) {
|
template <> const Item::Bound payloadGetBound(const RenderableZoneEntityItemMeta::Pointer& payload) {
|
||||||
if (payload && payload->entity) {
|
if (payload && payload->entity) {
|
||||||
return payload->entity->getAABox();
|
bool success;
|
||||||
|
auto result = payload->entity->getAABox(success);
|
||||||
|
if (!success) {
|
||||||
|
return render::Item::Bound();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return render::Item::Bound();
|
return render::Item::Bound();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,14 @@ AddEntityOperator::AddEntityOperator(EntityTreePointer tree, EntityItemPointer n
|
||||||
// caller must have verified existence of newEntity
|
// caller must have verified existence of newEntity
|
||||||
assert(_newEntity);
|
assert(_newEntity);
|
||||||
|
|
||||||
_newEntityBox = _newEntity->getQueryAACube().clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE);
|
bool success;
|
||||||
|
auto queryCube = _newEntity->getQueryAACube(success);
|
||||||
|
if (!success) {
|
||||||
|
// XXX put on a list for reprocessing?
|
||||||
|
qDebug() << "Warning -- AddEntityOperator failed to get queryAACube:" << _newEntity->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
_newEntityBox = queryCube.clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AddEntityOperator::preRecursion(OctreeElementPointer element) {
|
bool AddEntityOperator::preRecursion(OctreeElementPointer element) {
|
||||||
|
|
|
@ -1156,8 +1156,8 @@ void EntityItem::recordCreationTime() {
|
||||||
_lastSimulated = now;
|
_lastSimulated = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Transform EntityItem::getTransformToCenter() const {
|
const Transform EntityItem::getTransformToCenter(bool& success) const {
|
||||||
Transform result = getTransform();
|
Transform result = getTransform(success);
|
||||||
if (getRegistrationPoint() != ENTITY_ITEM_HALF_VEC3) { // If it is not already centered, translate to center
|
if (getRegistrationPoint() != ENTITY_ITEM_HALF_VEC3) { // If it is not already centered, translate to center
|
||||||
result.postTranslate(ENTITY_ITEM_HALF_VEC3 - getRegistrationPoint()); // Position to center
|
result.postTranslate(ENTITY_ITEM_HALF_VEC3 - getRegistrationPoint()); // Position to center
|
||||||
}
|
}
|
||||||
|
@ -1175,11 +1175,11 @@ void EntityItem::setDimensions(const glm::vec3& value) {
|
||||||
/// 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).
|
||||||
///
|
///
|
||||||
const AACube& EntityItem::getMaximumAACube() const {
|
const AACube& EntityItem::getMaximumAACube(bool& success) const {
|
||||||
if (_recalcMaxAACube) {
|
if (_recalcMaxAACube) {
|
||||||
// * we know that the position is the center of rotation
|
// * we know that the position is the center of rotation
|
||||||
glm::vec3 centerOfRotation = getPosition(); // also where _registration point is
|
glm::vec3 centerOfRotation = getPosition(success); // also where _registration point is
|
||||||
|
if (success) {
|
||||||
// * 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)
|
||||||
|
@ -1198,13 +1198,14 @@ const AACube& EntityItem::getMaximumAACube() const {
|
||||||
_maxAACube = AACube(minimumCorner, radius * 2.0f);
|
_maxAACube = AACube(minimumCorner, radius * 2.0f);
|
||||||
_recalcMaxAACube = false;
|
_recalcMaxAACube = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return _maxAACube;
|
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).
|
||||||
///
|
///
|
||||||
const AACube& EntityItem::getMinimumAACube() const {
|
const AACube& EntityItem::getMinimumAACube(bool& success) const {
|
||||||
if (_recalcMinAACube) {
|
if (_recalcMinAACube) {
|
||||||
// _position represents the position of the registration point.
|
// _position represents the position of the registration point.
|
||||||
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
||||||
|
@ -1212,11 +1213,13 @@ const AACube& EntityItem::getMinimumAACube() const {
|
||||||
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(success));
|
||||||
|
|
||||||
|
if (success) {
|
||||||
// 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();
|
||||||
|
@ -1227,10 +1230,11 @@ const AACube& EntityItem::getMinimumAACube() const {
|
||||||
_minAACube = AACube(cornerOfCube, longestSide);
|
_minAACube = AACube(cornerOfCube, longestSide);
|
||||||
_recalcMinAACube = false;
|
_recalcMinAACube = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return _minAACube;
|
return _minAACube;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AABox& EntityItem::getAABox() const {
|
const AABox& EntityItem::getAABox(bool& success) const {
|
||||||
if (_recalcAABox) {
|
if (_recalcAABox) {
|
||||||
// _position represents the position of the registration point.
|
// _position represents the position of the registration point.
|
||||||
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
glm::vec3 registrationRemainder = glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint;
|
||||||
|
@ -1238,24 +1242,26 @@ const AABox& EntityItem::getAABox() const {
|
||||||
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(success));
|
||||||
|
|
||||||
|
if (success) {
|
||||||
_cachedAABox = AABox(rotatedExtentsRelativeToRegistrationPoint);
|
_cachedAABox = AABox(rotatedExtentsRelativeToRegistrationPoint);
|
||||||
_recalcAABox = false;
|
_recalcAABox = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return _cachedAABox;
|
return _cachedAABox;
|
||||||
}
|
}
|
||||||
|
|
||||||
AACube EntityItem::getQueryAACube() const {
|
AACube EntityItem::getQueryAACube(bool& success) const {
|
||||||
// XXX
|
AACube result = getMaximumAACube(success);
|
||||||
if (!_queryAACubeSet) {
|
if (success) {
|
||||||
_queryAACube = getMaximumAACube();
|
return result;
|
||||||
_queryAACubeSet = true;
|
|
||||||
}
|
}
|
||||||
return SpatiallyNestable::getQueryAACube();
|
return SpatiallyNestable::getQueryAACube(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1288,7 +1294,9 @@ float EntityItem::getRadius() const {
|
||||||
|
|
||||||
bool EntityItem::contains(const glm::vec3& point) const {
|
bool EntityItem::contains(const glm::vec3& point) const {
|
||||||
if (getShapeType() == SHAPE_TYPE_COMPOUND) {
|
if (getShapeType() == SHAPE_TYPE_COMPOUND) {
|
||||||
return getAABox().contains(point);
|
bool success;
|
||||||
|
bool result = getAABox(success).contains(point);
|
||||||
|
return result & success;
|
||||||
} else {
|
} else {
|
||||||
ShapeInfo info;
|
ShapeInfo info;
|
||||||
info.setParams(getShapeType(), glm::vec3(0.5f));
|
info.setParams(getShapeType(), glm::vec3(0.5f));
|
||||||
|
@ -1831,6 +1839,14 @@ QList<EntityActionPointer> EntityItem::getActionsOfType(EntityActionType typeToG
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::quat EntityItem::getAbsoluteJointRotationInObjectFrame(int index) const {
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 EntityItem::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
||||||
|
return glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
void EntityItem::locationChanged() {
|
void EntityItem::locationChanged() {
|
||||||
requiresRecalcBoxes();
|
requiresRecalcBoxes();
|
||||||
SpatiallyNestable::locationChanged(); // tell all the children, also
|
SpatiallyNestable::locationChanged(); // tell all the children, also
|
||||||
|
|
|
@ -161,11 +161,10 @@ public:
|
||||||
// attributes applicable to all entity types
|
// attributes applicable to all entity types
|
||||||
EntityTypes::EntityType getType() const { return _type; }
|
EntityTypes::EntityType getType() const { return _type; }
|
||||||
|
|
||||||
inline glm::vec3 getCenterPosition() const { return getTransformToCenter().getTranslation(); }
|
inline glm::vec3 getCenterPosition(bool& success) const { return getTransformToCenter(success).getTranslation(); }
|
||||||
void setCenterPosition(const glm::vec3& position);
|
void setCenterPosition(const glm::vec3& position);
|
||||||
|
|
||||||
const Transform getTransformToCenter() const;
|
const Transform getTransformToCenter(bool& success) const;
|
||||||
void setTranformToCenter(const Transform& transform);
|
|
||||||
|
|
||||||
inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; }
|
inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; }
|
||||||
|
|
||||||
|
@ -232,11 +231,12 @@ public:
|
||||||
quint64 getExpiry() const;
|
quint64 getExpiry() const;
|
||||||
|
|
||||||
// position, size, and bounds related helpers
|
// position, size, and bounds related helpers
|
||||||
const AACube& getMaximumAACube() const;
|
const AACube& getMaximumAACube(bool& success) const;
|
||||||
const AACube& getMinimumAACube() const;
|
const AACube& getMinimumAACube(bool& success) const;
|
||||||
const AABox& getAABox() const; /// axis aligned bounding box in world-frame (meters)
|
const AABox& getAABox(bool& success) const; /// axis aligned bounding box in world-frame (meters)
|
||||||
|
|
||||||
virtual AACube getQueryAACube() const;
|
using SpatiallyNestable::getQueryAACube;
|
||||||
|
virtual AACube getQueryAACube(bool& success) const override;
|
||||||
|
|
||||||
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; }
|
||||||
|
@ -381,8 +381,8 @@ public:
|
||||||
QList<EntityActionPointer> getActionsOfType(EntityActionType typeToGet);
|
QList<EntityActionPointer> getActionsOfType(EntityActionType typeToGet);
|
||||||
|
|
||||||
// these are in the frame of this object
|
// these are in the frame of this object
|
||||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override { return glm::quat(); }
|
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
|
||||||
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override { return glm::vec3(0.0f); }
|
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override;
|
||||||
|
|
||||||
virtual void loader() {} // called indirectly when urls for geometry are updated
|
virtual void loader() {} // called indirectly when urls for geometry are updated
|
||||||
|
|
||||||
|
|
|
@ -72,12 +72,15 @@ EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties
|
||||||
scriptSideProperties.setLocalPosition(entitySideProperties.getPosition());
|
scriptSideProperties.setLocalPosition(entitySideProperties.getPosition());
|
||||||
scriptSideProperties.setLocalRotation(entitySideProperties.getRotation());
|
scriptSideProperties.setLocalRotation(entitySideProperties.getRotation());
|
||||||
|
|
||||||
|
bool success;
|
||||||
glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(),
|
glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex());
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
success);
|
||||||
glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(),
|
glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex());
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
success);
|
||||||
scriptSideProperties.setPosition(worldPosition);
|
scriptSideProperties.setPosition(worldPosition);
|
||||||
scriptSideProperties.setRotation(worldRotation);
|
scriptSideProperties.setRotation(worldRotation);
|
||||||
|
|
||||||
|
@ -89,13 +92,15 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
|
||||||
// convert position and rotation properties from world-space to local, unless localPosition and localRotation
|
// convert position and rotation properties from world-space to local, unless localPosition and localRotation
|
||||||
// are set. If they are set, they overwrite position and rotation.
|
// are set. If they are set, they overwrite position and rotation.
|
||||||
EntityItemProperties entitySideProperties = scriptSideProperties;
|
EntityItemProperties entitySideProperties = scriptSideProperties;
|
||||||
|
bool success;
|
||||||
|
|
||||||
if (scriptSideProperties.localPositionChanged()) {
|
if (scriptSideProperties.localPositionChanged()) {
|
||||||
entitySideProperties.setPosition(scriptSideProperties.getLocalPosition());
|
entitySideProperties.setPosition(scriptSideProperties.getLocalPosition());
|
||||||
} else if (scriptSideProperties.positionChanged()) {
|
} else if (scriptSideProperties.positionChanged()) {
|
||||||
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(),
|
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex());
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
success);
|
||||||
entitySideProperties.setPosition(localPosition);
|
entitySideProperties.setPosition(localPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +109,8 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
|
||||||
} else if (scriptSideProperties.rotationChanged()) {
|
} else if (scriptSideProperties.rotationChanged()) {
|
||||||
glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(),
|
glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(),
|
||||||
entitySideProperties.getParentID(),
|
entitySideProperties.getParentID(),
|
||||||
entitySideProperties.getParentJointIndex());
|
entitySideProperties.getParentJointIndex(),
|
||||||
|
success);
|
||||||
entitySideProperties.setRotation(localRotation);
|
entitySideProperties.setRotation(localRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,8 +119,9 @@ void EntitySimulation::sortEntitiesThatMoved() {
|
||||||
while (itemItr != _entitiesToSort.end()) {
|
while (itemItr != _entitiesToSort.end()) {
|
||||||
EntityItemPointer entity = *itemItr;
|
EntityItemPointer entity = *itemItr;
|
||||||
// check to see if this movement has sent the entity outside of the domain.
|
// check to see if this movement has sent the entity outside of the domain.
|
||||||
AACube newCube = entity->getQueryAACube();
|
bool success;
|
||||||
if (!domainBounds.touches(newCube)) {
|
AACube newCube = entity->getQueryAACube(success);
|
||||||
|
if (success && !domainBounds.touches(newCube)) {
|
||||||
qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
|
qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
|
||||||
_entitiesToDelete.insert(entity);
|
_entitiesToDelete.insert(entity);
|
||||||
_mortalEntities.remove(entity);
|
_mortalEntities.remove(entity);
|
||||||
|
@ -200,8 +201,9 @@ void EntitySimulation::changeEntity(EntityItemPointer entity) {
|
||||||
uint32_t dirtyFlags = entity->getDirtyFlags();
|
uint32_t dirtyFlags = entity->getDirtyFlags();
|
||||||
if (dirtyFlags & Simulation::DIRTY_POSITION) {
|
if (dirtyFlags & Simulation::DIRTY_POSITION) {
|
||||||
AACube domainBounds(glm::vec3((float)-HALF_TREE_SCALE), (float)TREE_SCALE);
|
AACube domainBounds(glm::vec3((float)-HALF_TREE_SCALE), (float)TREE_SCALE);
|
||||||
AACube newCube = entity->getQueryAACube();
|
bool success;
|
||||||
if (!domainBounds.touches(newCube)) {
|
AACube newCube = entity->getQueryAACube(success);
|
||||||
|
if (success && !domainBounds.touches(newCube)) {
|
||||||
qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
|
qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
|
||||||
_entitiesToDelete.insert(entity);
|
_entitiesToDelete.insert(entity);
|
||||||
_mortalEntities.remove(entity);
|
_mortalEntities.remove(entity);
|
||||||
|
|
|
@ -141,7 +141,12 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
|
||||||
EntityItemProperties tempProperties;
|
EntityItemProperties tempProperties;
|
||||||
tempProperties.setLocked(wantsLocked);
|
tempProperties.setLocked(wantsLocked);
|
||||||
|
|
||||||
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, entity->getQueryAACube());
|
bool success;
|
||||||
|
AACube queryCube = entity->getQueryAACube(success);
|
||||||
|
if (!success) {
|
||||||
|
qCDebug(entities) << "Warning -- failed to get query-cube for" << entity->getID();
|
||||||
|
}
|
||||||
|
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, queryCube);
|
||||||
recurseTreeWithOperator(&theOperator);
|
recurseTreeWithOperator(&theOperator);
|
||||||
entity->setProperties(tempProperties);
|
entity->setProperties(tempProperties);
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
|
@ -230,9 +235,15 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
|
||||||
if (!containingElement) {
|
if (!containingElement) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
UpdateEntityOperator theChildOperator(getThisPointer(),
|
|
||||||
containingElement,
|
bool success;
|
||||||
childEntity, childEntity->getQueryAACube());
|
AACube queryCube = childEntity->getQueryAACube(success);
|
||||||
|
if (!success) {
|
||||||
|
qCDebug(entities) << "Can't update child -- failed to get query-cube for" << childEntity->getID();
|
||||||
|
// XXX put on a list for later checking?
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateEntityOperator theChildOperator(getThisPointer(), containingElement, childEntity, queryCube);
|
||||||
recurseTreeWithOperator(&theChildOperator);
|
recurseTreeWithOperator(&theChildOperator);
|
||||||
foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) {
|
foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) {
|
||||||
if (childChild && childChild->getNestableType() == NestableType::Entity) {
|
if (childChild && childChild->getNestableType() == NestableType::Entity) {
|
||||||
|
|
|
@ -302,8 +302,9 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
||||||
// simulation changing what's visible. consider the case where the entity contains an angular velocity
|
// simulation changing what's visible. consider the case where the entity contains an angular velocity
|
||||||
// the entity may not be in view and then in view a frame later, let the client side handle it's view
|
// the entity may not be in view and then in view a frame later, let the client side handle it's view
|
||||||
// frustum culling on rendering.
|
// frustum culling on rendering.
|
||||||
AACube entityCube = entity->getQueryAACube();
|
bool success;
|
||||||
if (params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) {
|
AACube entityCube = entity->getQueryAACube(success);
|
||||||
|
if (!success || params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) {
|
||||||
includeThisEntity = false; // out of view, don't include it
|
includeThisEntity = false; // out of view, don't include it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,11 +414,21 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTreeElement::containsEntityBounds(EntityItemPointer entity) const {
|
bool EntityTreeElement::containsEntityBounds(EntityItemPointer entity) const {
|
||||||
return containsBounds(entity->getQueryAACube());
|
bool success;
|
||||||
|
auto queryCube = entity->getQueryAACube(success);
|
||||||
|
if (!success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return containsBounds(queryCube);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTreeElement::bestFitEntityBounds(EntityItemPointer entity) const {
|
bool EntityTreeElement::bestFitEntityBounds(EntityItemPointer entity) const {
|
||||||
return bestFitBounds(entity->getQueryAACube());
|
bool success;
|
||||||
|
auto queryCube = entity->getQueryAACube(success);
|
||||||
|
if (!success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return bestFitBounds(queryCube);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTreeElement::containsBounds(const EntityItemProperties& properties) const {
|
bool EntityTreeElement::containsBounds(const EntityItemProperties& properties) const {
|
||||||
|
@ -516,7 +527,8 @@ bool EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm::
|
||||||
|
|
||||||
bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching,
|
bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching,
|
||||||
OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
const QVector<EntityItemID>& entityIdsToInclude, void** intersectedObject, bool precisionPicking, float distanceToElementCube) {
|
const QVector<EntityItemID>& entityIdsToInclude, void** intersectedObject,
|
||||||
|
bool precisionPicking, float distanceToElementCube) {
|
||||||
|
|
||||||
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
||||||
int entityNumber = 0;
|
int entityNumber = 0;
|
||||||
|
@ -526,7 +538,12 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AABox entityBox = entity->getAABox();
|
bool success;
|
||||||
|
AABox entityBox = entity->getAABox(success);
|
||||||
|
if (!success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float localDistance;
|
float localDistance;
|
||||||
BoxFace localFace;
|
BoxFace localFace;
|
||||||
glm::vec3 localSurfaceNormal;
|
glm::vec3 localSurfaceNormal;
|
||||||
|
@ -631,11 +648,12 @@ EntityItemPointer EntityTreeElement::getClosestEntity(glm::vec3 position) const
|
||||||
void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searchRadius, QVector<EntityItemPointer>& foundEntities) const {
|
void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searchRadius, QVector<EntityItemPointer>& foundEntities) const {
|
||||||
forEachEntity([&](EntityItemPointer entity) {
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
|
|
||||||
AABox entityBox = entity->getAABox();
|
bool success;
|
||||||
|
AABox entityBox = entity->getAABox(success);
|
||||||
|
|
||||||
// if the sphere doesn't intersect with our world frame AABox, we don't need to consider the more complex case
|
// if the sphere doesn't intersect with our world frame AABox, we don't need to consider the more complex case
|
||||||
glm::vec3 penetration;
|
glm::vec3 penetration;
|
||||||
if (entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) {
|
if (success && entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) {
|
||||||
|
|
||||||
glm::vec3 dimensions = entity->getDimensions();
|
glm::vec3 dimensions = entity->getDimensions();
|
||||||
|
|
||||||
|
@ -651,10 +669,13 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc
|
||||||
// maximum bounding sphere, which is actually larger than our actual radius
|
// maximum bounding sphere, which is actually larger than our actual radius
|
||||||
float entityTrueRadius = dimensions.x / 2.0f;
|
float entityTrueRadius = dimensions.x / 2.0f;
|
||||||
|
|
||||||
|
bool success;
|
||||||
if (findSphereSpherePenetration(searchPosition, searchRadius,
|
if (findSphereSpherePenetration(searchPosition, searchRadius,
|
||||||
entity->getCenterPosition(), entityTrueRadius, penetration)) {
|
entity->getCenterPosition(success), entityTrueRadius, penetration)) {
|
||||||
|
if (success) {
|
||||||
foundEntities.push_back(entity);
|
foundEntities.push_back(entity);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// determine the worldToEntityMatrix that doesn't include scale because
|
// determine the worldToEntityMatrix that doesn't include scale because
|
||||||
// we're going to use the registration aware aa box in the entity frame
|
// we're going to use the registration aware aa box in the entity frame
|
||||||
|
@ -679,7 +700,8 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc
|
||||||
|
|
||||||
void EntityTreeElement::getEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities) {
|
void EntityTreeElement::getEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities) {
|
||||||
forEachEntity([&](EntityItemPointer entity) {
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
AABox entityBox = entity->getAABox();
|
bool success;
|
||||||
|
AABox entityBox = entity->getAABox(success);
|
||||||
// FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better
|
// FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better
|
||||||
// FIXME - consider allowing the entity to determine penetration so that
|
// FIXME - consider allowing the entity to determine penetration so that
|
||||||
// entities could presumably dull actuall hull testing if they wanted to
|
// entities could presumably dull actuall hull testing if they wanted to
|
||||||
|
@ -696,7 +718,7 @@ void EntityTreeElement::getEntities(const AACube& cube, QVector<EntityItemPointe
|
||||||
//
|
//
|
||||||
|
|
||||||
// If the entities AABox touches the search cube then consider it to be found
|
// If the entities AABox touches the search cube then consider it to be found
|
||||||
if (entityBox.touches(cube)) {
|
if (success && entityBox.touches(cube)) {
|
||||||
foundEntities.push_back(entity);
|
foundEntities.push_back(entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -704,7 +726,8 @@ void EntityTreeElement::getEntities(const AACube& cube, QVector<EntityItemPointe
|
||||||
|
|
||||||
void EntityTreeElement::getEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities) {
|
void EntityTreeElement::getEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities) {
|
||||||
forEachEntity([&](EntityItemPointer entity) {
|
forEachEntity([&](EntityItemPointer entity) {
|
||||||
AABox entityBox = entity->getAABox();
|
bool success;
|
||||||
|
AABox entityBox = entity->getAABox(success);
|
||||||
// FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better
|
// FIXME - handle entity->getShapeType() == SHAPE_TYPE_SPHERE case better
|
||||||
// FIXME - consider allowing the entity to determine penetration so that
|
// FIXME - consider allowing the entity to determine penetration so that
|
||||||
// entities could presumably dull actuall hull testing if they wanted to
|
// entities could presumably dull actuall hull testing if they wanted to
|
||||||
|
@ -721,7 +744,7 @@ void EntityTreeElement::getEntities(const AABox& box, QVector<EntityItemPointer>
|
||||||
//
|
//
|
||||||
|
|
||||||
// If the entities AABox touches the search cube then consider it to be found
|
// If the entities AABox touches the search cube then consider it to be found
|
||||||
if (entityBox.touches(box)) {
|
if (success && entityBox.touches(box)) {
|
||||||
foundEntities.push_back(entity);
|
foundEntities.push_back(entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -940,7 +963,11 @@ bool EntityTreeElement::pruneChildren() {
|
||||||
void EntityTreeElement::expandExtentsToContents(Extents& extents) {
|
void EntityTreeElement::expandExtentsToContents(Extents& extents) {
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
foreach(EntityItemPointer entity, _entityItems) {
|
foreach(EntityItemPointer entity, _entityItems) {
|
||||||
extents.add(entity->getAABox());
|
bool success;
|
||||||
|
AABox aaBox = entity->getAABox(success);
|
||||||
|
if (success) {
|
||||||
|
extents.add(aaBox);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,11 @@ bool SphereEntityItem::findDetailedRayIntersection(const glm::vec3& origin, cons
|
||||||
// then translate back to work coordinates
|
// then translate back to work coordinates
|
||||||
glm::vec3 hitAt = glm::vec3(entityToWorldMatrix * glm::vec4(entityFrameHitAt, 1.0f));
|
glm::vec3 hitAt = glm::vec3(entityToWorldMatrix * glm::vec4(entityFrameHitAt, 1.0f));
|
||||||
distance = glm::distance(origin, hitAt);
|
distance = glm::distance(origin, hitAt);
|
||||||
surfaceNormal = glm::normalize(hitAt - getCenterPosition());
|
bool success;
|
||||||
|
surfaceNormal = glm::normalize(hitAt - getCenterPosition(success));
|
||||||
|
if (!success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
SpatialParentFinder() { }
|
SpatialParentFinder() { }
|
||||||
virtual ~SpatialParentFinder() { }
|
virtual ~SpatialParentFinder() { }
|
||||||
|
|
||||||
virtual SpatiallyNestableWeakPointer find(QUuid parentID) const = 0;
|
virtual SpatiallyNestableWeakPointer find(QUuid parentID, bool& success) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_SpatialParentFinder_h
|
#endif // hifi_SpatialParentFinder_h
|
||||||
|
|
|
@ -24,21 +24,25 @@ SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
|
||||||
_transform.setRotation(glm::quat());
|
_transform.setRotation(glm::quat());
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform SpatiallyNestable::getParentTransform() const {
|
Transform SpatiallyNestable::getParentTransform(bool& success) const {
|
||||||
Transform result;
|
Transform result;
|
||||||
SpatiallyNestablePointer parent = getParentPointer();
|
SpatiallyNestablePointer parent = getParentPointer(success);
|
||||||
|
if (!success) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if (parent) {
|
if (parent) {
|
||||||
Transform parentTransform = parent->getTransform(_parentJointIndex);
|
Transform parentTransform = parent->getTransform(_parentJointIndex, success);
|
||||||
result = parentTransform.setScale(1.0f);
|
result = parentTransform.setScale(1.0f); // TODO: scaling
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const {
|
SpatiallyNestablePointer SpatiallyNestable::getParentPointer(bool& success) const {
|
||||||
SpatiallyNestablePointer parent = _parent.lock();
|
SpatiallyNestablePointer parent = _parent.lock();
|
||||||
|
|
||||||
if (!parent && _parentID.isNull()) {
|
if (!parent && _parentID.isNull()) {
|
||||||
// no parent
|
// no parent
|
||||||
|
success = true;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +52,7 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const {
|
||||||
parent->beParentOfChild(getThisPointer());
|
parent->beParentOfChild(getThisPointer());
|
||||||
_parentKnowsMe = true;
|
_parentKnowsMe = true;
|
||||||
}
|
}
|
||||||
|
success = true;
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +68,14 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const {
|
||||||
// we have a _parentID but no parent pointer, or our parent pointer was to the wrong thing
|
// we have a _parentID but no parent pointer, or our parent pointer was to the wrong thing
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
if (!parentFinder) {
|
if (!parentFinder) {
|
||||||
|
success = false;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
_parent = parentFinder->find(_parentID);
|
_parent = parentFinder->find(_parentID, success);
|
||||||
|
if (!success) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
parent = _parent.lock();
|
parent = _parent.lock();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent->beParentOfChild(thisPointer);
|
parent->beParentOfChild(thisPointer);
|
||||||
|
@ -73,7 +83,9 @@ SpatiallyNestablePointer SpatiallyNestable::getParentPointer() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent || _parentID.isNull()) {
|
if (parent || _parentID.isNull()) {
|
||||||
thisPointer->parentChanged();
|
success = true;
|
||||||
|
} else {
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent;
|
return parent;
|
||||||
|
@ -96,136 +108,245 @@ void SpatiallyNestable::setParentID(const QUuid& parentID) {
|
||||||
_parentID = parentID;
|
_parentID = parentID;
|
||||||
_parentKnowsMe = false;
|
_parentKnowsMe = false;
|
||||||
}
|
}
|
||||||
parentChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) {
|
void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) {
|
||||||
_parentJointIndex = parentJointIndex;
|
_parentJointIndex = parentJointIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
|
||||||
glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex) {
|
const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool& success) {
|
||||||
|
Transform result;
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
if (!parentFinder) {
|
||||||
|
success = false;
|
||||||
|
return glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
Transform parentTransform;
|
Transform parentTransform;
|
||||||
if (parentFinder) {
|
auto parentWP = parentFinder->find(parentID, success);
|
||||||
auto parentWP = parentFinder->find(parentID);
|
if (!success) {
|
||||||
|
return glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
auto parent = parentWP.lock();
|
auto parent = parentWP.lock();
|
||||||
|
if (!parentID.isNull() && !parent) {
|
||||||
|
success = false;
|
||||||
|
return glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parentTransform = parent->getTransform(parentJointIndex);
|
parentTransform = parent->getTransform(parentJointIndex, success);
|
||||||
parentTransform.setScale(1.0f);
|
if (!success) {
|
||||||
|
return glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
|
parentTransform.setScale(1.0f); // TODO: scale
|
||||||
}
|
}
|
||||||
|
success = true;
|
||||||
|
|
||||||
Transform positionTransform;
|
Transform positionTransform;
|
||||||
positionTransform.setTranslation(position);
|
positionTransform.setTranslation(position);
|
||||||
Transform myWorldTransform;
|
Transform myWorldTransform;
|
||||||
Transform::mult(myWorldTransform, parentTransform, positionTransform);
|
Transform::mult(myWorldTransform, parentTransform, positionTransform);
|
||||||
|
|
||||||
myWorldTransform.setTranslation(position);
|
myWorldTransform.setTranslation(position);
|
||||||
Transform result;
|
|
||||||
Transform::inverseMult(result, parentTransform, myWorldTransform);
|
Transform::inverseMult(result, parentTransform, myWorldTransform);
|
||||||
return result.getTranslation();
|
return result.getTranslation();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex) {
|
glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
|
||||||
|
const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool& success) {
|
||||||
|
Transform result;
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
if (!parentFinder) {
|
||||||
|
success = false;
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
Transform parentTransform;
|
Transform parentTransform;
|
||||||
if (parentFinder) {
|
auto parentWP = parentFinder->find(parentID, success);
|
||||||
auto parentWP = parentFinder->find(parentID);
|
if (!success) {
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
auto parent = parentWP.lock();
|
auto parent = parentWP.lock();
|
||||||
|
if (!parentID.isNull() && !parent) {
|
||||||
|
success = false;
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parentTransform = parent->getTransform(parentJointIndex);
|
parentTransform = parent->getTransform(parentJointIndex, success);
|
||||||
parentTransform.setScale(1.0f);
|
if (!success) {
|
||||||
|
return glm::quat();
|
||||||
}
|
}
|
||||||
|
parentTransform.setScale(1.0f); // TODO: scale
|
||||||
}
|
}
|
||||||
|
success = true;
|
||||||
|
|
||||||
Transform orientationTransform;
|
Transform orientationTransform;
|
||||||
orientationTransform.setRotation(orientation);
|
orientationTransform.setRotation(orientation);
|
||||||
Transform myWorldTransform;
|
Transform myWorldTransform;
|
||||||
Transform::mult(myWorldTransform, parentTransform, orientationTransform);
|
Transform::mult(myWorldTransform, parentTransform, orientationTransform);
|
||||||
myWorldTransform.setRotation(orientation);
|
myWorldTransform.setRotation(orientation);
|
||||||
Transform result;
|
|
||||||
Transform::inverseMult(result, parentTransform, myWorldTransform);
|
Transform::inverseMult(result, parentTransform, myWorldTransform);
|
||||||
return result.getRotation();
|
return result.getRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex) {
|
glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
|
||||||
|
const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool& success) {
|
||||||
|
Transform result;
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
if (!parentFinder) {
|
||||||
|
success = false;
|
||||||
|
return glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
Transform parentTransform;
|
Transform parentTransform;
|
||||||
if (parentFinder) {
|
auto parentWP = parentFinder->find(parentID, success);
|
||||||
auto parentWP = parentFinder->find(parentID);
|
if (!success) {
|
||||||
|
return glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
auto parent = parentWP.lock();
|
auto parent = parentWP.lock();
|
||||||
|
if (!parentID.isNull() && !parent) {
|
||||||
|
success = false;
|
||||||
|
return glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parentTransform = parent->getTransform(parentJointIndex);
|
parentTransform = parent->getTransform(parentJointIndex, success);
|
||||||
parentTransform.setScale(1.0f);
|
if (!success) {
|
||||||
|
return glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
|
parentTransform.setScale(1.0f); // TODO: scale
|
||||||
}
|
}
|
||||||
|
success = true;
|
||||||
|
|
||||||
Transform positionTransform;
|
Transform positionTransform;
|
||||||
positionTransform.setTranslation(position);
|
positionTransform.setTranslation(position);
|
||||||
Transform result;
|
|
||||||
Transform::mult(result, parentTransform, positionTransform);
|
Transform::mult(result, parentTransform, positionTransform);
|
||||||
return result.getTranslation();
|
return result.getTranslation();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex) {
|
glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation,
|
||||||
|
const QUuid& parentID, int parentJointIndex,
|
||||||
|
bool& success) {
|
||||||
|
Transform result;
|
||||||
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
|
||||||
|
if (!parentFinder) {
|
||||||
|
success = false;
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
Transform parentTransform;
|
Transform parentTransform;
|
||||||
if (parentFinder) {
|
auto parentWP = parentFinder->find(parentID, success);
|
||||||
auto parentWP = parentFinder->find(parentID);
|
if (!success) {
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
auto parent = parentWP.lock();
|
auto parent = parentWP.lock();
|
||||||
|
if (!parentID.isNull() && !parent) {
|
||||||
|
success = false;
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parentTransform = parent->getTransform(parentJointIndex);
|
parentTransform = parent->getTransform(parentJointIndex, success);
|
||||||
|
if (!success) {
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
parentTransform.setScale(1.0f);
|
parentTransform.setScale(1.0f);
|
||||||
}
|
}
|
||||||
}
|
success = true;
|
||||||
|
|
||||||
Transform orientationTransform;
|
Transform orientationTransform;
|
||||||
orientationTransform.setRotation(orientation);
|
orientationTransform.setRotation(orientation);
|
||||||
Transform result;
|
|
||||||
Transform::mult(result, parentTransform, orientationTransform);
|
Transform::mult(result, parentTransform, orientationTransform);
|
||||||
return result.getRotation();
|
return result.getRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 SpatiallyNestable::getPosition(bool& success) const {
|
||||||
|
return getTransform(success).getTranslation();
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getPosition() const {
|
glm::vec3 SpatiallyNestable::getPosition() const {
|
||||||
return getTransform().getTranslation();
|
bool success;
|
||||||
|
auto result = getPosition(success);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "Warning -- getPosition failed";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getPosition(int jointIndex) const {
|
glm::vec3 SpatiallyNestable::getPosition(int jointIndex, bool& success) const {
|
||||||
return getTransform(jointIndex).getTranslation();
|
return getTransform(jointIndex, success).getTranslation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatiallyNestable::setPosition(const glm::vec3& position) {
|
void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success) {
|
||||||
Transform parentTransform = getParentTransform();
|
Transform parentTransform = getParentTransform(success);
|
||||||
Transform myWorldTransform;
|
Transform myWorldTransform;
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
Transform::mult(myWorldTransform, parentTransform, _transform);
|
Transform::mult(myWorldTransform, parentTransform, _transform);
|
||||||
myWorldTransform.setTranslation(position);
|
myWorldTransform.setTranslation(position);
|
||||||
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
||||||
});
|
});
|
||||||
|
if (success) {
|
||||||
locationChanged();
|
locationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpatiallyNestable::setPosition(const glm::vec3& position) {
|
||||||
|
bool success;
|
||||||
|
setPosition(position, success);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "Warning -- setPosition failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat SpatiallyNestable::getOrientation(bool& success) const {
|
||||||
|
return getTransform(success).getRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::quat SpatiallyNestable::getOrientation() const {
|
glm::quat SpatiallyNestable::getOrientation() const {
|
||||||
return getTransform().getRotation();
|
bool success;
|
||||||
|
auto result = getOrientation(success);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "Warning -- getOrientation failed";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::quat SpatiallyNestable::getOrientation(int jointIndex) const {
|
glm::quat SpatiallyNestable::getOrientation(int jointIndex, bool& success) const {
|
||||||
return getTransform(jointIndex).getRotation();
|
return getTransform(jointIndex, success).getRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatiallyNestable::setOrientation(const glm::quat& orientation) {
|
void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& success) {
|
||||||
Transform parentTransform = getParentTransform();
|
Transform parentTransform = getParentTransform(success);
|
||||||
Transform myWorldTransform;
|
Transform myWorldTransform;
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
Transform::mult(myWorldTransform, parentTransform, _transform);
|
Transform::mult(myWorldTransform, parentTransform, _transform);
|
||||||
myWorldTransform.setRotation(orientation);
|
myWorldTransform.setRotation(orientation);
|
||||||
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
||||||
});
|
});
|
||||||
|
if (success) {
|
||||||
locationChanged();
|
locationChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Transform SpatiallyNestable::getTransform() const {
|
void SpatiallyNestable::setOrientation(const glm::quat& orientation) {
|
||||||
|
bool success;
|
||||||
|
setOrientation(orientation, success);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "Wanring -- setOrientation failed";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Transform SpatiallyNestable::getTransform(bool& success) const {
|
||||||
// return a world-space transform for this object's location
|
// return a world-space transform for this object's location
|
||||||
Transform parentTransform = getParentTransform();
|
Transform parentTransform = getParentTransform(success);
|
||||||
Transform result;
|
Transform result;
|
||||||
_transformLock.withReadLock([&] {
|
_transformLock.withReadLock([&] {
|
||||||
Transform::mult(result, parentTransform, _transform);
|
Transform::mult(result, parentTransform, _transform);
|
||||||
|
@ -233,25 +354,34 @@ const Transform SpatiallyNestable::getTransform() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Transform SpatiallyNestable::getTransform(int jointIndex) const {
|
const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success) const {
|
||||||
// this returns the world-space transform for this object. It finds its parent's transform (which may
|
// this returns the world-space transform for this object. It finds its parent's transform (which may
|
||||||
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
|
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
|
||||||
Transform worldTransform = getTransform();
|
|
||||||
Transform jointInObjectFrame = getAbsoluteJointTransformInObjectFrame(jointIndex);
|
|
||||||
Transform jointInWorldFrame;
|
Transform jointInWorldFrame;
|
||||||
|
|
||||||
|
Transform worldTransform = getTransform(success);
|
||||||
|
if (!success) {
|
||||||
|
return jointInWorldFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform jointInObjectFrame = getAbsoluteJointTransformInObjectFrame(jointIndex);
|
||||||
Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame);
|
Transform::mult(jointInWorldFrame, worldTransform, jointInObjectFrame);
|
||||||
|
success = true;
|
||||||
return jointInWorldFrame;
|
return jointInWorldFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatiallyNestable::setTransform(const Transform& transform) {
|
void SpatiallyNestable::setTransform(const Transform& transform, bool& success) {
|
||||||
Transform parentTransform = getParentTransform();
|
Transform parentTransform = getParentTransform(success);
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
Transform::inverseMult(_transform, parentTransform, transform);
|
Transform::inverseMult(_transform, parentTransform, transform);
|
||||||
});
|
});
|
||||||
|
if (success) {
|
||||||
locationChanged();
|
locationChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getScale() const {
|
glm::vec3 SpatiallyNestable::getScale() const {
|
||||||
|
// TODO: scale
|
||||||
glm::vec3 result;
|
glm::vec3 result;
|
||||||
_transformLock.withReadLock([&] {
|
_transformLock.withReadLock([&] {
|
||||||
result = _transform.getScale();
|
result = _transform.getScale();
|
||||||
|
@ -260,11 +390,12 @@ glm::vec3 SpatiallyNestable::getScale() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getScale(int jointIndex) const {
|
glm::vec3 SpatiallyNestable::getScale(int jointIndex) const {
|
||||||
// XXX ... something with joints
|
// TODO: scale
|
||||||
return getScale();
|
return getScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatiallyNestable::setScale(const glm::vec3& scale) {
|
void SpatiallyNestable::setScale(const glm::vec3& scale) {
|
||||||
|
// TODO: scale
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
_transform.setScale(scale);
|
_transform.setScale(scale);
|
||||||
});
|
});
|
||||||
|
@ -317,6 +448,7 @@ void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getLocalScale() const {
|
glm::vec3 SpatiallyNestable::getLocalScale() const {
|
||||||
|
// TODO: scale
|
||||||
glm::vec3 result;
|
glm::vec3 result;
|
||||||
_transformLock.withReadLock([&] {
|
_transformLock.withReadLock([&] {
|
||||||
result = _transform.getScale();
|
result = _transform.getScale();
|
||||||
|
@ -325,6 +457,7 @@ glm::vec3 SpatiallyNestable::getLocalScale() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatiallyNestable::setLocalScale(const glm::vec3& scale) {
|
void SpatiallyNestable::setLocalScale(const glm::vec3& scale) {
|
||||||
|
// TODO: scale
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
_transform.setScale(scale);
|
_transform.setScale(scale);
|
||||||
});
|
});
|
||||||
|
@ -353,6 +486,16 @@ const Transform SpatiallyNestable::getAbsoluteJointTransformInObjectFrame(int jo
|
||||||
return jointTransformInObjectFrame;
|
return jointTransformInObjectFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::quat SpatiallyNestable::getAbsoluteJointRotationInObjectFrame(int index) const {
|
||||||
|
assert(false);
|
||||||
|
return glm::quat();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 SpatiallyNestable::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
||||||
|
assert(false);
|
||||||
|
return glm::vec3();
|
||||||
|
}
|
||||||
|
|
||||||
SpatiallyNestablePointer SpatiallyNestable::getThisPointer() const {
|
SpatiallyNestablePointer SpatiallyNestable::getThisPointer() const {
|
||||||
SpatiallyNestableConstPointer constThisPointer = shared_from_this();
|
SpatiallyNestableConstPointer constThisPointer = shared_from_this();
|
||||||
SpatiallyNestablePointer thisPointer = std::const_pointer_cast<SpatiallyNestable>(constThisPointer); // ermahgerd !!!
|
SpatiallyNestablePointer thisPointer = std::const_pointer_cast<SpatiallyNestable>(constThisPointer); // ermahgerd !!!
|
||||||
|
@ -391,10 +534,19 @@ void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) {
|
||||||
_queryAACubeSet = true;
|
_queryAACubeSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AACube SpatiallyNestable::getQueryAACube() const {
|
AACube SpatiallyNestable::getQueryAACube(bool& success) const {
|
||||||
if (!_queryAACubeSet) {
|
if (_queryAACubeSet) {
|
||||||
_queryAACube = AACube(getPosition() - glm::vec3(0.5f), 1.0f); // XXX
|
success = true;
|
||||||
_queryAACubeSet = true;
|
|
||||||
}
|
|
||||||
return _queryAACube;
|
return _queryAACube;
|
||||||
|
}
|
||||||
|
return AACube(getPosition(success) - glm::vec3(0.5f), 1.0f); // XXX
|
||||||
|
}
|
||||||
|
|
||||||
|
AACube SpatiallyNestable::getQueryAACube() const {
|
||||||
|
bool success;
|
||||||
|
auto result = getQueryAACube(success);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "getQueryAACube failed:" << getID();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,34 +45,39 @@ public:
|
||||||
virtual quint16 getParentJointIndex() const { return _parentJointIndex; }
|
virtual quint16 getParentJointIndex() const { return _parentJointIndex; }
|
||||||
virtual void setParentJointIndex(quint16 parentJointIndex);
|
virtual void setParentJointIndex(quint16 parentJointIndex);
|
||||||
|
|
||||||
static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex);
|
static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success);
|
||||||
static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex);
|
static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success);
|
||||||
|
|
||||||
static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex);
|
static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success);
|
||||||
static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex);
|
static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success);
|
||||||
|
|
||||||
// world frame
|
// world frame
|
||||||
virtual const Transform getTransform() const;
|
virtual const Transform getTransform(bool& success) const;
|
||||||
virtual void setTransform(const Transform& transform);
|
virtual void setTransform(const Transform& transform, bool& success);
|
||||||
|
|
||||||
virtual Transform getParentTransform() const;
|
virtual Transform getParentTransform(bool& success) const;
|
||||||
|
|
||||||
|
virtual glm::vec3 getPosition(bool& success) const;
|
||||||
virtual glm::vec3 getPosition() const;
|
virtual glm::vec3 getPosition() const;
|
||||||
|
virtual void setPosition(const glm::vec3& position, bool& success);
|
||||||
virtual void setPosition(const glm::vec3& position);
|
virtual void setPosition(const glm::vec3& position);
|
||||||
|
|
||||||
|
virtual glm::quat getOrientation(bool& success) const;
|
||||||
virtual glm::quat getOrientation() const;
|
virtual glm::quat getOrientation() const;
|
||||||
virtual glm::quat getOrientation(int jointIndex) const;
|
virtual glm::quat getOrientation(int jointIndex, bool& success) const;
|
||||||
|
virtual void setOrientation(const glm::quat& orientation, bool& success);
|
||||||
virtual void setOrientation(const glm::quat& orientation);
|
virtual void setOrientation(const glm::quat& orientation);
|
||||||
|
|
||||||
virtual void setQueryAACube(const AACube& queryAACube);
|
virtual void setQueryAACube(const AACube& queryAACube);
|
||||||
|
virtual AACube getQueryAACube(bool& success) const;
|
||||||
virtual AACube getQueryAACube() const;
|
virtual AACube getQueryAACube() const;
|
||||||
|
|
||||||
virtual glm::vec3 getScale() const;
|
virtual glm::vec3 getScale() const;
|
||||||
virtual void setScale(const glm::vec3& scale);
|
virtual void setScale(const glm::vec3& scale);
|
||||||
|
|
||||||
// get world-frame values for a specific joint
|
// get world-frame values for a specific joint
|
||||||
virtual const Transform getTransform(int jointIndex) const;
|
virtual const Transform getTransform(int jointIndex, bool& success) const;
|
||||||
virtual glm::vec3 getPosition(int jointIndex) const;
|
virtual glm::vec3 getPosition(int jointIndex, bool& success) const;
|
||||||
virtual glm::vec3 getScale(int jointIndex) const;
|
virtual glm::vec3 getScale(int jointIndex) const;
|
||||||
|
|
||||||
// object's parent's frame
|
// object's parent's frame
|
||||||
|
@ -93,8 +98,8 @@ public:
|
||||||
|
|
||||||
// this object's frame
|
// this object's frame
|
||||||
virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const;
|
virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const;
|
||||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { assert(false); return glm::quat(); }
|
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const;
|
||||||
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { assert(false); return glm::vec3(); }
|
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const;
|
||||||
|
|
||||||
SpatiallyNestablePointer getThisPointer() const;
|
SpatiallyNestablePointer getThisPointer() const;
|
||||||
|
|
||||||
|
@ -103,7 +108,7 @@ protected:
|
||||||
QUuid _id;
|
QUuid _id;
|
||||||
QUuid _parentID; // what is this thing's transform relative to?
|
QUuid _parentID; // what is this thing's transform relative to?
|
||||||
quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to?
|
quint16 _parentJointIndex { 0 }; // which joint of the parent is this relative to?
|
||||||
SpatiallyNestablePointer getParentPointer() const;
|
SpatiallyNestablePointer getParentPointer(bool& success) const;
|
||||||
mutable SpatiallyNestableWeakPointer _parent;
|
mutable SpatiallyNestableWeakPointer _parent;
|
||||||
|
|
||||||
virtual void beParentOfChild(SpatiallyNestablePointer newChild) const;
|
virtual void beParentOfChild(SpatiallyNestablePointer newChild) const;
|
||||||
|
@ -112,7 +117,6 @@ protected:
|
||||||
mutable ReadWriteLockable _childrenLock;
|
mutable ReadWriteLockable _childrenLock;
|
||||||
mutable QHash<QUuid, SpatiallyNestableWeakPointer> _children;
|
mutable QHash<QUuid, SpatiallyNestableWeakPointer> _children;
|
||||||
|
|
||||||
virtual void parentChanged() {} // called when parent pointer is updated
|
|
||||||
virtual void locationChanged(); // called when a this object's location has changed
|
virtual void locationChanged(); // called when a this object's location has changed
|
||||||
virtual void dimensionsChanged() {} // called when a this object's dimensions have changed
|
virtual void dimensionsChanged() {} // called when a this object's dimensions have changed
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue