first steps toward a puffed-out query-box for child entities

This commit is contained in:
Seth Alves 2015-12-12 12:33:14 -08:00
parent 6c033d9603
commit 24fb43e8cd
23 changed files with 116 additions and 165 deletions

View file

@ -25,7 +25,7 @@ AddEntityOperator::AddEntityOperator(EntityTreePointer tree, EntityItemPointer n
// caller must have verified existence of newEntity
assert(_newEntity);
_newEntityBox = _newEntity->getMaximumAACube().clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE);
_newEntityBox = _newEntity->getQueryAACube().clamp((float)(-HALF_TREE_SCALE), (float)HALF_TREE_SCALE);
}
bool AddEntityOperator::preRecursion(OctreeElementPointer element) {

View file

@ -1,83 +0,0 @@
//
// BoundingBoxRelatedProperties.cpp
// libraries/entities/src
//
// Created by Seth Alves on 2015-9-24
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "EntityItemProperties.h"
#include "BoundingBoxRelatedProperties.h"
#include "EntityTree.h"
BoundingBoxRelatedProperties::BoundingBoxRelatedProperties(EntityItemPointer entity) :
position(entity->getPosition()),
rotation(entity->getRotation()),
registrationPoint(entity->getRegistrationPoint()),
dimensions(entity->getDimensions()),
parentID(entity->getParentID()) {
}
BoundingBoxRelatedProperties::BoundingBoxRelatedProperties(EntityItemPointer entity,
const EntityItemProperties& propertiesWithUpdates) :
BoundingBoxRelatedProperties(entity) {
if (propertiesWithUpdates.parentIDChanged()) {
parentID = propertiesWithUpdates.getParentID();
}
bool parentFound = false;
if (parentID != UNKNOWN_ENTITY_ID) {
EntityTreePointer tree = entity->getTree();
EntityItemPointer parentZone = tree->findEntityByID(parentID);
if (parentZone) {
parentFound = true;
glm::vec3 localPosition = propertiesWithUpdates.containsPositionChange() ?
propertiesWithUpdates.getPosition() :
entity->getLocalPosition();
glm::quat localRotation = propertiesWithUpdates.rotationChanged() ?
propertiesWithUpdates.getRotation() :
entity->getLocalOrientation();
const Transform parentTransform = parentZone->getTransformToCenter();
Transform parentDescaled(parentTransform.getRotation(), glm::vec3(1.0f), parentTransform.getTranslation());
Transform localTransform(localRotation, glm::vec3(1.0f), localPosition);
Transform result;
Transform::mult(result, parentDescaled, localTransform);
position = result.getTranslation();
rotation = result.getRotation();
}
}
if (!parentFound) {
if (propertiesWithUpdates.containsPositionChange()) {
position = propertiesWithUpdates.getPosition();
}
if (propertiesWithUpdates.rotationChanged()) {
rotation = propertiesWithUpdates.getRotation();
}
}
if (propertiesWithUpdates.registrationPointChanged()) {
registrationPoint = propertiesWithUpdates.getRegistrationPoint();
}
if (propertiesWithUpdates.dimensionsChanged()) {
dimensions = propertiesWithUpdates.getDimensions();
}
}
AACube BoundingBoxRelatedProperties::getMaximumAACube() const {
// see EntityItem::getMaximumAACube for comments which explain the following.
glm::vec3 scaledRegistrationPoint = (dimensions * registrationPoint);
glm::vec3 registrationRemainder = (dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - registrationPoint));
glm::vec3 furthestExtentFromRegistration = glm::max(scaledRegistrationPoint, registrationRemainder);
float radius = glm::length(furthestExtentFromRegistration);
glm::vec3 minimumCorner = position - glm::vec3(radius, radius, radius);
return AACube(minimumCorner, radius * 2.0f);
}

View file

@ -1,30 +0,0 @@
//
// BoundingBoxRelatedProperties.h
// libraries/entities/src
//
// Created by Seth Alves on 2015-9-24
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "EntityItem.h"
#ifndef hifi_BoundingBoxRelatedProperties_h
#define hifi_BoundingBoxRelatedProperties_h
class BoundingBoxRelatedProperties {
public:
BoundingBoxRelatedProperties(EntityItemPointer entity);
BoundingBoxRelatedProperties(EntityItemPointer entity, const EntityItemProperties& propertiesWithUpdates);
AACube getMaximumAACube() const;
glm::vec3 position;
glm::quat rotation;
glm::vec3 registrationPoint;
glm::vec3 dimensions;
EntityItemID parentID;
};
#endif // hifi_BoundingBoxRelatedProperties_h

View file

@ -133,6 +133,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
requestedProperties += PROP_ACTION_DATA;
requestedProperties += PROP_PARENT_ID;
requestedProperties += PROP_PARENT_JOINT_INDEX;
requestedProperties += PROP_QUERY_AA_CUBE;
return requestedProperties;
}
@ -269,6 +270,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, getActionData());
APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, getParentID());
APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, getParentJointIndex());
APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, getQueryAACube());
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
requestedProperties,
@ -693,6 +695,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
READ_ENTITY_PROPERTY(PROP_PARENT_ID, QUuid, setParentID);
READ_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex);
READ_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, AACube, setQueryAACube);
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
propertyFlags, overwriteLocalData, somethingChanged);
@ -1245,6 +1249,16 @@ const AABox& EntityItem::getAABox() const {
return _cachedAABox;
}
AACube EntityItem::getQueryAACube() const {
// XXX
if (!_queryAACubeSet) {
_queryAACube = getMaximumAACube();
_queryAACubeSet = true;
}
return SpatiallyNestable::getQueryAACube();
}
// NOTE: This should only be used in cases of old bitstreams which only contain radius data
// 0,0,0 --> maxDimension,maxDimension,maxDimension
// ... has a corner to corner distance of glm::length(maxDimension,maxDimension,maxDimension)

View file

@ -236,6 +236,8 @@ public:
const AACube& getMinimumAACube() const;
const AABox& getAABox() const; /// axis aligned bounding box in world-frame (meters)
virtual AACube getQueryAACube() const;
const QString& getScript() const { return _script; }
void setScript(const QString& value) { _script = value; }

View file

@ -262,6 +262,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_Z_P_NEIGHBOR_ID, zPNeighborID);
CHECK_PROPERTY_CHANGE(PROP_PARENT_ID, parentID);
CHECK_PROPERTY_CHANGE(PROP_PARENT_JOINT_INDEX, parentJointIndex);
CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube);
changedProperties += _animation.getChangedProperties();
changedProperties += _keyLight.getChangedProperties();
@ -477,6 +478,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_POSITION, localPosition);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_QUERY_AA_CUBE, queryAACube);
// FIXME - I don't think these properties are supported any more
//COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel);
//COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha);
@ -922,6 +925,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
APPEND_ENTITY_PROPERTY(PROP_DESCRIPTION, properties.getDescription());
APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, properties.getParentID());
APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, properties.getParentJointIndex());
APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, properties.getQueryAACube());
if (properties.getType() == EntityTypes::Web) {
APPEND_ENTITY_PROPERTY(PROP_SOURCE_URL, properties.getSourceUrl());
@ -1208,6 +1212,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DESCRIPTION, QString, setDescription);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_ID, QUuid, setParentID);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARENT_JOINT_INDEX, quint16, setParentJointIndex);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_QUERY_AA_CUBE, AACube, setQueryAACube);
if (properties.getType() == EntityTypes::Web) {
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SOURCE_URL, QString, setSourceUrl);
@ -1462,32 +1467,6 @@ void EntityItemProperties::markAllChanged() {
_parentJointIndexChanged = true;
}
/// The maximum bounding cube for the entity, independent of it's rotation.
/// This accounts for the registration point (upon which rotation occurs around).
///
AACube EntityItemProperties::getMaximumAACube() const {
// * we know that the position is the center of rotation
glm::vec3 centerOfRotation = _position; // 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 = (_dimensions * _registrationPoint);
glm::vec3 registrationRemainder = (_dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint));
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 the minimum bounding cube of this maximum possible sphere is
// (center - radius) to (center + radius)
glm::vec3 minimumCorner = centerOfRotation - glm::vec3(radius, radius, radius);
float diameter = radius * 2.0f;
return AACube(minimumCorner, diameter);
}
// The minimum bounding box for the entity.
AABox EntityItemProperties::getAABox() const {

View file

@ -85,7 +85,6 @@ public:
bool parentDependentPropertyChanged() const; // was there a changed in a property that requires parent info to interpret?
AACube getMaximumAACube() const;
AABox getAABox() const;
void debugDump() const;
@ -193,6 +192,7 @@ public:
DEFINE_PROPERTY_REF(PROP_Z_P_NEIGHBOR_ID, ZPNeighborID, zPNeighborID, EntityItemID, UNKNOWN_ENTITY_ID);
DEFINE_PROPERTY_REF(PROP_PARENT_ID, ParentID, parentID, QUuid, UNKNOWN_ENTITY_ID);
DEFINE_PROPERTY_REF(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, 0);
DEFINE_PROPERTY_REF(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube, AACube());
// these are used when bouncing location data into and out of scripts
DEFINE_PROPERTY_REF(PROP_LOCAL_POSITION, LocalPosition, localPosition, glmVec3, ENTITY_ITEM_ZERO_VEC3);
@ -397,6 +397,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParentID, parentID, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParentJointIndex, parentJointIndex, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, QueryAACube, queryAACube, "");
properties.getAnimation().debugDump();
properties.getAtmosphere().debugDump();

View file

@ -122,6 +122,9 @@ inline QScriptValue convertScriptValue(QScriptEngine* e, const QByteArray& v) {
inline QScriptValue convertScriptValue(QScriptEngine* e, const EntityItemID& v) { return QScriptValue(QUuid(v).toString()); }
inline QScriptValue convertScriptValue(QScriptEngine* e, const AACube& v) { return aaCubeToScriptValue(e, v); }
#define COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(X,G,g,P,p) \
if ((desiredProperties.isEmpty() || desiredProperties.getHasProperty(X)) && \

View file

@ -157,6 +157,8 @@ enum EntityPropertyList {
PROP_LOCAL_POSITION, // only used to convert values to and from scripts
PROP_LOCAL_ROTATION, // only used to convert values to and from scripts
PROP_QUERY_AA_CUBE, // how the EntityTree considers the size and position on an entity
////////////////////////////////////////////////////////////////////////////////////////////////////
// ATTENTION: add new properties to end of list just ABOVE this line
PROP_AFTER_LAST_ITEM,

View file

@ -119,7 +119,7 @@ void EntitySimulation::sortEntitiesThatMoved() {
while (itemItr != _entitiesToSort.end()) {
EntityItemPointer entity = *itemItr;
// check to see if this movement has sent the entity outside of the domain.
AACube newCube = entity->getMaximumAACube();
AACube newCube = entity->getQueryAACube();
if (!domainBounds.touches(newCube)) {
qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
_entitiesToDelete.insert(entity);
@ -200,7 +200,7 @@ void EntitySimulation::changeEntity(EntityItemPointer entity) {
uint32_t dirtyFlags = entity->getDirtyFlags();
if (dirtyFlags & Simulation::DIRTY_POSITION) {
AACube domainBounds(glm::vec3((float)-HALF_TREE_SCALE), (float)TREE_SCALE);
AACube newCube = entity->getMaximumAACube();
AACube newCube = entity->getQueryAACube();
if (!domainBounds.touches(newCube)) {
qCDebug(entities) << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
_entitiesToDelete.insert(entity);

View file

@ -18,7 +18,7 @@
#include "VariantMapToScriptValue.h"
#include "AddEntityOperator.h"
#include "MovingEntitiesOperator.h"
// #include "MovingEntitiesOperator.h"
#include "UpdateEntityOperator.h"
#include "QVariantGLM.h"
#include "EntitiesLogging.h"
@ -142,9 +142,9 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
EntityItemProperties tempProperties;
tempProperties.setLocked(wantsLocked);
BoundingBoxRelatedProperties newBBRelProperties(entity, tempProperties);
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newBBRelProperties);
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, entity->getQueryAACube());
recurseTreeWithOperator(&theOperator);
entity->setProperties(tempProperties);
_isDirty = true;
}
@ -211,8 +211,7 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
QString collisionSoundURLBefore = entity->getCollisionSoundURL();
uint32_t preFlags = entity->getDirtyFlags();
BoundingBoxRelatedProperties newBBRelProperties(entity, properties);
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, newBBRelProperties);
UpdateEntityOperator theOperator(getThisPointer(), containingElement, entity, properties.getQueryAACube());
recurseTreeWithOperator(&theOperator);
entity->setProperties(properties);
@ -226,10 +225,9 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI
while (!toProcess.empty()) {
EntityItemPointer childEntity = std::static_pointer_cast<EntityItem>(toProcess.dequeue());
BoundingBoxRelatedProperties newChildBBRelProperties(childEntity);
UpdateEntityOperator theChildOperator(getThisPointer(),
childEntity->getElement(),
childEntity, newChildBBRelProperties);
childEntity, childEntity->getQueryAACube());
recurseTreeWithOperator(&theChildOperator);
foreach (SpatiallyNestablePointer childChild, childEntity->getChildren()) {
if (childChild && childChild->getNestableType() == NestableType::Entity) {

View file

@ -302,7 +302,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
// 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
// frustum culling on rendering.
AACube entityCube = entity->getMaximumAACube();
AACube entityCube = entity->getQueryAACube();
if (params.viewFrustum->cubeInFrustum(entityCube) == ViewFrustum::OUTSIDE) {
includeThisEntity = false; // out of view, don't include it
}
@ -413,19 +413,19 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
}
bool EntityTreeElement::containsEntityBounds(EntityItemPointer entity) const {
return containsBounds(entity->getMaximumAACube());
return containsBounds(entity->getQueryAACube());
}
bool EntityTreeElement::bestFitEntityBounds(EntityItemPointer entity) const {
return bestFitBounds(entity->getMaximumAACube());
return bestFitBounds(entity->getQueryAACube());
}
bool EntityTreeElement::containsBounds(const EntityItemProperties& properties) const {
return containsBounds(properties.getMaximumAACube());
return containsBounds(properties.getQueryAACube());
}
bool EntityTreeElement::bestFitBounds(const EntityItemProperties& properties) const {
return bestFitBounds(properties.getMaximumAACube());
return bestFitBounds(properties.getQueryAACube());
}
bool EntityTreeElement::containsBounds(const AACube& bounds) const {

View file

@ -14,12 +14,11 @@
UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree,
EntityTreeElementPointer containingElement,
EntityItemPointer existingEntity,
const BoundingBoxRelatedProperties& newProperties) :
const AACube newQueryAACube) :
_tree(tree),
_existingEntity(existingEntity),
_containingElement(containingElement),
_containingElementCube(containingElement->getAACube()),
_newProperties(newProperties),
_entityItemID(existingEntity->getEntityItemID()),
_foundOld(false),
_foundNew(false),
@ -41,13 +40,13 @@ UpdateEntityOperator::UpdateEntityOperator(EntityTreePointer tree,
// entity into the the element, or do we want to use the entities "relaxed" bounds
// which can handle all potential rotations?
// the getMaximumAACube is the relaxed form.
_oldEntityCube = _existingEntity->getMaximumAACube();
_oldEntityCube = _existingEntity->getQueryAACube();
_oldEntityBox = _oldEntityCube.clamp((float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); // clamp to domain bounds
// If our new properties don't have bounds details (no change to position, etc) or if this containing element would
// be the best fit for our new properties, then just do the new portion of the store pass, since the change path will
// be the same for both parts of the update
bool oldElementBestFit = _containingElement->bestFitBounds(newProperties.getMaximumAACube());
bool oldElementBestFit = _containingElement->bestFitBounds(newQueryAACube);
// For some reason we've seen a case where the original containing element isn't a best fit for the old properties
// in this case we want to move it, even if the properties haven't changed.

View file

@ -12,7 +12,7 @@
#ifndef hifi_UpdateEntityOperator_h
#define hifi_UpdateEntityOperator_h
#include "BoundingBoxRelatedProperties.h"
// #include "BoundingBoxRelatedProperties.h"
#include "EntitiesLogging.h"
#include "EntityItem.h"
#include "EntityItemProperties.h"
@ -22,7 +22,7 @@
class UpdateEntityOperator : public RecurseOctreeOperator {
public:
UpdateEntityOperator(EntityTreePointer tree, EntityTreeElementPointer containingElement,
EntityItemPointer existingEntity, const BoundingBoxRelatedProperties& newProperties);
EntityItemPointer existingEntity, const AACube newQueryAACube);
~UpdateEntityOperator();
@ -34,7 +34,7 @@ private:
EntityItemPointer _existingEntity;
EntityTreeElementPointer _containingElement;
AACube _containingElementCube; // we temporarily store our cube here in case we need to delete the containing element
BoundingBoxRelatedProperties _newProperties;
// BoundingBoxRelatedProperties _newProperties;
EntityItemID _entityItemID;
bool _foundOld;
bool _foundNew;

View file

@ -41,7 +41,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityAdd:
case PacketType::EntityEdit:
case PacketType::EntityData:
return VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP;
return VERSION_ENTITITES_HAVE_QUERY_BOX;
case PacketType::AvatarData:
case PacketType::BulkAvatarData:
return 17;

View file

@ -162,5 +162,6 @@ const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49;
const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50;
const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51;
const PacketVersion VERSION_ENTITITES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52;
const PacketVersion VERSION_ENTITITES_HAVE_QUERY_BOX = 53;
#endif // hifi_PacketHeaders_h

View file

@ -461,6 +461,10 @@ bool OctreePacketData::appendValue(const QByteArray& bytes) {
return success;
}
bool OctreePacketData::appendValue(const AACube& aaCube) {
bool success = appendValue(aaCube.getCorner());
return success & appendValue(aaCube.getScale());
}
bool OctreePacketData::appendPosition(const glm::vec3& value) {
const unsigned char* data = (const unsigned char*)&value;
@ -638,3 +642,12 @@ int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QByteA
result = value;
return sizeof(length) + length;
}
int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, AACube& result) {
glm::vec3 corner;
float scale;
int bytes = unpackDataFromBytes(dataBytes, corner);
bytes += unpackDataFromBytes(dataBytes + bytes, scale);
result = AACube(corner, scale);
return bytes;
}

View file

@ -187,6 +187,9 @@ public:
/// appends a QByteArray value to the end of the stream, may fail if new data stream is too long to fit in packet
bool appendValue(const QByteArray& bytes);
/// appends an AACube value to the end of the stream, may fail if new data stream is too long to fit in packet
bool appendValue(const AACube& aaCube);
/// appends a position to the end of the stream, may fail if new data stream is too long to fit in packet
bool appendPosition(const glm::vec3& value);
@ -253,6 +256,7 @@ public:
static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<glm::vec3>& result);
static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<float>& result);
static int unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result);
static int unpackDataFromBytes(const unsigned char* dataBytes, AACube& result);
private:
/// appends raw bytes, might fail if byte would cause packet to be too large

View file

@ -135,6 +135,8 @@ int unpackOrientationQuatFromBytes(const unsigned char* buffer, glm::quat& quatO
return sizeof(quatParts);
}
// Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's
// http://www.geometrictools.com/Documentation/EulerAngles.pdf (via Clyde,
// https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java)

View file

@ -42,7 +42,7 @@ void registerMetaTypes(QScriptEngine* engine) {
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue);
qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue);
qScriptRegisterMetaType(engine, aaCubeToScriptValue, aaCubeFromScriptValue);
}
QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) {
@ -238,6 +238,26 @@ QScriptValue qColorToScriptValue(QScriptEngine* engine, const QColor& color) {
return object;
}
QScriptValue aaCubeToScriptValue(QScriptEngine* engine, const AACube& aaCube) {
QScriptValue obj = engine->newObject();
const glm::vec3& corner = aaCube.getCorner();
obj.setProperty("x", corner.x);
obj.setProperty("y", corner.y);
obj.setProperty("z", corner.z);
obj.setProperty("scale", aaCube.getScale());
return obj;
}
void aaCubeFromScriptValue(const QScriptValue &object, AACube& aaCube) {
glm::vec3 corner;
corner.x = object.property("x").toVariant().toFloat();
corner.y = object.property("y").toVariant().toFloat();
corner.z = object.property("z").toVariant().toFloat();
float scale = object.property("scale").toVariant().toFloat();
aaCube.setBox(corner, scale);
}
void qColorFromScriptValue(const QScriptValue& object, QColor& color) {
if (object.isNumber()) {
color.setRgb(object.toUInt32());

View file

@ -18,6 +18,7 @@
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include "AACube.h"
#include "SharedUtil.h"
class QColor;
@ -30,6 +31,7 @@ Q_DECLARE_METATYPE(glm::quat)
Q_DECLARE_METATYPE(xColor)
Q_DECLARE_METATYPE(QVector<glm::vec3>)
Q_DECLARE_METATYPE(QVector<float>)
Q_DECLARE_METATYPE(AACube)
void registerMetaTypes(QScriptEngine* engine);
@ -67,6 +69,9 @@ QVector<float> qVectorFloatFromScriptValue(const QScriptValue& array);
QVector<QUuid> qVectorQUuidFromScriptValue(const QScriptValue& array);
QScriptValue aaCubeToScriptValue(QScriptEngine* engine, const AACube& aaCube);
void aaCubeFromScriptValue(const QScriptValue &object, AACube& aaCube);
class PickRay {
public:
PickRay() : origin(0.0f), direction(0.0f) { }

View file

@ -385,3 +385,16 @@ void SpatiallyNestable::locationChanged() {
object->locationChanged();
});
}
void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) {
_queryAACube = queryAACube;
_queryAACubeSet = true;
}
AACube SpatiallyNestable::getQueryAACube() const {
if (!_queryAACubeSet) {
_queryAACube = AACube(getPosition() - glm::vec3(0.5f), 1.0f); // XXX
_queryAACubeSet = true;
}
return _queryAACube;
}

View file

@ -15,6 +15,7 @@
#include <QUuid>
#include "Transform.h"
#include "AACube.h"
#include "SpatialParentFinder.h"
#include "shared/ReadWriteLockable.h"
@ -63,6 +64,9 @@ public:
virtual glm::quat getOrientation(int jointIndex) const;
virtual void setOrientation(const glm::quat& orientation);
virtual void setQueryAACube(const AACube& queryAACube);
virtual AACube getQueryAACube() const;
virtual glm::vec3 getScale() const;
virtual void setScale(const glm::vec3& scale);
@ -91,7 +95,7 @@ public:
virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const;
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { assert(false); return glm::quat(); }
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { assert(false); return glm::vec3(); }
SpatiallyNestablePointer getThisPointer() const;
protected:
@ -115,6 +119,10 @@ protected:
void forEachChild(std::function<void(SpatiallyNestablePointer)> actor);
void forEachDescendant(std::function<void(SpatiallyNestablePointer)> actor);
// _queryAACube is used to decide where something lives in the octree
mutable AACube _queryAACube;
mutable bool _queryAACubeSet { false };
private:
mutable ReadWriteLockable _transformLock;
Transform _transform; // this is to be combined with parent's world-transform to produce this' world-transform.