mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 03:42:27 +02:00
Merge pull request #13890 from sethalves/grab-properties-1
move grab pseudo-properties (userData) into first-class EntityItemProperties
This commit is contained in:
commit
0e0542ec6e
64 changed files with 1527 additions and 738 deletions
|
@ -75,8 +75,11 @@ size_t AvatarDataPacket::maxJointDataSize(size_t numJoints, bool hasGrabJoints)
|
|||
totalSize += numJoints * sizeof(SixByteTrans); // Translations
|
||||
|
||||
size_t NUM_FAUX_JOINT = 2;
|
||||
size_t num_grab_joints = (hasGrabJoints ? 2 : 0);
|
||||
totalSize += (NUM_FAUX_JOINT + num_grab_joints) * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints
|
||||
totalSize += NUM_FAUX_JOINT * (sizeof(SixByteQuat) + sizeof(SixByteTrans)); // faux joints
|
||||
|
||||
if (hasGrabJoints) {
|
||||
totalSize += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||
}
|
||||
|
||||
return totalSize;
|
||||
}
|
||||
|
@ -690,7 +693,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
if (hasGrabJoints) {
|
||||
// the far-grab joints may range further than 3 meters, so we can't use packFloatVec3ToSignedTwoByteFixed etc
|
||||
auto startSection = destinationBuffer;
|
||||
auto data = reinterpret_cast<AvatarDataPacket::FarGrabJoints*>(destinationBuffer);
|
||||
|
||||
glm::vec3 leftFarGrabPosition = extractTranslation(leftFarGrabMatrix);
|
||||
glm::quat leftFarGrabRotation = extractRotation(leftFarGrabMatrix);
|
||||
glm::vec3 rightFarGrabPosition = extractTranslation(rightFarGrabMatrix);
|
||||
|
@ -698,28 +701,17 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
glm::vec3 mouseFarGrabPosition = extractTranslation(mouseFarGrabMatrix);
|
||||
glm::quat mouseFarGrabRotation = extractRotation(mouseFarGrabMatrix);
|
||||
|
||||
AVATAR_MEMCPY(leftFarGrabPosition);
|
||||
// Can't do block copy as struct order is x, y, z, w.
|
||||
data->leftFarGrabRotation[0] = leftFarGrabRotation.w;
|
||||
data->leftFarGrabRotation[1] = leftFarGrabRotation.x;
|
||||
data->leftFarGrabRotation[2] = leftFarGrabRotation.y;
|
||||
data->leftFarGrabRotation[3] = leftFarGrabRotation.z;
|
||||
destinationBuffer += sizeof(data->leftFarGrabPosition);
|
||||
|
||||
AVATAR_MEMCPY(rightFarGrabPosition);
|
||||
data->rightFarGrabRotation[0] = rightFarGrabRotation.w;
|
||||
data->rightFarGrabRotation[1] = rightFarGrabRotation.x;
|
||||
data->rightFarGrabRotation[2] = rightFarGrabRotation.y;
|
||||
data->rightFarGrabRotation[3] = rightFarGrabRotation.z;
|
||||
destinationBuffer += sizeof(data->rightFarGrabRotation);
|
||||
|
||||
AVATAR_MEMCPY(mouseFarGrabPosition);
|
||||
data->mouseFarGrabRotation[0] = mouseFarGrabRotation.w;
|
||||
data->mouseFarGrabRotation[1] = mouseFarGrabRotation.x;
|
||||
data->mouseFarGrabRotation[2] = mouseFarGrabRotation.y;
|
||||
data->mouseFarGrabRotation[3] = mouseFarGrabRotation.z;
|
||||
destinationBuffer += sizeof(data->mouseFarGrabRotation);
|
||||
AvatarDataPacket::FarGrabJoints farGrabJoints = {
|
||||
{ leftFarGrabPosition.x, leftFarGrabPosition.y, leftFarGrabPosition.z },
|
||||
{ leftFarGrabRotation.w, leftFarGrabRotation.x, leftFarGrabRotation.y, leftFarGrabRotation.z },
|
||||
{ rightFarGrabPosition.x, rightFarGrabPosition.y, rightFarGrabPosition.z },
|
||||
{ rightFarGrabRotation.w, rightFarGrabRotation.x, rightFarGrabRotation.y, rightFarGrabRotation.z },
|
||||
{ mouseFarGrabPosition.x, mouseFarGrabPosition.y, mouseFarGrabPosition.z },
|
||||
{ mouseFarGrabRotation.w, mouseFarGrabRotation.x, mouseFarGrabRotation.y, mouseFarGrabRotation.z }
|
||||
};
|
||||
|
||||
memcpy(destinationBuffer, &farGrabJoints, sizeof(farGrabJoints));
|
||||
destinationBuffer += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||
int numBytes = destinationBuffer - startSection;
|
||||
|
||||
if (outboundDataRateOut) {
|
||||
|
@ -1250,25 +1242,37 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
|||
auto startSection = sourceBuffer;
|
||||
|
||||
PACKET_READ_CHECK(FarGrabJoints, sizeof(AvatarDataPacket::FarGrabJoints));
|
||||
auto data = reinterpret_cast<const AvatarDataPacket::FarGrabJoints*>(sourceBuffer);
|
||||
glm::vec3 leftFarGrabPosition = glm::vec3(data->leftFarGrabPosition[0], data->leftFarGrabPosition[1],
|
||||
data->leftFarGrabPosition[2]);
|
||||
glm::quat leftFarGrabRotation = glm::quat(data->leftFarGrabRotation[0], data->leftFarGrabRotation[1],
|
||||
data->leftFarGrabRotation[2], data->leftFarGrabRotation[3]);
|
||||
glm::vec3 rightFarGrabPosition = glm::vec3(data->rightFarGrabPosition[0], data->rightFarGrabPosition[1],
|
||||
data->rightFarGrabPosition[2]);
|
||||
glm::quat rightFarGrabRotation = glm::quat(data->rightFarGrabRotation[0], data->rightFarGrabRotation[1],
|
||||
data->rightFarGrabRotation[2], data->rightFarGrabRotation[3]);
|
||||
glm::vec3 mouseFarGrabPosition = glm::vec3(data->mouseFarGrabPosition[0], data->mouseFarGrabPosition[1],
|
||||
data->mouseFarGrabPosition[2]);
|
||||
glm::quat mouseFarGrabRotation = glm::quat(data->mouseFarGrabRotation[0], data->mouseFarGrabRotation[1],
|
||||
data->mouseFarGrabRotation[2], data->mouseFarGrabRotation[3]);
|
||||
|
||||
AvatarDataPacket::FarGrabJoints farGrabJoints;
|
||||
memcpy(&farGrabJoints, sourceBuffer, sizeof(farGrabJoints)); // to avoid misaligned floats
|
||||
|
||||
glm::vec3 leftFarGrabPosition = glm::vec3(farGrabJoints.leftFarGrabPosition[0],
|
||||
farGrabJoints.leftFarGrabPosition[1],
|
||||
farGrabJoints.leftFarGrabPosition[2]);
|
||||
glm::quat leftFarGrabRotation = glm::quat(farGrabJoints.leftFarGrabRotation[0],
|
||||
farGrabJoints.leftFarGrabRotation[1],
|
||||
farGrabJoints.leftFarGrabRotation[2],
|
||||
farGrabJoints.leftFarGrabRotation[3]);
|
||||
glm::vec3 rightFarGrabPosition = glm::vec3(farGrabJoints.rightFarGrabPosition[0],
|
||||
farGrabJoints.rightFarGrabPosition[1],
|
||||
farGrabJoints.rightFarGrabPosition[2]);
|
||||
glm::quat rightFarGrabRotation = glm::quat(farGrabJoints.rightFarGrabRotation[0],
|
||||
farGrabJoints.rightFarGrabRotation[1],
|
||||
farGrabJoints.rightFarGrabRotation[2],
|
||||
farGrabJoints.rightFarGrabRotation[3]);
|
||||
glm::vec3 mouseFarGrabPosition = glm::vec3(farGrabJoints.mouseFarGrabPosition[0],
|
||||
farGrabJoints.mouseFarGrabPosition[1],
|
||||
farGrabJoints.mouseFarGrabPosition[2]);
|
||||
glm::quat mouseFarGrabRotation = glm::quat(farGrabJoints.mouseFarGrabRotation[0],
|
||||
farGrabJoints.mouseFarGrabRotation[1],
|
||||
farGrabJoints.mouseFarGrabRotation[2],
|
||||
farGrabJoints.mouseFarGrabRotation[3]);
|
||||
|
||||
_farGrabLeftMatrixCache.set(createMatFromQuatAndPos(leftFarGrabRotation, leftFarGrabPosition));
|
||||
_farGrabRightMatrixCache.set(createMatFromQuatAndPos(rightFarGrabRotation, rightFarGrabPosition));
|
||||
_farGrabMouseMatrixCache.set(createMatFromQuatAndPos(mouseFarGrabRotation, mouseFarGrabPosition));
|
||||
|
||||
sourceBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition);
|
||||
sourceBuffer += sizeof(AvatarDataPacket::FarGrabJoints);
|
||||
int numBytesRead = sourceBuffer - startSection;
|
||||
_farGrabJointRate.increment(numBytesRead);
|
||||
_farGrabJointUpdateRate.increment();
|
||||
|
|
|
@ -131,6 +131,10 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
|
|||
requestedProperties += PROP_CLONE_AVATAR_ENTITY;
|
||||
requestedProperties += PROP_CLONE_ORIGIN_ID;
|
||||
|
||||
withReadLock([&] {
|
||||
requestedProperties += _grabProperties.getEntityProperties(params);
|
||||
});
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
|
@ -168,6 +172,9 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
|||
EntityPropertyFlags propertyFlags(PROP_LAST_ITEM);
|
||||
EntityPropertyFlags requestedProperties = getEntityProperties(params);
|
||||
|
||||
requestedProperties -= PROP_CLIENT_ONLY;
|
||||
requestedProperties -= PROP_OWNING_AVATAR_ID;
|
||||
|
||||
// If we are being called for a subsequent pass at appendEntityData() that failed to completely encode this item,
|
||||
// then our entityTreeElementExtraEncodeData should include data about which properties we need to append.
|
||||
if (entityTreeElementExtraEncodeData && entityTreeElementExtraEncodeData->entities.contains(getEntityItemID())) {
|
||||
|
@ -300,7 +307,12 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
|
|||
APPEND_ENTITY_PROPERTY(PROP_CLONE_LIMIT, getCloneLimit());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, getCloneDynamic());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, getCloneAvatarEntity());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, getCloneOriginID());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, getCloneOriginID());
|
||||
|
||||
withReadLock([&] {
|
||||
_grabProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
});
|
||||
|
||||
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
|
||||
requestedProperties,
|
||||
|
@ -892,7 +904,15 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
READ_ENTITY_PROPERTY(PROP_CLONE_LIMIT, float, setCloneLimit);
|
||||
READ_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, bool, setCloneDynamic);
|
||||
READ_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, bool, setCloneAvatarEntity);
|
||||
READ_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, QUuid, setCloneOriginID);
|
||||
READ_ENTITY_PROPERTY(PROP_CLONE_ORIGIN_ID, QUuid, setCloneOriginID);
|
||||
|
||||
withWriteLock([&] {
|
||||
int bytesFromGrab = _grabProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData,
|
||||
somethingChanged);
|
||||
bytesRead += bytesFromGrab;
|
||||
dataAt += bytesFromGrab;
|
||||
});
|
||||
|
||||
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData, somethingChanged);
|
||||
|
@ -1329,6 +1349,10 @@ EntityItemProperties EntityItem::getProperties(const EntityPropertyFlags& desire
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneAvatarEntity, getCloneAvatarEntity);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(cloneOriginID, getCloneOriginID);
|
||||
|
||||
withReadLock([&] {
|
||||
_grabProperties.getProperties(properties);
|
||||
});
|
||||
|
||||
properties._defaultSettings = false;
|
||||
|
||||
return properties;
|
||||
|
@ -1465,6 +1489,11 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneAvatarEntity, setCloneAvatarEntity);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(cloneOriginID, setCloneOriginID);
|
||||
|
||||
withWriteLock([&] {
|
||||
bool grabPropertiesChanged = _grabProperties.setProperties(properties);
|
||||
somethingChanged |= grabPropertiesChanged;
|
||||
});
|
||||
|
||||
if (updateQueryAACube()) {
|
||||
somethingChanged = true;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "SimulationOwner.h"
|
||||
#include "SimulationFlags.h"
|
||||
#include "EntityDynamicInterface.h"
|
||||
#include "GrabPropertyGroup.h"
|
||||
|
||||
#include "graphics/Material.h"
|
||||
|
||||
|
@ -533,6 +534,8 @@ public:
|
|||
void setCloneIDs(const QVector<QUuid>& cloneIDs);
|
||||
void setVisuallyReady(bool visuallyReady) { _visuallyReady = visuallyReady; }
|
||||
|
||||
const GrabPropertyGroup& getGrabProperties() const { return _grabProperties; }
|
||||
|
||||
signals:
|
||||
void requestRenderUpdate();
|
||||
void spaceUpdate(std::pair<int32_t, glm::vec4> data);
|
||||
|
@ -711,6 +714,8 @@ protected:
|
|||
QUuid _cloneOriginID;
|
||||
QVector<QUuid> _cloneIDs;
|
||||
|
||||
GrabPropertyGroup _grabProperties;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, graphics::MultiMaterial> _materials;
|
||||
std::mutex _materialsLock;
|
||||
|
|
|
@ -40,6 +40,7 @@ HazePropertyGroup EntityItemProperties::_staticHaze;
|
|||
BloomPropertyGroup EntityItemProperties::_staticBloom;
|
||||
KeyLightPropertyGroup EntityItemProperties::_staticKeyLight;
|
||||
AmbientLightPropertyGroup EntityItemProperties::_staticAmbientLight;
|
||||
GrabPropertyGroup EntityItemProperties::_staticGrab;
|
||||
|
||||
EntityPropertyList PROP_LAST_ITEM = (EntityPropertyList)(PROP_AFTER_LAST_ITEM - 1);
|
||||
|
||||
|
@ -86,6 +87,7 @@ void EntityItemProperties::debugDump() const {
|
|||
getKeyLight().debugDump();
|
||||
getAmbientLight().debugDump();
|
||||
getBloom().debugDump();
|
||||
getGrab().debugDump();
|
||||
|
||||
qCDebug(entities) << " changed properties...";
|
||||
EntityPropertyFlags props = getChangedProperties();
|
||||
|
@ -471,6 +473,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
changedProperties += _skybox.getChangedProperties();
|
||||
changedProperties += _haze.getChangedProperties();
|
||||
changedProperties += _bloom.getChangedProperties();
|
||||
changedProperties += _grab.getChangedProperties();
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
@ -628,6 +631,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* avatar entities: their <code>clientOnly</code> property will be set to <code>true</code>.
|
||||
* @property {Uuid} cloneOriginID - The ID of the entity that this entity was cloned from.
|
||||
*
|
||||
* @property {Entities.Grab} grab - The grab-related properties.
|
||||
*
|
||||
* @property {string} itemName="" - Certifiable name of the Marketplace item.
|
||||
* @property {string} itemDescription="" - Certifiable description of the Marketplace item.
|
||||
* @property {string} itemCategories="" - Certifiable category of the Marketplace item.
|
||||
|
@ -1530,6 +1535,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_AVATAR_ENTITY, cloneAvatarEntity);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLONE_ORIGIN_ID, cloneOriginID);
|
||||
|
||||
_grab.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||
|
||||
// Rendering info
|
||||
if (!skipDefaults && !strictSemantics &&
|
||||
(!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::RenderInfo))) {
|
||||
|
@ -1700,7 +1707,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeColors, qVectorVec3, setStrokeColors);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths,qVectorFloat, setStrokeWidths);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(isUVModeStretch, bool, setIsUVModeStretch);
|
||||
|
||||
|
||||
|
||||
if (!honorReadOnly) {
|
||||
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
||||
|
@ -1718,6 +1725,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
_skybox.copyFromScriptValue(object, _defaultSettings);
|
||||
_haze.copyFromScriptValue(object, _defaultSettings);
|
||||
_bloom.copyFromScriptValue(object, _defaultSettings);
|
||||
_grab.copyFromScriptValue(object, _defaultSettings);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(xTextureURL, QString, setXTextureURL);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(yTextureURL, QString, setYTextureURL);
|
||||
|
@ -1883,6 +1891,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
_skybox.merge(other._skybox);
|
||||
_haze.merge(other._haze);
|
||||
_bloom.merge(other._bloom);
|
||||
_grab.merge(other._grab);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(xTextureURL);
|
||||
COPY_PROPERTY_IF_CHANGED(yTextureURL);
|
||||
|
@ -2172,6 +2181,26 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_PROPERTY_TO_MAP(PROP_CLONE_AVATAR_ENTITY, CloneAvatarEntity, cloneAvatarEntity, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_CLONE_ORIGIN_ID, CloneOriginID, cloneOriginID, QUuid);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_GRABBABLE, Grab, grab, Grabbable, grabbable);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_KINEMATIC, Grab, grab, GrabKinematic, grabKinematic);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_FOLLOWS_CONTROLLER, Grab, grab, GrabFollowsController, grabFollowsController);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_TRIGGERABLE, Grab, grab, Triggerable, triggerable);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE, Grab, grab, Equippable, equippable);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, Grab, grab,
|
||||
EquippableLeftPosition, equippableLeftPosition);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab,
|
||||
EquippableLeftRotation, equippableLeftRotation);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, Grab, grab,
|
||||
EquippableRightPosition, equippableRightPosition);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab,
|
||||
EquippableRightRotation, equippableRightRotation);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, Grab, grab,
|
||||
EquippableIndicatorURL, equippableIndicatorURL);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, Grab, grab,
|
||||
EquippableIndicatorScale, equippableIndicatorScale);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, Grab, grab,
|
||||
EquippableIndicatorOffset, equippableIndicatorOffset);
|
||||
|
||||
// FIXME - these are not yet handled
|
||||
//ADD_PROPERTY_TO_MAP(PROP_CREATED, Created, created, quint64);
|
||||
|
||||
|
@ -2501,6 +2530,10 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
APPEND_ENTITY_PROPERTY(PROP_CLONE_LIMIT, properties.getCloneLimit());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CLONE_DYNAMIC, properties.getCloneDynamic());
|
||||
APPEND_ENTITY_PROPERTY(PROP_CLONE_AVATAR_ENTITY, properties.getCloneAvatarEntity());
|
||||
|
||||
_staticGrab.setProperties(properties);
|
||||
_staticGrab.appendToEditPacket(packetData, requestedProperties, propertyFlags,
|
||||
propertiesDidntFit, propertyCount, appendState);
|
||||
}
|
||||
|
||||
if (propertyCount > 0) {
|
||||
|
@ -2794,7 +2827,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FILTER_URL, QString, setFilterURL);
|
||||
|
||||
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_HAZE_MODE, uint32_t, setHazeMode);
|
||||
properties.getHaze().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
|
||||
|
@ -2881,6 +2914,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_DYNAMIC, bool, setCloneDynamic);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CLONE_AVATAR_ENTITY, bool, setCloneAvatarEntity);
|
||||
|
||||
properties.getGrab().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
@ -3120,6 +3155,7 @@ void EntityItemProperties::markAllChanged() {
|
|||
_skybox.markAllChanged();
|
||||
_haze.markAllChanged();
|
||||
_bloom.markAllChanged();
|
||||
_grab.markAllChanged();
|
||||
|
||||
_sourceUrlChanged = true;
|
||||
_voxelVolumeSizeChanged = true;
|
||||
|
@ -3654,6 +3690,7 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
getSkybox().listChangedProperties(out);
|
||||
getHaze().listChangedProperties(out);
|
||||
getBloom().listChangedProperties(out);
|
||||
getGrab().listChangedProperties(out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -292,6 +292,8 @@ public:
|
|||
DEFINE_PROPERTY(PROP_CLONE_AVATAR_ENTITY, CloneAvatarEntity, cloneAvatarEntity, bool, ENTITY_ITEM_DEFAULT_CLONE_AVATAR_ENTITY);
|
||||
DEFINE_PROPERTY_REF(PROP_CLONE_ORIGIN_ID, CloneOriginID, cloneOriginID, QUuid, ENTITY_ITEM_DEFAULT_CLONE_ORIGIN_ID);
|
||||
|
||||
DEFINE_PROPERTY_GROUP(Grab, grab, GrabPropertyGroup);
|
||||
|
||||
static QString getComponentModeString(uint32_t mode);
|
||||
static QString getComponentModeAsString(uint32_t mode);
|
||||
|
||||
|
|
207
libraries/entities/src/EntityPropertyFlags.cpp
Normal file
207
libraries/entities/src/EntityPropertyFlags.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
|
||||
#include "EntityPropertyFlags.h"
|
||||
|
||||
|
||||
QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f) {
|
||||
QString result = "[ ";
|
||||
|
||||
result = f.getHasProperty(PROP_PAGED_PROPERTY) ? result + "pagedProperty " : result;
|
||||
result = f.getHasProperty(PROP_CUSTOM_PROPERTIES_INCLUDED) ? result + "customPropertiesIncluded " : result;
|
||||
result = f.getHasProperty(PROP_VISIBLE) ? result + "visible " : result;
|
||||
result = f.getHasProperty(PROP_CAN_CAST_SHADOW) ? result + "canCastShadow " : result;
|
||||
result = f.getHasProperty(PROP_POSITION) ? result + "position " : result;
|
||||
result = f.getHasProperty(PROP_DIMENSIONS) ? result + "dimensions " : result;
|
||||
result = f.getHasProperty(PROP_ROTATION) ? result + "rotation " : result;
|
||||
result = f.getHasProperty(PROP_DENSITY) ? result + "density " : result;
|
||||
result = f.getHasProperty(PROP_VELOCITY) ? result + "velocity " : result;
|
||||
result = f.getHasProperty(PROP_GRAVITY) ? result + "gravity " : result;
|
||||
result = f.getHasProperty(PROP_DAMPING) ? result + "damping " : result;
|
||||
result = f.getHasProperty(PROP_LIFETIME) ? result + "lifetime " : result;
|
||||
result = f.getHasProperty(PROP_SCRIPT) ? result + "script " : result;
|
||||
result = f.getHasProperty(PROP_COLOR) ? result + "color " : result;
|
||||
result = f.getHasProperty(PROP_MODEL_URL) ? result + "modelUrl " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_URL) ? result + "animationUrl " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_FPS) ? result + "animationFps " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_FRAME_INDEX) ? result + "animationFrameIndex " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_PLAYING) ? result + "animationPlaying " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_ALLOW_TRANSLATION) ? result + "animationAllowTranslation " : result;
|
||||
result = f.getHasProperty(PROP_RELAY_PARENT_JOINTS) ? result + "relayParentJoints " : result;
|
||||
result = f.getHasProperty(PROP_REGISTRATION_POINT) ? result + "registrationPoint " : result;
|
||||
result = f.getHasProperty(PROP_ANGULAR_VELOCITY) ? result + "angularVelocity " : result;
|
||||
result = f.getHasProperty(PROP_ANGULAR_DAMPING) ? result + "angularDamping " : result;
|
||||
result = f.getHasProperty(PROP_COLLISIONLESS) ? result + "collisionless " : result;
|
||||
result = f.getHasProperty(PROP_DYNAMIC) ? result + "dynamic " : result;
|
||||
result = f.getHasProperty(PROP_IS_SPOTLIGHT) ? result + "isSpotlight " : result;
|
||||
result = f.getHasProperty(PROP_DIFFUSE_COLOR) ? result + "diffuseColor " : result;
|
||||
result = f.getHasProperty(PROP_AMBIENT_COLOR_UNUSED) ? result + "ambientColorUnused " : result;
|
||||
result = f.getHasProperty(PROP_SPECULAR_COLOR_UNUSED) ? result + "specularColorUnused " : result;
|
||||
result = f.getHasProperty(PROP_INTENSITY) ? result + "intensity " : result;
|
||||
result = f.getHasProperty(PROP_LINEAR_ATTENUATION_UNUSED) ? result + "linearAttenuationUnused " : result;
|
||||
result = f.getHasProperty(PROP_QUADRATIC_ATTENUATION_UNUSED) ? result + "quadraticAttenuationUnused " : result;
|
||||
result = f.getHasProperty(PROP_EXPONENT) ? result + "exponent " : result;
|
||||
result = f.getHasProperty(PROP_CUTOFF) ? result + "cutoff " : result;
|
||||
result = f.getHasProperty(PROP_LOCKED) ? result + "locked " : result;
|
||||
result = f.getHasProperty(PROP_TEXTURES) ? result + "textures " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_SETTINGS_UNUSED) ? result + "animationSettingsUnused " : result;
|
||||
result = f.getHasProperty(PROP_USER_DATA) ? result + "userData " : result;
|
||||
result = f.getHasProperty(PROP_SHAPE_TYPE) ? result + "shapeType " : result;
|
||||
result = f.getHasProperty(PROP_MAX_PARTICLES) ? result + "maxParticles " : result;
|
||||
result = f.getHasProperty(PROP_LIFESPAN) ? result + "lifespan " : result;
|
||||
result = f.getHasProperty(PROP_EMIT_RATE) ? result + "emitRate " : result;
|
||||
result = f.getHasProperty(PROP_EMIT_SPEED) ? result + "emitSpeed " : result;
|
||||
result = f.getHasProperty(PROP_EMIT_STRENGTH) ? result + "emitStrength " : result;
|
||||
result = f.getHasProperty(PROP_EMIT_ACCELERATION) ? result + "emitAcceleration " : result;
|
||||
result = f.getHasProperty(PROP_PARTICLE_RADIUS) ? result + "particleRadius " : result;
|
||||
result = f.getHasProperty(PROP_COMPOUND_SHAPE_URL) ? result + "compoundShapeUrl " : result;
|
||||
result = f.getHasProperty(PROP_MARKETPLACE_ID) ? result + "marketplaceID " : result;
|
||||
result = f.getHasProperty(PROP_ACCELERATION) ? result + "acceleration " : result;
|
||||
result = f.getHasProperty(PROP_SIMULATION_OWNER) ? result + "simulationOwner " : result;
|
||||
result = f.getHasProperty(PROP_NAME) ? result + "name " : result;
|
||||
result = f.getHasProperty(PROP_COLLISION_SOUND_URL) ? result + "collisionSoundUrl " : result;
|
||||
result = f.getHasProperty(PROP_RESTITUTION) ? result + "restitution " : result;
|
||||
result = f.getHasProperty(PROP_FRICTION) ? result + "friction " : result;
|
||||
result = f.getHasProperty(PROP_VOXEL_VOLUME_SIZE) ? result + "voxelVolumeSize " : result;
|
||||
result = f.getHasProperty(PROP_VOXEL_DATA) ? result + "voxelData " : result;
|
||||
result = f.getHasProperty(PROP_VOXEL_SURFACE_STYLE) ? result + "voxelSurfaceStyle " : result;
|
||||
result = f.getHasProperty(PROP_LINE_WIDTH) ? result + "lineWidth " : result;
|
||||
result = f.getHasProperty(PROP_LINE_POINTS) ? result + "linePoints " : result;
|
||||
result = f.getHasProperty(PROP_HREF) ? result + "href " : result;
|
||||
result = f.getHasProperty(PROP_DESCRIPTION) ? result + "description " : result;
|
||||
result = f.getHasProperty(PROP_FACE_CAMERA) ? result + "faceCamera " : result;
|
||||
result = f.getHasProperty(PROP_SCRIPT_TIMESTAMP) ? result + "scriptTimestamp " : result;
|
||||
result = f.getHasProperty(PROP_ACTION_DATA) ? result + "actionData " : result;
|
||||
result = f.getHasProperty(PROP_X_TEXTURE_URL) ? result + "xTextureUrl " : result;
|
||||
result = f.getHasProperty(PROP_Y_TEXTURE_URL) ? result + "yTextureUrl " : result;
|
||||
result = f.getHasProperty(PROP_Z_TEXTURE_URL) ? result + "zTextureUrl " : result;
|
||||
result = f.getHasProperty(PROP_NORMALS) ? result + "normals " : result;
|
||||
result = f.getHasProperty(PROP_STROKE_COLORS) ? result + "strokeColors " : result;
|
||||
result = f.getHasProperty(PROP_STROKE_WIDTHS) ? result + "strokeWidths " : result;
|
||||
result = f.getHasProperty(PROP_IS_UV_MODE_STRETCH) ? result + "isUvModeStretch " : result;
|
||||
result = f.getHasProperty(PROP_SPEED_SPREAD) ? result + "speedSpread " : result;
|
||||
result = f.getHasProperty(PROP_ACCELERATION_SPREAD) ? result + "accelerationSpread " : result;
|
||||
result = f.getHasProperty(PROP_X_N_NEIGHBOR_ID) ? result + "xNNeighborID " : result;
|
||||
result = f.getHasProperty(PROP_Y_N_NEIGHBOR_ID) ? result + "yNNeighborID " : result;
|
||||
result = f.getHasProperty(PROP_Z_N_NEIGHBOR_ID) ? result + "zNNeighborID " : result;
|
||||
result = f.getHasProperty(PROP_X_P_NEIGHBOR_ID) ? result + "xPNeighborID " : result;
|
||||
result = f.getHasProperty(PROP_Y_P_NEIGHBOR_ID) ? result + "yPNeighborID " : result;
|
||||
result = f.getHasProperty(PROP_Z_P_NEIGHBOR_ID) ? result + "zPNeighborID " : result;
|
||||
result = f.getHasProperty(PROP_RADIUS_SPREAD) ? result + "radiusSpread " : result;
|
||||
result = f.getHasProperty(PROP_RADIUS_START) ? result + "radiusStart " : result;
|
||||
result = f.getHasProperty(PROP_RADIUS_FINISH) ? result + "radiusFinish " : result;
|
||||
result = f.getHasProperty(PROP_ALPHA) ? result + "alpha " : result;
|
||||
result = f.getHasProperty(PROP_COLOR_SPREAD) ? result + "colorSpread " : result;
|
||||
result = f.getHasProperty(PROP_COLOR_START) ? result + "colorStart " : result;
|
||||
result = f.getHasProperty(PROP_COLOR_FINISH) ? result + "colorFinish " : result;
|
||||
result = f.getHasProperty(PROP_ALPHA_SPREAD) ? result + "alphaSpread " : result;
|
||||
result = f.getHasProperty(PROP_ALPHA_START) ? result + "alphaStart " : result;
|
||||
result = f.getHasProperty(PROP_ALPHA_FINISH) ? result + "alphaFinish " : result;
|
||||
result = f.getHasProperty(PROP_EMIT_ORIENTATION) ? result + "emitOrientation " : result;
|
||||
result = f.getHasProperty(PROP_EMIT_DIMENSIONS) ? result + "emitDimensions " : result;
|
||||
result = f.getHasProperty(PROP_EMIT_RADIUS_START) ? result + "emitRadiusStart " : result;
|
||||
result = f.getHasProperty(PROP_POLAR_START) ? result + "polarStart " : result;
|
||||
result = f.getHasProperty(PROP_POLAR_FINISH) ? result + "polarFinish " : result;
|
||||
result = f.getHasProperty(PROP_AZIMUTH_START) ? result + "azimuthStart " : result;
|
||||
result = f.getHasProperty(PROP_AZIMUTH_FINISH) ? result + "azimuthFinish " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_LOOP) ? result + "animationLoop " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_FIRST_FRAME) ? result + "animationFirstFrame " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_LAST_FRAME) ? result + "animationLastFrame " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_HOLD) ? result + "animationHold " : result;
|
||||
result = f.getHasProperty(PROP_ANIMATION_START_AUTOMATICALLY) ? result + "animationStartAutomatically " : result;
|
||||
result = f.getHasProperty(PROP_EMITTER_SHOULD_TRAIL) ? result + "emitterShouldTrail " : result;
|
||||
result = f.getHasProperty(PROP_PARENT_ID) ? result + "parentID " : result;
|
||||
result = f.getHasProperty(PROP_PARENT_JOINT_INDEX) ? result + "parentJointIndex " : result;
|
||||
result = f.getHasProperty(PROP_LOCAL_POSITION) ? result + "localPosition " : result;
|
||||
result = f.getHasProperty(PROP_LOCAL_ROTATION) ? result + "localRotation " : result;
|
||||
result = f.getHasProperty(PROP_QUERY_AA_CUBE) ? result + "queryAaCube " : result;
|
||||
result = f.getHasProperty(PROP_JOINT_ROTATIONS_SET) ? result + "jointRotationsSet " : result;
|
||||
result = f.getHasProperty(PROP_JOINT_ROTATIONS) ? result + "jointRotations " : result;
|
||||
result = f.getHasProperty(PROP_JOINT_TRANSLATIONS_SET) ? result + "jointTranslationsSet " : result;
|
||||
result = f.getHasProperty(PROP_JOINT_TRANSLATIONS) ? result + "jointTranslations " : result;
|
||||
result = f.getHasProperty(PROP_COLLISION_MASK) ? result + "collisionMask " : result;
|
||||
result = f.getHasProperty(PROP_FALLOFF_RADIUS) ? result + "falloffRadius " : result;
|
||||
result = f.getHasProperty(PROP_FLYING_ALLOWED) ? result + "flyingAllowed " : result;
|
||||
result = f.getHasProperty(PROP_GHOSTING_ALLOWED) ? result + "ghostingAllowed " : result;
|
||||
result = f.getHasProperty(PROP_CLIENT_ONLY) ? result + "clientOnly " : result;
|
||||
result = f.getHasProperty(PROP_OWNING_AVATAR_ID) ? result + "owningAvatarID " : result;
|
||||
result = f.getHasProperty(PROP_SHAPE) ? result + "shape " : result;
|
||||
result = f.getHasProperty(PROP_DPI) ? result + "dpi " : result;
|
||||
result = f.getHasProperty(PROP_LOCAL_VELOCITY) ? result + "localVelocity " : result;
|
||||
result = f.getHasProperty(PROP_LOCAL_ANGULAR_VELOCITY) ? result + "localAngularVelocity " : result;
|
||||
result = f.getHasProperty(PROP_LAST_EDITED_BY) ? result + "lastEditedBy " : result;
|
||||
result = f.getHasProperty(PROP_SERVER_SCRIPTS) ? result + "serverScripts " : result;
|
||||
result = f.getHasProperty(PROP_FILTER_URL) ? result + "filterUrl " : result;
|
||||
result = f.getHasProperty(PROP_ITEM_NAME) ? result + "itemName " : result;
|
||||
result = f.getHasProperty(PROP_ITEM_DESCRIPTION) ? result + "itemDescription " : result;
|
||||
result = f.getHasProperty(PROP_ITEM_CATEGORIES) ? result + "itemCategories " : result;
|
||||
result = f.getHasProperty(PROP_ITEM_ARTIST) ? result + "itemArtist " : result;
|
||||
result = f.getHasProperty(PROP_ITEM_LICENSE) ? result + "itemLicense " : result;
|
||||
result = f.getHasProperty(PROP_LIMITED_RUN) ? result + "limitedRun " : result;
|
||||
result = f.getHasProperty(PROP_EDITION_NUMBER) ? result + "editionNumber " : result;
|
||||
result = f.getHasProperty(PROP_ENTITY_INSTANCE_NUMBER) ? result + "entityInstanceNumber " : result;
|
||||
result = f.getHasProperty(PROP_CERTIFICATE_ID) ? result + "certificateID " : result;
|
||||
result = f.getHasProperty(PROP_STATIC_CERTIFICATE_VERSION) ? result + "staticCertificateVersion " : result;
|
||||
result = f.getHasProperty(PROP_CLONEABLE) ? result + "cloneable " : result;
|
||||
result = f.getHasProperty(PROP_CLONE_LIFETIME) ? result + "cloneLifetime " : result;
|
||||
result = f.getHasProperty(PROP_CLONE_LIMIT) ? result + "cloneLimit " : result;
|
||||
result = f.getHasProperty(PROP_CLONE_DYNAMIC) ? result + "cloneDynamic " : result;
|
||||
result = f.getHasProperty(PROP_CLONE_AVATAR_ENTITY) ? result + "cloneAvatarEntity " : result;
|
||||
result = f.getHasProperty(PROP_CLONE_ORIGIN_ID) ? result + "cloneOriginID " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_MODE) ? result + "hazeMode " : result;
|
||||
result = f.getHasProperty(PROP_KEYLIGHT_COLOR) ? result + "keylightColor " : result;
|
||||
result = f.getHasProperty(PROP_KEYLIGHT_INTENSITY) ? result + "keylightIntensity " : result;
|
||||
result = f.getHasProperty(PROP_KEYLIGHT_DIRECTION) ? result + "keylightDirection " : result;
|
||||
result = f.getHasProperty(PROP_KEYLIGHT_CAST_SHADOW) ? result + "keylightCastShadow " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_RANGE) ? result + "hazeRange " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_COLOR) ? result + "hazeColor " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_GLARE_COLOR) ? result + "hazeGlareColor " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_ENABLE_GLARE) ? result + "hazeEnableGlare " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_GLARE_ANGLE) ? result + "hazeGlareAngle " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_ALTITUDE_EFFECT) ? result + "hazeAltitudeEffect " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_CEILING) ? result + "hazeCeiling " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_BASE_REF) ? result + "hazeBaseRef " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_BACKGROUND_BLEND) ? result + "hazeBackgroundBlend " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_ATTENUATE_KEYLIGHT) ? result + "hazeAttenuateKeylight " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_KEYLIGHT_RANGE) ? result + "hazeKeylightRange " : result;
|
||||
result = f.getHasProperty(PROP_HAZE_KEYLIGHT_ALTITUDE) ? result + "hazeKeylightAltitude " : result;
|
||||
result = f.getHasProperty(PROP_KEY_LIGHT_MODE) ? result + "keyLightMode " : result;
|
||||
result = f.getHasProperty(PROP_AMBIENT_LIGHT_MODE) ? result + "ambientLightMode " : result;
|
||||
result = f.getHasProperty(PROP_SKYBOX_MODE) ? result + "skyboxMode " : result;
|
||||
result = f.getHasProperty(PROP_LOCAL_DIMENSIONS) ? result + "localDimensions " : result;
|
||||
result = f.getHasProperty(PROP_MATERIAL_URL) ? result + "materialUrl " : result;
|
||||
result = f.getHasProperty(PROP_MATERIAL_MAPPING_MODE) ? result + "materialMappingMode " : result;
|
||||
result = f.getHasProperty(PROP_MATERIAL_PRIORITY) ? result + "materialPriority " : result;
|
||||
result = f.getHasProperty(PROP_PARENT_MATERIAL_NAME) ? result + "parentMaterialName " : result;
|
||||
result = f.getHasProperty(PROP_MATERIAL_MAPPING_POS) ? result + "materialMappingPos " : result;
|
||||
result = f.getHasProperty(PROP_MATERIAL_MAPPING_SCALE) ? result + "materialMappingScale " : result;
|
||||
result = f.getHasProperty(PROP_MATERIAL_MAPPING_ROT) ? result + "materialMappingRot " : result;
|
||||
result = f.getHasProperty(PROP_MATERIAL_DATA) ? result + "materialData " : result;
|
||||
result = f.getHasProperty(PROP_VISIBLE_IN_SECONDARY_CAMERA) ? result + "visibleInSecondaryCamera " : result;
|
||||
result = f.getHasProperty(PROP_PARTICLE_SPIN) ? result + "particleSpin " : result;
|
||||
result = f.getHasProperty(PROP_SPIN_START) ? result + "spinStart " : result;
|
||||
result = f.getHasProperty(PROP_SPIN_FINISH) ? result + "spinFinish " : result;
|
||||
result = f.getHasProperty(PROP_SPIN_SPREAD) ? result + "spinSpread " : result;
|
||||
result = f.getHasProperty(PROP_PARTICLE_ROTATE_WITH_ENTITY) ? result + "particleRotateWithEntity " : result;
|
||||
result = f.getHasProperty(PROP_BLOOM_INTENSITY) ? result + "bloomIntensity " : result;
|
||||
result = f.getHasProperty(PROP_BLOOM_THRESHOLD) ? result + "bloomThreshold " : result;
|
||||
result = f.getHasProperty(PROP_BLOOM_SIZE) ? result + "bloomSize " : result;
|
||||
result = f.getHasProperty(PROP_GRAB_GRABBABLE) ? result + "grab.Grabbable " : result;
|
||||
result = f.getHasProperty(PROP_GRAB_KINEMATIC) ? result + "grab.Kinematic " : result;
|
||||
result = f.getHasProperty(PROP_GRAB_FOLLOWS_CONTROLLER) ? result + "grab.FollowsController " : result;
|
||||
result = f.getHasProperty(PROP_GRAB_TRIGGERABLE) ? result + "grab.Triggerable " : result;
|
||||
result = f.getHasProperty(PROP_GRAB_EQUIPPABLE) ? result + "grab.Equippable " : result;
|
||||
result =
|
||||
f.getHasProperty(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET) ? result + "grab.LeftEquippablePositionOffset " : result;
|
||||
result =
|
||||
f.getHasProperty(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET) ? result + "grab.LeftEquippableRotationOffset " : result;
|
||||
result =
|
||||
f.getHasProperty(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET) ? result + "grab.RightEquippablePositionOffset " : result;
|
||||
result =
|
||||
f.getHasProperty(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET) ? result + "grab.RightEquippableRotationOffset " : result;
|
||||
result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_URL) ? result + "grab.EquippableIndicatorURL " : result;
|
||||
result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE) ? result + "grab.EquippableIndicatorScale " : result;
|
||||
result = f.getHasProperty(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET) ? result + "grab.EquippableIndicatorOffset " : result;
|
||||
|
||||
result += "]";
|
||||
dbg.nospace() << result;
|
||||
return dbg;
|
||||
}
|
|
@ -262,6 +262,19 @@ enum EntityPropertyList {
|
|||
PROP_BLOOM_THRESHOLD,
|
||||
PROP_BLOOM_SIZE,
|
||||
|
||||
PROP_GRAB_GRABBABLE,
|
||||
PROP_GRAB_KINEMATIC,
|
||||
PROP_GRAB_FOLLOWS_CONTROLLER,
|
||||
PROP_GRAB_TRIGGERABLE,
|
||||
PROP_GRAB_EQUIPPABLE,
|
||||
PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET,
|
||||
PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET,
|
||||
PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET,
|
||||
PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET,
|
||||
PROP_GRAB_EQUIPPABLE_INDICATOR_URL,
|
||||
PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE,
|
||||
PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ATTENTION: add new properties to end of list just ABOVE this line
|
||||
PROP_AFTER_LAST_ITEM,
|
||||
|
@ -304,5 +317,10 @@ typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
|||
// one greater than the last item property due to the enum's auto-incrementing.
|
||||
extern EntityPropertyList PROP_LAST_ITEM;
|
||||
|
||||
QString EntityPropertyFlagsToString(EntityPropertyFlags propertiesFlags);
|
||||
|
||||
|
||||
QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f);
|
||||
|
||||
|
||||
#endif // hifi_EntityPropertyFlags_h
|
||||
|
|
|
@ -668,7 +668,7 @@ void EntityTree::unhookChildAvatar(const EntityItemID entityID) {
|
|||
void EntityTree::cleanupCloneIDs(const EntityItemID& entityID) {
|
||||
EntityItemPointer entity = findEntityByEntityItemID(entityID);
|
||||
if (entity) {
|
||||
// remove clone ID from it's clone origin's clone ID list if clone origin exists
|
||||
// remove clone ID from its clone origin's clone ID list if clone origin exists
|
||||
const QUuid& cloneOriginID = entity->getCloneOriginID();
|
||||
if (!cloneOriginID.isNull()) {
|
||||
EntityItemPointer cloneOrigin = findEntityByID(cloneOriginID);
|
||||
|
@ -2558,7 +2558,7 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
|||
if (needsConversion && (properties.getType() == EntityTypes::EntityType::Zone)) {
|
||||
// The legacy version had no keylight mode - this is set to on
|
||||
properties.setKeyLightMode(COMPONENT_MODE_ENABLED);
|
||||
|
||||
|
||||
// The ambient URL has been moved from "keyLight" to "ambientLight"
|
||||
if (entityMap.contains("keyLight")) {
|
||||
QVariantMap keyLightObject = entityMap["keyLight"].toMap();
|
||||
|
@ -2629,6 +2629,108 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
|||
}
|
||||
}
|
||||
|
||||
// convert old grab-related userData to new grab properties
|
||||
if (contentVersion < (int)EntityVersion::GrabProperties) {
|
||||
QJsonObject userData = QJsonDocument::fromJson(properties.getUserData().toUtf8()).object();
|
||||
QJsonObject grabbableKey = userData["grabbableKey"].toObject();
|
||||
QJsonValue wantsTrigger = grabbableKey["wantsTrigger"];
|
||||
|
||||
GrabPropertyGroup& grabProperties = properties.getGrab();
|
||||
|
||||
if (wantsTrigger.isBool()) {
|
||||
grabProperties.setTriggerable(wantsTrigger.toBool());
|
||||
}
|
||||
QJsonValue triggerable = grabbableKey["triggerable"];
|
||||
if (triggerable.isBool()) {
|
||||
grabProperties.setTriggerable(triggerable.toBool());
|
||||
}
|
||||
QJsonValue grabbable = grabbableKey["grabbable"];
|
||||
if (grabbable.isBool()) {
|
||||
grabProperties.setGrabbable(grabbable.toBool());
|
||||
}
|
||||
QJsonValue ignoreIK = grabbableKey["ignoreIK"];
|
||||
if (ignoreIK.isBool()) {
|
||||
grabProperties.setGrabFollowsController(ignoreIK.toBool());
|
||||
}
|
||||
QJsonValue kinematic = grabbableKey["kinematic"];
|
||||
if (kinematic.isBool()) {
|
||||
grabProperties.setGrabKinematic(kinematic.toBool());
|
||||
}
|
||||
|
||||
if (grabbableKey["spatialKey"].isObject()) {
|
||||
QJsonObject spatialKey = grabbableKey["spatialKey"].toObject();
|
||||
grabProperties.setEquippable(true);
|
||||
if (spatialKey["leftRelativePosition"].isObject()) {
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(spatialKey["leftRelativePosition"].toVariant()));
|
||||
}
|
||||
if (spatialKey["rightRelativePosition"].isObject()) {
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(spatialKey["rightRelativePosition"].toVariant()));
|
||||
}
|
||||
if (spatialKey["relativeRotation"].isObject()) {
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(spatialKey["relativeRotation"].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(spatialKey["relativeRotation"].toVariant()));
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject wearable = userData["wearable"].toObject();
|
||||
QJsonObject joints = wearable["joints"].toObject();
|
||||
if (joints["LeftHand"].isArray()) {
|
||||
QJsonArray leftHand = joints["LeftHand"].toArray();
|
||||
if (leftHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(leftHand[0].toVariant()));
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(leftHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
if (joints["RightHand"].isArray()) {
|
||||
QJsonArray rightHand = joints["RightHand"].toArray();
|
||||
if (rightHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(rightHand[0].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(rightHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
|
||||
if (userData["equipHotspots"].isArray()) {
|
||||
QJsonArray equipHotspots = userData["equipHotspots"].toArray();
|
||||
if (equipHotspots.size() > 0) {
|
||||
// just take the first one
|
||||
QJsonObject firstHotSpot = equipHotspots[0].toObject();
|
||||
QJsonObject joints = firstHotSpot["joints"].toObject();
|
||||
if (joints["LeftHand"].isArray()) {
|
||||
QJsonArray leftHand = joints["LeftHand"].toArray();
|
||||
if (leftHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(leftHand[0].toVariant()));
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(leftHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
if (joints["RightHand"].isArray()) {
|
||||
QJsonArray rightHand = joints["RightHand"].toArray();
|
||||
if (rightHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(rightHand[0].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(rightHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
QJsonValue indicatorURL = firstHotSpot["modelURL"];
|
||||
if (indicatorURL.isString()) {
|
||||
grabProperties.setEquippableIndicatorURL(indicatorURL.toString());
|
||||
}
|
||||
QJsonValue indicatorScale = firstHotSpot["modelScale"];
|
||||
if (indicatorScale.isDouble()) {
|
||||
grabProperties.setEquippableIndicatorScale(glm::vec3((float)indicatorScale.toDouble()));
|
||||
} else if (indicatorScale.isObject()) {
|
||||
grabProperties.setEquippableIndicatorScale(qMapToVec3(indicatorScale.toVariant()));
|
||||
}
|
||||
QJsonValue indicatorOffset = firstHotSpot["position"];
|
||||
if (indicatorOffset.isObject()) {
|
||||
grabProperties.setEquippableIndicatorOffset(qMapToVec3(indicatorOffset.toVariant()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Zero out the spread values that were fixed in version ParticleEntityFix so they behave the same as before
|
||||
if (contentVersion < (int)EntityVersion::ParticleEntityFix) {
|
||||
properties.setRadiusSpread(0.0f);
|
||||
|
|
303
libraries/entities/src/GrabPropertyGroup.cpp
Normal file
303
libraries/entities/src/GrabPropertyGroup.cpp
Normal file
|
@ -0,0 +1,303 @@
|
|||
//
|
||||
// GrabPropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Seth Alves on 2018-8-8.
|
||||
// Copyright 2018 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 "GrabPropertyGroup.h"
|
||||
|
||||
#include <OctreePacketData.h>
|
||||
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
void GrabPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties,
|
||||
QScriptEngine* engine, bool skipDefaults,
|
||||
EntityItemProperties& defaultEntityProperties) const {
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_GRABBABLE, Grab, grab, Grabbable, grabbable);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_KINEMATIC, Grab, grab, GrabKinematic, grabKinematic);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_FOLLOWS_CONTROLLER, Grab, grab, GrabFollowsController, grabFollowsController);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_TRIGGERABLE, Grab, grab, Triggerable, triggerable);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE, Grab, grab, Equippable, equippable);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, Grab, grab,
|
||||
EquippableLeftPosition, equippableLeftPosition);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab,
|
||||
EquippableLeftRotation, equippableLeftRotation);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, Grab, grab,
|
||||
EquippableRightPosition, equippableRightPosition);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, Grab, grab,
|
||||
EquippableRightRotation, equippableRightRotation);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, Grab, grab,
|
||||
EquippableIndicatorURL, equippableIndicatorURL);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, Grab, grab,
|
||||
EquippableIndicatorScale, equippableIndicatorScale);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, Grab, grab,
|
||||
EquippableIndicatorOffset, equippableIndicatorOffset);
|
||||
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, grabbable, bool, setGrabbable);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, grabKinematic, bool, setGrabKinematic);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, grabFollowsController, bool, setGrabFollowsController);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, triggerable, bool, setTriggerable);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippable, bool, setEquippable);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableLeftPosition, vec3, setEquippableLeftPosition);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableLeftRotation, quat, setEquippableLeftRotation);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableRightPosition, vec3, setEquippableRightPosition);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableRightRotation, quat, setEquippableRightRotation);
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::merge(const GrabPropertyGroup& other) {
|
||||
COPY_PROPERTY_IF_CHANGED(grabbable);
|
||||
COPY_PROPERTY_IF_CHANGED(grabKinematic);
|
||||
COPY_PROPERTY_IF_CHANGED(grabFollowsController);
|
||||
COPY_PROPERTY_IF_CHANGED(triggerable);
|
||||
COPY_PROPERTY_IF_CHANGED(equippable);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableLeftPosition);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableLeftRotation);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableRightPosition);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableRightRotation);
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::debugDump() const {
|
||||
qCDebug(entities) << " GrabPropertyGroup: ---------------------------------------------";
|
||||
|
||||
qCDebug(entities) << " _grabbable:" << _grabbable;
|
||||
qCDebug(entities) << " _grabKinematic:" << _grabKinematic;
|
||||
qCDebug(entities) << " _grabFollowsController:" << _grabFollowsController;
|
||||
qCDebug(entities) << " _triggerable:" << _triggerable;
|
||||
qCDebug(entities) << " _equippable:" << _equippable;
|
||||
qCDebug(entities) << " _equippableLeftPosition:" << _equippableLeftPosition;
|
||||
qCDebug(entities) << " _equippableLeftRotation:" << _equippableLeftRotation;
|
||||
qCDebug(entities) << " _equippableRightPosition:" << _equippableRightPosition;
|
||||
qCDebug(entities) << " _equippableRightRotation:" << _equippableRightRotation;
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
if (grabbableChanged()) {
|
||||
out << "grab-grabbable";
|
||||
}
|
||||
if (grabKinematicChanged()) {
|
||||
out << "grab-grabKinematic";
|
||||
}
|
||||
if (grabFollowsControllerChanged()) {
|
||||
out << "grab-followsController";
|
||||
}
|
||||
if (triggerableChanged()) {
|
||||
out << "grab-triggerable";
|
||||
}
|
||||
if (equippableChanged()) {
|
||||
out << "grab-equippable";
|
||||
}
|
||||
if (equippableLeftPositionChanged()) {
|
||||
out << "grab-equippableLeftPosition";
|
||||
}
|
||||
if (equippableLeftRotationChanged()) {
|
||||
out << "grab-equippableLeftRotation";
|
||||
}
|
||||
if (equippableRightPositionChanged()) {
|
||||
out << "grab-equippableRightPosition";
|
||||
}
|
||||
if (equippableRightRotationChanged()) {
|
||||
out << "grab-equippableRightRotation";
|
||||
}
|
||||
}
|
||||
|
||||
bool GrabPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_GRABBABLE, getGrabbable());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_KINEMATIC, getGrabKinematic());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, getGrabFollowsController());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_TRIGGERABLE, getTriggerable());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE, getEquippable());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, getEquippableLeftPosition());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, getEquippableLeftRotation());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, getEquippableRightPosition());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, getEquippableRightRotation());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, getEquippableIndicatorURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, getEquippableIndicatorScale());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, getEquippableIndicatorOffset());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrabPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags,
|
||||
const unsigned char*& dataAt , int& processedBytes) {
|
||||
|
||||
int bytesRead = 0;
|
||||
bool overwriteLocalData = true;
|
||||
bool somethingChanged = false;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_GRABBABLE, bool, setGrabbable);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_KINEMATIC, bool, setGrabKinematic);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, bool, setGrabFollowsController);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_TRIGGERABLE, bool, setTriggerable);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE, bool, setEquippable);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, glm::vec3, setEquippableLeftPosition);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, glm::quat, setEquippableLeftRotation);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, glm::vec3, setEquippableRightPosition);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, glm::quat, setEquippableRightRotation);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, QString, setEquippableIndicatorURL);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, glm::vec3, setEquippableIndicatorScale);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, glm::vec3, setEquippableIndicatorOffset);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_GRABBABLE, Grabbable);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_KINEMATIC, GrabKinematic);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_FOLLOWS_CONTROLLER, GrabFollowsController);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_TRIGGERABLE, Triggerable);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_EQUIPPABLE, Equippable);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, EquippableLeftPosition);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, EquippableLeftRotation);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, EquippableRightPosition);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, EquippableRightRotation);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, EquippableIndicatorURL);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, EquippableIndicatorScale);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, EquippableIndicatorOffset);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
Q_UNUSED(somethingChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::markAllChanged() {
|
||||
_grabbableChanged = true;
|
||||
_grabKinematicChanged = true;
|
||||
_grabFollowsControllerChanged = true;
|
||||
_triggerableChanged = true;
|
||||
_equippableChanged = true;
|
||||
_equippableLeftPositionChanged = true;
|
||||
_equippableLeftRotationChanged = true;
|
||||
_equippableRightPositionChanged = true;
|
||||
_equippableRightRotationChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags GrabPropertyGroup::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_GRABBABLE, grabbable);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_KINEMATIC, grabKinematic);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_FOLLOWS_CONTROLLER, grabFollowsController);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_TRIGGERABLE, triggerable);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_EQUIPPABLE, equippable);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, equippableLeftPosition);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, equippableLeftRotation);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, equippableRightPosition);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, equippableRightRotation);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, equippableIndicatorURL);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, equippableIndicatorScale);
|
||||
CHECK_PROPERTY_CHANGE(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, equippableIndicatorOffset);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::getProperties(EntityItemProperties& properties) const {
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, Grabbable, getGrabbable);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, GrabKinematic, getGrabKinematic);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, GrabFollowsController, getGrabFollowsController);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, Triggerable, getTriggerable);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, Equippable, getEquippable);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableLeftPosition, getEquippableLeftPosition);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableLeftRotation, getEquippableLeftRotation);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableRightPosition, getEquippableRightPosition);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableRightRotation, getEquippableRightRotation);
|
||||
}
|
||||
|
||||
bool GrabPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, Grabbable, grabbable, setGrabbable);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, GrabKinematic, grabKinematic, setGrabKinematic);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, GrabFollowsController, grabFollowsController, setGrabFollowsController);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, Triggerable, triggerable, setTriggerable);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, Equippable, equippable, setEquippable);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableLeftPosition, equippableLeftPosition, setEquippableLeftPosition);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableLeftRotation, equippableLeftRotation, setEquippableLeftRotation);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableRightPosition, equippableRightPosition,
|
||||
setEquippableRightPosition);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableRightRotation, equippableRightRotation,
|
||||
setEquippableRightRotation);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
EntityPropertyFlags GrabPropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
EntityPropertyFlags requestedProperties;
|
||||
|
||||
requestedProperties += PROP_GRAB_GRABBABLE;
|
||||
requestedProperties += PROP_GRAB_KINEMATIC;
|
||||
requestedProperties += PROP_GRAB_FOLLOWS_CONTROLLER;
|
||||
requestedProperties += PROP_GRAB_TRIGGERABLE;
|
||||
requestedProperties += PROP_GRAB_EQUIPPABLE;
|
||||
requestedProperties += PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET;
|
||||
requestedProperties += PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET;
|
||||
requestedProperties += PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET;
|
||||
requestedProperties += PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET;
|
||||
requestedProperties += PROP_GRAB_EQUIPPABLE_INDICATOR_URL;
|
||||
requestedProperties += PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE;
|
||||
requestedProperties += PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_GRABBABLE, getGrabbable());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_KINEMATIC, getGrabKinematic());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, getGrabFollowsController());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_TRIGGERABLE, getTriggerable());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE, getEquippable());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, getEquippableLeftPosition());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, getEquippableLeftRotation());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, getEquippableRightPosition());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, getEquippableRightRotation());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, getEquippableIndicatorURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, getEquippableIndicatorScale());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, getEquippableIndicatorOffset());
|
||||
}
|
||||
|
||||
int GrabPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) {
|
||||
|
||||
int bytesRead = 0;
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_GRABBABLE, bool, setGrabbable);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_KINEMATIC, bool, setGrabKinematic);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, bool, setGrabFollowsController);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_TRIGGERABLE, bool, setTriggerable);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE, bool, setEquippable);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, glm::vec3, setEquippableLeftPosition);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, glm::quat, setEquippableLeftRotation);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, glm::vec3, setEquippableRightPosition);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, glm::quat, setEquippableRightRotation);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, QString, setEquippableIndicatorURL);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, glm::vec3, setEquippableIndicatorScale);
|
||||
READ_ENTITY_PROPERTY(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, glm::vec3, setEquippableIndicatorOffset);
|
||||
|
||||
return bytesRead;
|
||||
}
|
141
libraries/entities/src/GrabPropertyGroup.h
Normal file
141
libraries/entities/src/GrabPropertyGroup.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
//
|
||||
// GrabPropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Seth Alves on 2018-8-8.
|
||||
// Copyright 2018 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
|
||||
//
|
||||
|
||||
#ifndef hifi_GrabPropertyGroup_h
|
||||
#define hifi_GrabPropertyGroup_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include "PropertyGroup.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
class EntityItemProperties;
|
||||
class EncodeBitstreamParams;
|
||||
class OctreePacketData;
|
||||
class ReadBitstreamToTreeParams;
|
||||
|
||||
static const bool INITIAL_GRABBABLE { true };
|
||||
static const bool INITIAL_KINEMATIC { true };
|
||||
static const bool INITIAL_FOLLOWS_CONTROLLER { true };
|
||||
static const bool INITIAL_TRIGGERABLE { false };
|
||||
static const bool INITIAL_EQUIPPABLE { false };
|
||||
static const glm::vec3 INITIAL_LEFT_EQUIPPABLE_POSITION { glm::vec3(0.0f) };
|
||||
static const glm::quat INITIAL_LEFT_EQUIPPABLE_ROTATION { glm::quat() };
|
||||
static const glm::vec3 INITIAL_RIGHT_EQUIPPABLE_POSITION { glm::vec3(0.0f) };
|
||||
static const glm::quat INITIAL_RIGHT_EQUIPPABLE_ROTATION { glm::quat() };
|
||||
static const glm::vec3 INITIAL_EQUIPPABLE_INDICATOR_SCALE { glm::vec3(1.0f) };
|
||||
static const glm::vec3 INITIAL_EQUIPPABLE_INDICATOR_OFFSET { glm::vec3(0.0f) };
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Grab is defined by the following properties.
|
||||
* @typedef {object} Entities.Grab
|
||||
*
|
||||
* @property {boolean} grabbable=true - If <code>true</code> the entity can be grabbed.
|
||||
* @property {boolean} grabKinematic=true - If <code>true</code> the entity is updated in a kinematic manner.
|
||||
* If <code>false</code> it will be grabbed using a tractor action. A kinematic grab will make the item appear more
|
||||
* tightly held, but will cause it to behave poorly when interacting with dynamic entities.
|
||||
* @property {boolean} grabFollowsController=true - If <code>true</code> the entity will follow the motions of the
|
||||
* hand-controller even if the avatar's hand can't get to the implied position. This should be <code>true</code>
|
||||
* for tools, pens, etc and false for things meant to decorate the hand.
|
||||
*
|
||||
* @property {boolean} triggerable=false - If <code>true</code> the entity will receive calls to trigger
|
||||
* {@link Controller|Controller entity methods}.
|
||||
*
|
||||
* @property {boolean} equippable=true - If <code>true</code> the entity can be equipped.
|
||||
* @property {Vec3} equippableLeftPosition=0,0,0 - Positional offset from the left hand, when equipped.
|
||||
* @property {Quat} equippableLeftRotation=0,0,0,1 - Rotational offset from the left hand, when equipped.
|
||||
* @property {Vec3} equippableRightPosition=0,0,0 - Positional offset from the right hand, when equipped.
|
||||
* @property {Quat} equippableRightRotation=0,0,0,1 - Rotational offset from the right hand, when equipped.
|
||||
*
|
||||
* @property {string} equippableIndicatorURL="" - If non-empty, this model will be used to indicate that an
|
||||
* entity is equippable, rather than the default.
|
||||
* @property {Vec3} equippableIndicatorScale=1,1,1 - If equippableIndicatorURL is non-empty, this controls the
|
||||
scale of the displayed overlay.
|
||||
* @property {Vec3} equippableIndicatorOffset=0,0,0 - If equippableIndicatorURL is non-empty, this controls the
|
||||
relative offset of the displayed overlay from the equippable entity.
|
||||
*/
|
||||
|
||||
|
||||
class GrabPropertyGroup : public PropertyGroup {
|
||||
public:
|
||||
// EntityItemProperty related helpers
|
||||
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties,
|
||||
QScriptEngine* engine, bool skipDefaults,
|
||||
EntityItemProperties& defaultEntityProperties) const override;
|
||||
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) override;
|
||||
|
||||
void merge(const GrabPropertyGroup& other);
|
||||
|
||||
virtual void debugDump() const override;
|
||||
virtual void listChangedProperties(QList<QString>& out) override;
|
||||
|
||||
virtual bool appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags,
|
||||
const unsigned char*& dataAt, int& processedBytes) override;
|
||||
virtual void markAllChanged() override;
|
||||
virtual EntityPropertyFlags getChangedProperties() const override;
|
||||
|
||||
// EntityItem related helpers
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual void getProperties(EntityItemProperties& propertiesOut) const override;
|
||||
|
||||
// returns true if something changed
|
||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
// grab properties
|
||||
DEFINE_PROPERTY(PROP_GRAB_GRABBABLE, Grabbable, grabbable, bool, INITIAL_GRABBABLE);
|
||||
DEFINE_PROPERTY(PROP_GRAB_KINEMATIC, GrabKinematic, grabKinematic, bool, INITIAL_KINEMATIC);
|
||||
DEFINE_PROPERTY(PROP_GRAB_FOLLOWS_CONTROLLER, GrabFollowsController, grabFollowsController, bool,
|
||||
INITIAL_FOLLOWS_CONTROLLER);
|
||||
DEFINE_PROPERTY(PROP_GRAB_TRIGGERABLE, Triggerable, triggerable, bool, INITIAL_TRIGGERABLE);
|
||||
DEFINE_PROPERTY(PROP_GRAB_EQUIPPABLE, Equippable, equippable, bool, INITIAL_EQUIPPABLE);
|
||||
DEFINE_PROPERTY_REF(PROP_GRAB_LEFT_EQUIPPABLE_POSITION_OFFSET, EquippableLeftPosition, equippableLeftPosition,
|
||||
glm::vec3, INITIAL_LEFT_EQUIPPABLE_POSITION);
|
||||
DEFINE_PROPERTY_REF(PROP_GRAB_LEFT_EQUIPPABLE_ROTATION_OFFSET, EquippableLeftRotation, equippableLeftRotation,
|
||||
glm::quat, INITIAL_LEFT_EQUIPPABLE_ROTATION);
|
||||
DEFINE_PROPERTY_REF(PROP_GRAB_RIGHT_EQUIPPABLE_POSITION_OFFSET, EquippableRightPosition, equippableRightPosition,
|
||||
glm::vec3, INITIAL_RIGHT_EQUIPPABLE_POSITION);
|
||||
DEFINE_PROPERTY_REF(PROP_GRAB_RIGHT_EQUIPPABLE_ROTATION_OFFSET, EquippableRightRotation, equippableRightRotation,
|
||||
glm::quat, INITIAL_RIGHT_EQUIPPABLE_ROTATION);
|
||||
DEFINE_PROPERTY_REF(PROP_GRAB_EQUIPPABLE_INDICATOR_URL, EquippableIndicatorURL, equippableIndicatorURL, QString, "");
|
||||
DEFINE_PROPERTY_REF(PROP_GRAB_EQUIPPABLE_INDICATOR_SCALE, EquippableIndicatorScale, equippableIndicatorScale,
|
||||
glm::vec3, INITIAL_EQUIPPABLE_INDICATOR_SCALE);
|
||||
DEFINE_PROPERTY_REF(PROP_GRAB_EQUIPPABLE_INDICATOR_OFFSET, EquippableIndicatorOffset, equippableIndicatorOffset,
|
||||
glm::vec3, INITIAL_EQUIPPABLE_INDICATOR_OFFSET);
|
||||
};
|
||||
|
||||
#endif // hifi_GrabPropertyGroup_h
|
|
@ -33,14 +33,14 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::EntityEdit:
|
||||
case PacketType::EntityData:
|
||||
case PacketType::EntityPhysics:
|
||||
return static_cast<PacketVersion>(EntityVersion::BloomEffect);
|
||||
return static_cast<PacketVersion>(EntityVersion::GrabProperties);
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::ConicalFrustums);
|
||||
case PacketType::AvatarIdentity:
|
||||
case PacketType::AvatarData:
|
||||
case PacketType::BulkAvatarData:
|
||||
case PacketType::KillAvatar:
|
||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::MigrateAvatarEntitiesToTraits);
|
||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::FarGrabJointsRedux);
|
||||
case PacketType::MessagesData:
|
||||
return static_cast<PacketVersion>(MessageDataVersion::TextOrBinaryData);
|
||||
// ICE packets
|
||||
|
|
|
@ -242,7 +242,8 @@ enum class EntityVersion : PacketVersion {
|
|||
YieldSimulationOwnership,
|
||||
ParticleEntityFix,
|
||||
ParticleSpin,
|
||||
BloomEffect
|
||||
BloomEffect,
|
||||
GrabProperties
|
||||
};
|
||||
|
||||
enum class EntityScriptCallMethodVersion : PacketVersion {
|
||||
|
@ -293,7 +294,8 @@ enum class AvatarMixerPacketVersion : PacketVersion {
|
|||
ProceduralFaceMovementFlagsAndBlendshapes,
|
||||
FarGrabJoints,
|
||||
MigrateSkeletonURLToTraits,
|
||||
MigrateAvatarEntitiesToTraits
|
||||
MigrateAvatarEntitiesToTraits,
|
||||
FarGrabJointsRedux
|
||||
};
|
||||
|
||||
enum class DomainConnectRequestVersion : PacketVersion {
|
||||
|
|
|
@ -198,17 +198,17 @@ const unsigned char* OctreePacketData::getFinalizedData() {
|
|||
|
||||
int OctreePacketData::getFinalizedSize() {
|
||||
if (!_enableCompression) {
|
||||
return _bytesInUse;
|
||||
return _bytesInUse;
|
||||
}
|
||||
|
||||
if (_dirty) {
|
||||
if (_debug) {
|
||||
qCDebug(octree, "getFinalizedSize() _compressedBytes=%d _bytesInUse=%d",_compressedBytes, _bytesInUse);
|
||||
}
|
||||
compressContent();
|
||||
compressContent();
|
||||
}
|
||||
|
||||
return _compressedBytes;
|
||||
return _compressedBytes;
|
||||
}
|
||||
|
||||
|
||||
|
@ -604,6 +604,9 @@ bool OctreePacketData::compressContent() {
|
|||
memcpy(_compressed, compressedData.constData(), _compressedBytes);
|
||||
_dirty = false;
|
||||
success = true;
|
||||
} else {
|
||||
qCWarning(octree) << "OctreePacketData::compressContent -- compressedData.size >= MAX_OCTREE_PACKET_DATA_SIZE";
|
||||
assert(false);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -623,11 +626,16 @@ void OctreePacketData::loadFinalizedContent(const unsigned char* data, int lengt
|
|||
memcpy(compressedData.data(), data, _compressedBytes);
|
||||
|
||||
QByteArray uncompressedData = qUncompress(compressedData);
|
||||
if (uncompressedData.size() <= _bytesAvailable) {
|
||||
_bytesInUse = uncompressedData.size();
|
||||
_bytesAvailable -= uncompressedData.size();
|
||||
memcpy(_uncompressed, uncompressedData.constData(), _bytesInUse);
|
||||
if (uncompressedData.size() > _bytesAvailable) {
|
||||
int moreNeeded = uncompressedData.size() - _bytesAvailable;
|
||||
_uncompressedByteArray.resize(_uncompressedByteArray.size() + moreNeeded);
|
||||
_uncompressed = (unsigned char*)_uncompressedByteArray.data();
|
||||
_bytesAvailable += moreNeeded;
|
||||
}
|
||||
|
||||
_bytesInUse = uncompressedData.size();
|
||||
_bytesAvailable -= uncompressedData.size();
|
||||
memcpy(_uncompressed, uncompressedData.constData(), _bytesInUse);
|
||||
} else {
|
||||
memcpy(_uncompressed, data, length);
|
||||
memcpy(_compressed, data, length);
|
||||
|
|
|
@ -10,7 +10,7 @@ var uuid = Entities.addEntity({
|
|||
maxVolume: 0.1,
|
||||
range: 25,
|
||||
disabled: true,
|
||||
grabbableKey: { wantsTrigger: true },
|
||||
grab: { triggerable: true }
|
||||
}),
|
||||
lifetime: 600,
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
/* jslint bitwise: true */
|
||||
/* global Script, Entities, MyAvatar, Vec3, Quat, Mat4 */
|
||||
/* global Script, Entities, MyAvatar, Vec3, Quat, Mat4, Overlays */
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
|||
var sectionCenterB = 0;
|
||||
var sectionCenterSign = 0;
|
||||
var yFlip = 0;
|
||||
|
||||
|
||||
var objects = [];
|
||||
var overlays = [];
|
||||
|
||||
|
@ -35,41 +35,41 @@
|
|||
createPropsCube(index, false, false, true, true);
|
||||
createPropsModel(index, false, false, true, true);
|
||||
createSign(index, "Clone Dynamic Entity");
|
||||
};
|
||||
}
|
||||
|
||||
function createCloneEntity(index) {
|
||||
createPropsCube(index, false, false, true, false);
|
||||
createPropsModel(index, false, false, true, false);
|
||||
createSign(index, "Clone Non-Dynamic Entity");
|
||||
};
|
||||
}
|
||||
|
||||
function createNearGrabOverlay(index) {
|
||||
createPropsCubeOverlay(index, false, false, true, true);
|
||||
createPropsModelOverlay(index, false, false, true, true);
|
||||
createSign(index, "Near Grab Overlay");
|
||||
};
|
||||
}
|
||||
|
||||
function createNearGrabEntity(index) {
|
||||
createPropsCube(index, false, false, false, false);
|
||||
createPropsModel(index, false, false, false, false);
|
||||
createSign(index, "Near Grab Entity");
|
||||
};
|
||||
}
|
||||
|
||||
function createFarGrabEntity(index) {
|
||||
createPropsCube(index, true, false, false, false);
|
||||
createPropsModel(index, true, false, false, false);
|
||||
createSign(index, "Far Grab Entity");
|
||||
};
|
||||
}
|
||||
|
||||
function createPropsModel(i, dynamic, collisionless, clone, cloneDynamic) {
|
||||
var propsModel = {
|
||||
name: "controller-tests model object " + i,
|
||||
type: "Model",
|
||||
modelURL: "http://headache.hungry.com/~seth/hifi/controller-tests/color-cube.obj",
|
||||
|
||||
|
||||
position: sectionCenterA,
|
||||
rotation: sectionRotation,
|
||||
|
||||
|
||||
gravity: (dynamic && !collisionless) ? { x: 0, y: -1, z: 0 } : { x: 0, y: 0, z: 0 },
|
||||
dimensions: { x: 0.2, y: 0.2, z: 0.2 },
|
||||
userData: JSON.stringify({
|
||||
|
@ -270,8 +270,8 @@
|
|||
Entities.deleteEntity(nearbyID);
|
||||
}
|
||||
|
||||
for (var i = 0; i < overlays.length; i++) {
|
||||
var overlayID = overlays[i];
|
||||
for (var j = 0; j < overlays.length; j++) {
|
||||
var overlayID = overlays[j];
|
||||
Overlays.deleteOverlay(overlayID);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -329,36 +329,18 @@ function isGrabbable(entityID) {
|
|||
return false;
|
||||
}
|
||||
|
||||
var properties = Entities.getEntityProperties(entityID, ['clientOnly', 'userData']);
|
||||
var properties = Entities.getEntityProperties(entityID, ['clientOnly', 'grab.grabbable']);
|
||||
if (properties.clientOnly) {
|
||||
var userData;
|
||||
try {
|
||||
userData = JSON.parse(properties.userData);
|
||||
} catch (e) {
|
||||
userData = {};
|
||||
}
|
||||
|
||||
return userData.grabbableKey && userData.grabbableKey.grabbable;
|
||||
return properties.grab.grabbable;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function setGrabbable(entityID, grabbable) {
|
||||
var properties = Entities.getEntityProperties(entityID, ['clientOnly', 'userData']);
|
||||
var properties = Entities.getEntityProperties(entityID, ['clientOnly']);
|
||||
if (properties.clientOnly) {
|
||||
var userData;
|
||||
try {
|
||||
userData = JSON.parse(properties.userData);
|
||||
} catch (e) {
|
||||
userData = {};
|
||||
}
|
||||
|
||||
if (userData.grabbableKey === undefined) {
|
||||
userData.grabbableKey = {};
|
||||
}
|
||||
userData.grabbableKey.grabbable = grabbable;
|
||||
Entities.editEntity(entityID, {userData: JSON.stringify(userData)});
|
||||
Entities.editEntity(entityID, { grab: { grabbable: grabbable }});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,8 @@
|
|||
/* global Script, Entities, Overlays, Controller, Vec3, Quat, getControllerWorldLocation,
|
||||
controllerDispatcherPlugins:true, controllerDispatcherPluginsNeedSort:true,
|
||||
LEFT_HAND, RIGHT_HAND, NEAR_GRAB_PICK_RADIUS, DEFAULT_SEARCH_SPHERE_DISTANCE, DISPATCHER_PROPERTIES,
|
||||
getGrabPointSphereOffset, HMD, MyAvatar, Messages, findHandChildEntities, Picks, PickType, Pointers, COLORS_GRAB_SEARCHING_HALF_SQUEEZE
|
||||
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, TRIGGER_ON_VALUE, PointerManager, print
|
||||
getGrabPointSphereOffset, HMD, MyAvatar, Messages, findHandChildEntities, Picks, PickType, Pointers,
|
||||
PointerManager, getGrabPointSphereOffset, HMD, MyAvatar, Messages, findHandChildEntities, Picks, PickType, Pointers,
|
||||
PointerManager, print, Selection, DISPATCHER_HOVERING_LIST, DISPATCHER_HOVERING_STYLE
|
||||
*/
|
||||
|
||||
|
@ -34,6 +33,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
|
||||
var PROFILE = false;
|
||||
var DEBUG = false;
|
||||
var SHOW_GRAB_SPHERE = false;
|
||||
|
||||
|
||||
if (typeof Test !== "undefined") {
|
||||
PROFILE = true;
|
||||
|
@ -51,6 +52,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
this.tabletID = null;
|
||||
this.blacklist = [];
|
||||
this.pointerManager = new PointerManager();
|
||||
this.grabSphereOverlays = [null, null];
|
||||
|
||||
// a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are
|
||||
// not set to false (not in use), a module cannot start. When a module is using a slot, that module's name
|
||||
|
@ -251,7 +253,28 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
for (h = LEFT_HAND; h <= RIGHT_HAND; h++) {
|
||||
if (controllerLocations[h].valid) {
|
||||
var controllerPosition = controllerLocations[h].position;
|
||||
var nearbyEntityIDs = Entities.findEntities(controllerPosition, NEAR_MAX_RADIUS * sensorScaleFactor);
|
||||
var findRadius = NEAR_MAX_RADIUS * sensorScaleFactor;
|
||||
|
||||
if (SHOW_GRAB_SPHERE) {
|
||||
if (this.grabSphereOverlays[h]) {
|
||||
Overlays.editOverlay(this.grabSphereOverlays[h], { position: controllerLocations[h].position });
|
||||
} else {
|
||||
var grabSphereSize = findRadius * 2;
|
||||
this.grabSphereOverlays[h] = Overlays.addOverlay("sphere", {
|
||||
position: controllerLocations[h].position,
|
||||
dimensions: { x: grabSphereSize, y: grabSphereSize, z: grabSphereSize },
|
||||
color: { red: 30, green: 30, blue: 255 },
|
||||
alpha: 0.3,
|
||||
solid: true,
|
||||
visible: true,
|
||||
// lineWidth: 2.0,
|
||||
drawInFront: false,
|
||||
grabbable: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var nearbyEntityIDs = Entities.findEntities(controllerPosition, findRadius);
|
||||
for (var j = 0; j < nearbyEntityIDs.length; j++) {
|
||||
var entityID = nearbyEntityIDs[j];
|
||||
var props = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* globals createControllerDisplay:true deleteControllerDisplay:true */
|
||||
/* globals createControllerDisplay:true, deleteControllerDisplay:true, Controller, Overlays, Vec3, MyAvatar, Quat */
|
||||
|
||||
function clamp(value, min, max) {
|
||||
if (value < min) {
|
||||
|
@ -188,7 +188,7 @@ createControllerDisplay = function(config) {
|
|||
for (var partName in controller.parts) {
|
||||
var part = controller.parts[partName];
|
||||
var localPosition = Vec3.subtract(part.naturalPosition, controller.naturalPosition);
|
||||
var localRotation = { x: 0, y: 0, z: 0, w: 1 }
|
||||
var localRotation = { x: 0, y: 0, z: 0, w: 1 };
|
||||
|
||||
controllerDisplay.parts[partName] = controller.parts[partName];
|
||||
|
||||
|
@ -203,7 +203,7 @@ createControllerDisplay = function(config) {
|
|||
if (part.defaultTextureLayer) {
|
||||
var textures = {};
|
||||
textures[part.textureName] = part.textureLayers[part.defaultTextureLayer].defaultTextureURL;
|
||||
properties['textures'] = textures;
|
||||
properties.textures = textures;
|
||||
}
|
||||
|
||||
var overlayID = Overlays.addOverlay("model", properties);
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* globals ControllerDisplayManager:true createControllerDisplay deleteControllerDisplay
|
||||
VIVE_CONTROLLER_CONFIGURATION_LEFT VIVE_CONTROLLER_CONFIGURATION_RIGHT */
|
||||
/* globals ControllerDisplayManager:true, createControllerDisplay, deleteControllerDisplay,
|
||||
VIVE_CONTROLLER_CONFIGURATION_LEFT, VIVE_CONTROLLER_CONFIGURATION_RIGHT, Script, HMD, Controller,
|
||||
MyAvatar, Overlays, TOUCH_CONTROLLER_CONFIGURATION_LEFT, TOUCH_CONTROLLER_CONFIGURATION_RIGHT, Messages */
|
||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||
|
||||
(function () {
|
||||
|
@ -93,7 +94,7 @@ ControllerDisplayManager = function() {
|
|||
if (controllerRight) {
|
||||
controllerRight.resize(sensorScaleFactor);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var handleMessages = function(channel, message, sender) {
|
||||
var i, data, name, visible;
|
||||
|
|
|
@ -58,18 +58,16 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
if (channel === 'Hifi-Hand-Disabler') {
|
||||
if (message === 'left') {
|
||||
leftDisableModules.disableModules = true;
|
||||
}
|
||||
if (message === 'right') {
|
||||
} else if (message === 'right') {
|
||||
rightDisableModules.disableModules = true;
|
||||
}
|
||||
if (message === 'both' || message === 'none') {
|
||||
if (message === 'both') {
|
||||
leftDisableModules.disableModules = true;
|
||||
rightDisableModules.disableModules = true;
|
||||
} else if (message === 'none') {
|
||||
leftDisableModules.disableModules = false;
|
||||
rightDisableModules.disableModules = false;
|
||||
}
|
||||
} else if (message === 'both') {
|
||||
leftDisableModules.disableModules = true;
|
||||
rightDisableModules.disableModules = true;
|
||||
} else if (message === 'none') {
|
||||
leftDisableModules.disableModules = false;
|
||||
rightDisableModules.disableModules = false;
|
||||
} else {
|
||||
print("disableOtherModule -- unknown command: " + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, Camera,
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, Camera, print,
|
||||
getControllerJointIndex, enableDispatcherModule, disableDispatcherModule, entityIsFarGrabbedByOther,
|
||||
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
|
||||
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable,
|
||||
cloneEntity, DISPATCHER_PROPERTIES, Uuid, unhighlightTargetEntity, isInEditMode
|
||||
cloneEntity, DISPATCHER_PROPERTIES, Uuid, unhighlightTargetEntity, isInEditMode, getGrabbableData
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/Xform.js");
|
||||
|
@ -66,12 +66,16 @@ EquipHotspotBuddy.prototype.updateHotspot = function(hotspot, timestamp) {
|
|||
overlays: []
|
||||
};
|
||||
|
||||
var diameter = hotspot.radius * 2;
|
||||
var dimensions = hotspot.radius * 2 * EQUIP_SPHERE_SCALE_FACTOR;
|
||||
|
||||
if (hotspot.indicatorURL) {
|
||||
dimensions = hotspot.indicatorScale;
|
||||
}
|
||||
|
||||
// override default sphere with a user specified model, if it exists.
|
||||
overlayInfoSet.overlays.push(Overlays.addOverlay("model", {
|
||||
name: "hotspot overlay",
|
||||
url: hotspot.modelURL ? hotspot.modelURL : DEFAULT_SPHERE_MODEL_URL,
|
||||
url: hotspot.indicatorURL ? hotspot.indicatorURL : DEFAULT_SPHERE_MODEL_URL,
|
||||
position: hotspot.worldPosition,
|
||||
rotation: {
|
||||
x: 0,
|
||||
|
@ -79,8 +83,7 @@ EquipHotspotBuddy.prototype.updateHotspot = function(hotspot, timestamp) {
|
|||
z: 0,
|
||||
w: 1
|
||||
},
|
||||
dimensions: diameter * EQUIP_SPHERE_SCALE_FACTOR,
|
||||
scale: hotspot.modelScale,
|
||||
dimensions: dimensions,
|
||||
ignoreRayIntersection: true
|
||||
}));
|
||||
overlayInfoSet.type = "model";
|
||||
|
@ -137,8 +140,13 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
var position = entityXform.xformPoint(overlayInfoSet.localPosition);
|
||||
|
||||
var dimensions;
|
||||
if (overlayInfoSet.type === "sphere") {
|
||||
dimensions = (overlayInfoSet.hotspot.radius / 2) * overlayInfoSet.currentSize * EQUIP_SPHERE_SCALE_FACTOR;
|
||||
if (overlayInfoSet.hotspot.indicatorURL) {
|
||||
var ratio = overlayInfoSet.currentSize / overlayInfoSet.targetSize;
|
||||
dimensions = {
|
||||
x: overlayInfoSet.hotspot.dimensions.x * ratio,
|
||||
y: overlayInfoSet.hotspot.dimensions.y * ratio,
|
||||
z: overlayInfoSet.hotspot.dimensions.z * ratio
|
||||
};
|
||||
} else {
|
||||
dimensions = (overlayInfoSet.hotspot.radius / 2) * overlayInfoSet.currentSize;
|
||||
}
|
||||
|
@ -158,12 +166,21 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
var alreadyWarned = {};
|
||||
function warnAboutUserData(props) {
|
||||
if (alreadyWarned[props.id]) {
|
||||
return;
|
||||
}
|
||||
print("Warning -- overriding grab properties with userData for " + props.id + " / " + props.name);
|
||||
alreadyWarned[props.id] = true;
|
||||
}
|
||||
|
||||
|
||||
(function() {
|
||||
|
||||
var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints";
|
||||
|
||||
var EQUIP_RADIUS = 1.0; // radius used for palm vs equip-hotspot for equipping.
|
||||
|
||||
var HAPTIC_PULSE_STRENGTH = 1.0;
|
||||
var HAPTIC_PULSE_DURATION = 13.0;
|
||||
var HAPTIC_TEXTURE_STRENGTH = 0.1;
|
||||
|
@ -176,36 +193,86 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
var TRIGGER_OFF_VALUE = 0.1;
|
||||
var TRIGGER_ON_VALUE = TRIGGER_OFF_VALUE + 0.05; // Squeezed just enough to activate search or near grab
|
||||
var BUMPER_ON_VALUE = 0.5;
|
||||
|
||||
|
||||
var EMPTY_PARENT_ID = "{00000000-0000-0000-0000-000000000000}";
|
||||
|
||||
|
||||
var UNEQUIP_KEY = "u";
|
||||
|
||||
function getWearableData(props) {
|
||||
var wearable = {};
|
||||
try {
|
||||
if (!props.userDataParsed) {
|
||||
props.userDataParsed = JSON.parse(props.userData);
|
||||
}
|
||||
if (props.grab.equippable) {
|
||||
// if equippable is true, we know this was already converted from the old userData style to properties
|
||||
return {
|
||||
joints: {
|
||||
LeftHand: [ props.grab.equippableLeftPosition, props.grab.equippableLeftRotation ],
|
||||
RightHand: [ props.grab.equippableRightPosition, props.grab.equippableRightRotation ]
|
||||
},
|
||||
indicatorURL: props.grab.equippableIndicatorURL,
|
||||
indicatorScale: props.grab.equippableIndicatorScale,
|
||||
indicatorOffset: props.grab.equippableIndicatorOffset
|
||||
};
|
||||
} else {
|
||||
// check for old userData equippability. The JSON reader will convert userData to properties
|
||||
// in EntityTree.cpp, but this won't catch things created from scripts or some items in
|
||||
// the market. Eventually we'll remove this section.
|
||||
try {
|
||||
if (!props.userDataParsed) {
|
||||
props.userDataParsed = JSON.parse(props.userData);
|
||||
}
|
||||
var userDataParsed = props.userDataParsed;
|
||||
|
||||
wearable = props.userDataParsed.wearable ? props.userDataParsed.wearable : {};
|
||||
} catch (err) {
|
||||
// don't want to spam the logs
|
||||
}
|
||||
return wearable;
|
||||
}
|
||||
function getEquipHotspotsData(props) {
|
||||
var equipHotspots = [];
|
||||
try {
|
||||
if (!props.userDataParsed) {
|
||||
props.userDataParsed = JSON.parse(props.userData);
|
||||
}
|
||||
// userData: { wearable: { joints: { LeftHand: {...}, RightHand: {...} } } }
|
||||
if (userDataParsed.wearable && userDataParsed.wearable.joints) {
|
||||
warnAboutUserData(props);
|
||||
userDataParsed.wearable.indicatorURL = "";
|
||||
userDataParsed.wearable.indicatorScale = { x: 1, y: 1, z: 1 };
|
||||
userDataParsed.wearable.indicatorOffset = { x: 0, y: 0, z: 0 };
|
||||
return userDataParsed.wearable;
|
||||
}
|
||||
|
||||
equipHotspots = props.userDataParsed.equipHotspots ? props.userDataParsed.equipHotspots : [];
|
||||
} catch (err) {
|
||||
// don't want to spam the logs
|
||||
// userData: { equipHotspots: { joints: { LeftHand: {...}, RightHand: {...} } } }
|
||||
// https://highfidelity.atlassian.net/wiki/spaces/HOME/pages/51085337/Authoring+Equippable+Entities
|
||||
if (userDataParsed.equipHotspots &&
|
||||
userDataParsed.equipHotspots.length > 0 &&
|
||||
userDataParsed.equipHotspots[0].joints) {
|
||||
warnAboutUserData(props);
|
||||
var hotSpot = userDataParsed.equipHotspots[0];
|
||||
|
||||
var indicatorScale = { x: hotSpot.radius, y: hotSpot.radius, z: hotSpot.radius };
|
||||
if (hotSpot.modelURL && hotSpot.modelURL !== "") {
|
||||
indicatorScale = hotSpot.modelScale;
|
||||
}
|
||||
|
||||
return {
|
||||
joints: hotSpot.joints,
|
||||
indicatorURL: hotSpot.modelURL,
|
||||
indicatorScale: indicatorScale,
|
||||
indicatorOffset: hotSpot.position,
|
||||
};
|
||||
}
|
||||
|
||||
// userData:{grabbableKey:{spatialKey:{leftRelativePosition:{...},rightRelativePosition:{...}}}}
|
||||
if (userDataParsed.grabbableKey &&
|
||||
userDataParsed.grabbableKey.spatialKey) {
|
||||
warnAboutUserData(props);
|
||||
var joints = {};
|
||||
joints.LeftHand = [ { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0, w: 1 } ];
|
||||
joints.RightHand = [ { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0, w: 1 } ];
|
||||
if (userDataParsed.grabbableKey.spatialKey.leftRelativePosition) {
|
||||
joints.LeftHand = [userDataParsed.grabbableKey.spatialKey.leftRelativePosition,
|
||||
userDataParsed.grabbableKey.spatialKey.relativeRotation];
|
||||
}
|
||||
if (userDataParsed.grabbableKey.spatialKey.rightRelativePosition) {
|
||||
joints.RightHand = [userDataParsed.grabbableKey.spatialKey.rightRelativePosition,
|
||||
userDataParsed.grabbableKey.spatialKey.relativeRotation];
|
||||
}
|
||||
return { joints: joints };
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
// don't spam logs
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return equipHotspots;
|
||||
}
|
||||
|
||||
function getAttachPointSettings() {
|
||||
|
@ -275,7 +342,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
this.handHasBeenRightsideUp = false;
|
||||
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
300,
|
||||
115,
|
||||
this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip"] : ["leftHand", "leftHandEquip"],
|
||||
[],
|
||||
100);
|
||||
|
@ -299,51 +366,29 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
// * radius {number} radius of equip hotspot
|
||||
// * joints {Object} keys are joint names values are arrays of two elements:
|
||||
// offset position {Vec3} and offset rotation {Quat}, both are in the coordinate system of the joint.
|
||||
// * modelURL {string} url for model to use instead of default sphere.
|
||||
// * modelScale {Vec3} scale factor for model
|
||||
// * indicatorURL {string} url for model to use instead of default sphere.
|
||||
// * indicatorScale {Vec3} scale factor for model
|
||||
this.collectEquipHotspots = function(props) {
|
||||
var result = [];
|
||||
var entityID = props.id;
|
||||
var entityXform = new Xform(props.rotation, props.position);
|
||||
|
||||
var equipHotspotsProps = getEquipHotspotsData(props);
|
||||
if (equipHotspotsProps && equipHotspotsProps.length > 0) {
|
||||
var i, length = equipHotspotsProps.length;
|
||||
for (i = 0; i < length; i++) {
|
||||
var hotspot = equipHotspotsProps[i];
|
||||
if (hotspot.position && hotspot.radius && hotspot.joints) {
|
||||
result.push({
|
||||
key: entityID.toString() + i.toString(),
|
||||
entityID: entityID,
|
||||
localPosition: hotspot.position,
|
||||
worldPosition: entityXform.xformPoint(hotspot.position),
|
||||
radius: hotspot.radius,
|
||||
joints: hotspot.joints,
|
||||
modelURL: hotspot.modelURL,
|
||||
modelScale: hotspot.modelScale
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var wearableProps = getWearableData(props);
|
||||
var sensorToScaleFactor = MyAvatar.sensorToWorldScale;
|
||||
if (wearableProps && wearableProps.joints) {
|
||||
|
||||
result.push({
|
||||
key: entityID.toString() + "0",
|
||||
entityID: entityID,
|
||||
localPosition: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
worldPosition: entityXform.pos,
|
||||
radius: EQUIP_RADIUS * sensorToScaleFactor,
|
||||
joints: wearableProps.joints,
|
||||
modelURL: null,
|
||||
modelScale: null
|
||||
});
|
||||
}
|
||||
var wearableProps = getWearableData(props);
|
||||
var sensorToScaleFactor = MyAvatar.sensorToWorldScale;
|
||||
if (wearableProps && wearableProps.joints) {
|
||||
result.push({
|
||||
key: entityID.toString() + "0",
|
||||
entityID: entityID,
|
||||
localPosition: wearableProps.indicatorOffset,
|
||||
worldPosition: entityXform.pos,
|
||||
radius: ((wearableProps.indicatorScale.x +
|
||||
wearableProps.indicatorScale.y +
|
||||
wearableProps.indicatorScale.z) / 3) * sensorToScaleFactor,
|
||||
dimensions: wearableProps.indicatorScale,
|
||||
joints: wearableProps.joints,
|
||||
indicatorURL: wearableProps.indicatorURL,
|
||||
indicatorScale: wearableProps.indicatorScale,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
@ -492,7 +537,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
};
|
||||
|
||||
Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message));
|
||||
var grabbedProperties = Entities.getEntityProperties(this.targetEntityID);
|
||||
var grabbedProperties = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES);
|
||||
var grabData = getGrabbableData(grabbedProperties);
|
||||
|
||||
// if an object is "equipped" and has a predefined offset, use it.
|
||||
if (this.grabbedHotspot) {
|
||||
|
@ -510,7 +556,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
}
|
||||
|
||||
var handJointIndex;
|
||||
if (this.ignoreIK) {
|
||||
if (grabData.grabFollowsController) {
|
||||
handJointIndex = this.controllerJointIndex;
|
||||
} else {
|
||||
handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||
|
@ -796,7 +842,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
if (intersection.intersects) {
|
||||
var entityID = intersection.entityID;
|
||||
var entityProperties = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES);
|
||||
var hasEquipData = getWearableData(entityProperties).joints || getEquipHotspotsData(entityProperties).length > 0;
|
||||
entityProperties.id = entityID;
|
||||
var hasEquipData = getWearableData(entityProperties);
|
||||
if (hasEquipData && entityProperties.parentID === EMPTY_PARENT_ID && !entityIsFarGrabbedByOther(entityID)) {
|
||||
entityProperties.id = entityID;
|
||||
var rightHandPosition = MyAvatar.getJointPosition("RightHand");
|
||||
|
@ -804,7 +851,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
var distanceToRightHand = Vec3.distance(entityProperties.position, rightHandPosition);
|
||||
var distanceToLeftHand = Vec3.distance(entityProperties.position, leftHandPosition);
|
||||
var leftHandAvailable = leftEquipEntity.targetEntityID === null;
|
||||
var rightHandAvailable = rightEquipEntity.targetEntityID === null;
|
||||
var rightHandAvailable = rightEquipEntity.targetEntityID === null;
|
||||
if (rightHandAvailable && (distanceToRightHand < distanceToLeftHand || !leftHandAvailable)) {
|
||||
// clear any existing grab actions on the entity now (their later removal could affect bootstrapping flags)
|
||||
clearGrabActions(entityID);
|
||||
|
@ -817,7 +864,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var onKeyPress = function(event) {
|
||||
if (event.text.toLowerCase() === UNEQUIP_KEY) {
|
||||
if (rightEquipEntity.targetEntityID) {
|
||||
|
@ -828,7 +875,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var deleteEntity = function(entityID) {
|
||||
if (rightEquipEntity.targetEntityID === entityID) {
|
||||
rightEquipEntity.endEquipEntity();
|
||||
|
@ -837,7 +884,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
leftEquipEntity.endEquipEntity();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var clearEntities = function() {
|
||||
if (rightEquipEntity.targetEntityID) {
|
||||
rightEquipEntity.endEquipEntity();
|
||||
|
@ -846,7 +893,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
leftEquipEntity.endEquipEntity();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Messages.subscribe('Hifi-Hand-Grab');
|
||||
Messages.subscribe('Hifi-Hand-Drop');
|
||||
Messages.messageReceived.connect(handleMessage);
|
||||
|
|
|
@ -8,38 +8,19 @@
|
|||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
|
||||
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities,
|
||||
getEnabledModuleByName, makeRunningValues, Entities,
|
||||
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, entityIsGrabbable,
|
||||
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI
|
||||
Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST,
|
||||
worldPositionToRegistrationFrameMatrix
|
||||
TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD,
|
||||
Picks, makeLaserLockInfo, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST,
|
||||
worldPositionToRegistrationFrameMatrix, DISPATCHER_PROPERTIES, Uuid, Picks
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
Script.include("/~/system/libraries/Xform.js");
|
||||
|
||||
(function() {
|
||||
var GRABBABLE_PROPERTIES = [
|
||||
"position",
|
||||
"registrationPoint",
|
||||
"rotation",
|
||||
"gravity",
|
||||
"collidesWith",
|
||||
"dynamic",
|
||||
"collisionless",
|
||||
"locked",
|
||||
"name",
|
||||
"shapeType",
|
||||
"parentID",
|
||||
"parentJointIndex",
|
||||
"density",
|
||||
"dimensions",
|
||||
"userData"
|
||||
];
|
||||
|
||||
var MARGIN = 25;
|
||||
|
||||
|
@ -106,9 +87,9 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
this.locked = false;
|
||||
this.highlightedEntity = null;
|
||||
this.reticleMinX = MARGIN;
|
||||
this.reticleMaxX;
|
||||
this.reticleMaxX = null;
|
||||
this.reticleMinY = MARGIN;
|
||||
this.reticleMaxY;
|
||||
this.reticleMaxY = null;
|
||||
|
||||
this.ignoredEntities = [];
|
||||
|
||||
|
@ -212,7 +193,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
var worldToSensorMat = Mat4.inverse(MyAvatar.getSensorToWorldMatrix());
|
||||
var roomControllerPosition = Mat4.transformPoint(worldToSensorMat, worldControllerPosition);
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedThingID, GRABBABLE_PROPERTIES);
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedThingID, DISPATCHER_PROPERTIES);
|
||||
var now = Date.now();
|
||||
var deltaObjectTime = (now - this.currentObjectTime) / MSECS_PER_SEC; // convert to seconds
|
||||
this.currentObjectTime = now;
|
||||
|
@ -329,7 +310,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
|
||||
this.notPointingAtEntity = function(controllerData) {
|
||||
var intersection = controllerData.rayPicks[this.hand];
|
||||
var entityProperty = Entities.getEntityProperties(intersection.objectID);
|
||||
var entityProperty = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES);
|
||||
var entityType = entityProperty.type;
|
||||
var hudRayPick = controllerData.hudRayPicks[this.hand];
|
||||
var point2d = this.calculateNewReticlePosition(hudRayPick.intersection);
|
||||
|
@ -373,7 +354,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
var worldControllerPosition = controllerLocation.position;
|
||||
var worldControllerRotation = controllerLocation.orientation;
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES);
|
||||
var grabbedProperties = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES);
|
||||
this.currentObjectPosition = grabbedProperties.position;
|
||||
this.grabRadius = intersection.distance;
|
||||
|
||||
|
@ -395,7 +376,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
};
|
||||
|
||||
this.targetIsNull = function() {
|
||||
var properties = Entities.getEntityProperties(this.grabbedThingID);
|
||||
var properties = Entities.getEntityProperties(this.grabbedThingID, DISPATCHER_PROPERTIES);
|
||||
if (Object.keys(properties).length === 0 && this.distanceHolding) {
|
||||
return true;
|
||||
}
|
||||
|
@ -460,8 +441,8 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
// if we are doing a distance grab and the object or tablet gets close enough to the controller,
|
||||
// stop the far-grab so the near-grab or equip can take over.
|
||||
for (var k = 0; k < nearGrabReadiness.length; k++) {
|
||||
if (nearGrabReadiness[k].active && (nearGrabReadiness[k].targets[0] === this.grabbedThingID
|
||||
|| HMD.tabletID && nearGrabReadiness[k].targets[0] === HMD.tabletID)) {
|
||||
if (nearGrabReadiness[k].active && (nearGrabReadiness[k].targets[0] === this.grabbedThingID ||
|
||||
HMD.tabletID && nearGrabReadiness[k].targets[0] === HMD.tabletID)) {
|
||||
this.endFarGrabAction();
|
||||
this.restoreIgnoredEntities();
|
||||
return makeRunningValues(false, [], []);
|
||||
|
@ -487,11 +468,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
||||
this.highlightedEntity);
|
||||
this.highlightedEntity = null;
|
||||
var targetProps = Entities.getEntityProperties(entityID, [
|
||||
"dynamic", "shapeType", "position",
|
||||
"rotation", "dimensions", "density",
|
||||
"userData", "locked", "type", "href"
|
||||
]);
|
||||
var targetProps = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES);
|
||||
if (targetProps.href !== "") {
|
||||
AddressManager.handleLookupString(targetProps.href);
|
||||
this.restoreIgnoredEntities();
|
||||
|
@ -540,11 +517,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
if (this.highlightedEntity !== targetEntityID) {
|
||||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
||||
this.highlightedEntity);
|
||||
var selectionTargetProps = Entities.getEntityProperties(targetEntityID, [
|
||||
"dynamic", "shapeType", "position",
|
||||
"rotation", "dimensions", "density",
|
||||
"userData", "locked", "type", "href"
|
||||
]);
|
||||
var selectionTargetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES);
|
||||
|
||||
var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps);
|
||||
selectionTargetObject.parentProps = getEntityParents(selectionTargetProps);
|
||||
|
@ -574,11 +547,12 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
if (!_this.entityWithContextOverlay &&
|
||||
_this.contextOverlayTimer &&
|
||||
_this.potentialEntityWithContextOverlay === rayPickInfo.objectID) {
|
||||
var props = Entities.getEntityProperties(rayPickInfo.objectID);
|
||||
var props = Entities.getEntityProperties(rayPickInfo.objectID, DISPATCHER_PROPERTIES);
|
||||
var pointerEvent = {
|
||||
type: "Move",
|
||||
id: _this.hand + 1, // 0 is reserved for hardware mouse
|
||||
pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, rayPickInfo.intersection, props),
|
||||
pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID,
|
||||
rayPickInfo.intersection, props),
|
||||
pos3D: rayPickInfo.intersection,
|
||||
normal: rayPickInfo.surfaceNormal,
|
||||
direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal),
|
||||
|
|
|
@ -11,32 +11,14 @@
|
|||
makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, entityIsGrabbable,
|
||||
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE,
|
||||
TRIGGER_ON_VALUE, ZERO_VEC, getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD,
|
||||
Picks, makeLaserLockInfo, Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST,
|
||||
Uuid, worldPositionToRegistrationFrameMatrix
|
||||
Picks, makeLaserLockInfo, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST,
|
||||
Uuid, worldPositionToRegistrationFrameMatrix, DISPATCHER_PROPERTIES
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
Script.include("/~/system/libraries/Xform.js");
|
||||
|
||||
(function() {
|
||||
var GRABBABLE_PROPERTIES = [
|
||||
"position",
|
||||
"registrationPoint",
|
||||
"rotation",
|
||||
"gravity",
|
||||
"collidesWith",
|
||||
"dynamic",
|
||||
"collisionless",
|
||||
"locked",
|
||||
"name",
|
||||
"shapeType",
|
||||
"parentID",
|
||||
"parentJointIndex",
|
||||
"density",
|
||||
"dimensions",
|
||||
"userData"
|
||||
];
|
||||
|
||||
var MARGIN = 25;
|
||||
|
||||
|
@ -45,7 +27,6 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
this.entityProps = entityProps;
|
||||
this.targetEntityID = null;
|
||||
this.targetEntityProps = null;
|
||||
this.previousCollisionStatus = null;
|
||||
|
||||
this.getTargetEntity = function() {
|
||||
var parentPropsLength = this.parentProps.length;
|
||||
|
@ -74,7 +55,6 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
this.potentialEntityWithContextOverlay = false;
|
||||
this.entityWithContextOverlay = false;
|
||||
this.contextOverlayTimer = false;
|
||||
this.previousCollisionStatus = false;
|
||||
this.locked = false;
|
||||
this.highlightedEntity = null;
|
||||
this.reticleMinX = MARGIN;
|
||||
|
@ -182,7 +162,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
var worldToSensorMat = Mat4.inverse(MyAvatar.getSensorToWorldMatrix());
|
||||
var roomControllerPosition = Mat4.transformPoint(worldToSensorMat, worldControllerPosition);
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedThingID, GRABBABLE_PROPERTIES);
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedThingID, DISPATCHER_PROPERTIES);
|
||||
var now = Date.now();
|
||||
var deltaObjectTime = (now - this.currentObjectTime) / MSECS_PER_SEC; // convert to seconds
|
||||
this.currentObjectTime = now;
|
||||
|
@ -284,7 +264,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
|
||||
this.notPointingAtEntity = function(controllerData) {
|
||||
var intersection = controllerData.rayPicks[this.hand];
|
||||
var entityProperty = Entities.getEntityProperties(intersection.objectID);
|
||||
var entityProperty = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES);
|
||||
var entityType = entityProperty.type;
|
||||
var hudRayPick = controllerData.hudRayPicks[this.hand];
|
||||
var point2d = this.calculateNewReticlePosition(hudRayPick.intersection);
|
||||
|
@ -319,7 +299,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
var worldControllerPosition = controllerLocation.position;
|
||||
var worldControllerRotation = controllerLocation.orientation;
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES);
|
||||
var grabbedProperties = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES);
|
||||
this.currentObjectPosition = grabbedProperties.position;
|
||||
this.grabRadius = intersection.distance;
|
||||
|
||||
|
@ -341,7 +321,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
};
|
||||
|
||||
this.targetIsNull = function() {
|
||||
var properties = Entities.getEntityProperties(this.grabbedThingID);
|
||||
var properties = Entities.getEntityProperties(this.grabbedThingID, DISPATCHER_PROPERTIES);
|
||||
if (Object.keys(properties).length === 0 && this.distanceHolding) {
|
||||
return true;
|
||||
}
|
||||
|
@ -351,7 +331,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
this.getTargetProps = function (controllerData) {
|
||||
var targetEntityID = controllerData.rayPicks[this.hand].objectID;
|
||||
if (targetEntityID) {
|
||||
return Entities.getEntityProperties(targetEntityID);
|
||||
return Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
@ -435,11 +415,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
||||
this.highlightedEntity);
|
||||
this.highlightedEntity = null;
|
||||
var targetProps = Entities.getEntityProperties(entityID, [
|
||||
"dynamic", "shapeType", "position",
|
||||
"rotation", "dimensions", "density",
|
||||
"userData", "locked", "type", "href"
|
||||
]);
|
||||
var targetProps = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES);
|
||||
if (targetProps.href !== "") {
|
||||
AddressManager.handleLookupString(targetProps.href);
|
||||
return makeRunningValues(false, [], []);
|
||||
|
@ -488,11 +464,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
if (this.highlightedEntity !== targetEntityID) {
|
||||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity",
|
||||
this.highlightedEntity);
|
||||
var selectionTargetProps = Entities.getEntityProperties(targetEntityID, [
|
||||
"dynamic", "shapeType", "position",
|
||||
"rotation", "dimensions", "density",
|
||||
"userData", "locked", "type", "href"
|
||||
]);
|
||||
var selectionTargetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES);
|
||||
|
||||
var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps);
|
||||
selectionTargetObject.parentProps = getEntityParents(selectionTargetProps);
|
||||
|
@ -522,7 +494,8 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
if (!_this.entityWithContextOverlay &&
|
||||
_this.contextOverlayTimer &&
|
||||
_this.potentialEntityWithContextOverlay === rayPickInfo.objectID) {
|
||||
var pEvProps = Entities.getEntityProperties(rayPickInfo.objectID);
|
||||
var pEvProps = Entities.getEntityProperties(rayPickInfo.objectID,
|
||||
DISPATCHER_PROPERTIES);
|
||||
var pointerEvent = {
|
||||
type: "Move",
|
||||
id: _this.hand + 1, // 0 is reserved for hardware mouse
|
||||
|
|
|
@ -10,34 +10,15 @@
|
|||
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Quat, getEnabledModuleByName, makeRunningValues,
|
||||
Entities, enableDispatcherModule, disableDispatcherModule, entityIsGrabbable, makeDispatcherModuleParameters, MSECS_PER_SEC,
|
||||
HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, getControllerWorldLocation,
|
||||
projectOntoEntityXYPlane, ContextOverlay, HMD, Picks, makeLaserLockInfo, Xform, makeLaserParams, AddressManager,
|
||||
projectOntoEntityXYPlane, ContextOverlay, HMD, Picks, makeLaserLockInfo, makeLaserParams, AddressManager,
|
||||
getEntityParents, Selection, DISPATCHER_HOVERING_LIST, unhighlightTargetEntity, Messages, Uuid, findGroupParent,
|
||||
worldPositionToRegistrationFrameMatrix
|
||||
worldPositionToRegistrationFrameMatrix, DISPATCHER_PROPERTIES, findFarGrabJointChildEntities
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
Script.include("/~/system/libraries/Xform.js");
|
||||
|
||||
(function() {
|
||||
var GRABBABLE_PROPERTIES = [
|
||||
"position",
|
||||
"registrationPoint",
|
||||
"rotation",
|
||||
"gravity",
|
||||
"collidesWith",
|
||||
"dynamic",
|
||||
"collisionless",
|
||||
"locked",
|
||||
"name",
|
||||
"shapeType",
|
||||
"parentID",
|
||||
"parentJointIndex",
|
||||
"density",
|
||||
"dimensions",
|
||||
"userData"
|
||||
];
|
||||
|
||||
var MARGIN = 25;
|
||||
|
||||
function TargetObject(entityID, entityProps) {
|
||||
|
@ -68,6 +49,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
this.hand = hand;
|
||||
this.targetEntityID = null;
|
||||
this.targetObject = null;
|
||||
this.previouslyUnhooked = {};
|
||||
this.previousParentID = {};
|
||||
this.previousParentJointIndex = {};
|
||||
this.potentialEntityWithContextOverlay = false;
|
||||
|
@ -78,6 +60,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
this.reticleMaxX = 0;
|
||||
this.reticleMinY = MARGIN;
|
||||
this.reticleMaxY = 0;
|
||||
this.lastUnexpectedChildrenCheckTime = 0;
|
||||
|
||||
var FAR_GRAB_JOINTS = [65527, 65528]; // FARGRAB_LEFTHAND_INDEX, FARGRAB_RIGHTHAND_INDEX
|
||||
|
||||
|
@ -214,7 +197,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
var worldToSensorMat = Mat4.inverse(MyAvatar.getSensorToWorldMatrix());
|
||||
var roomControllerPosition = Mat4.transformPoint(worldToSensorMat, worldControllerPosition);
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(this.targetEntityID, GRABBABLE_PROPERTIES);
|
||||
var grabbedProperties = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES);
|
||||
var now = Date.now();
|
||||
var deltaObjectTime = (now - this.currentObjectTime) / MSECS_PER_SEC; // convert to seconds
|
||||
this.currentObjectTime = now;
|
||||
|
@ -275,7 +258,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
this.endFarParentGrab = function (controllerData) {
|
||||
this.hapticTargetID = null;
|
||||
// var endProps = controllerData.nearbyEntityPropertiesByID[this.targetEntityID];
|
||||
var endProps = Entities.getEntityProperties(this.targetEntityID, GRABBABLE_PROPERTIES);
|
||||
var endProps = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES);
|
||||
if (this.thisFarGrabJointIsParent(endProps)) {
|
||||
Entities.editEntity(this.targetEntityID, {
|
||||
parentID: this.previousParentID[this.targetEntityID],
|
||||
|
@ -313,7 +296,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
|
||||
this.notPointingAtEntity = function(controllerData) {
|
||||
var intersection = controllerData.rayPicks[this.hand];
|
||||
var entityProperty = Entities.getEntityProperties(intersection.objectID);
|
||||
var entityProperty = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES);
|
||||
var entityType = entityProperty.type;
|
||||
var hudRayPick = controllerData.hudRayPicks[this.hand];
|
||||
var point2d = this.calculateNewReticlePosition(hudRayPick.intersection);
|
||||
|
@ -348,7 +331,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
var worldControllerPosition = controllerLocation.position;
|
||||
var worldControllerRotation = controllerLocation.orientation;
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES);
|
||||
var grabbedProperties = Entities.getEntityProperties(intersection.objectID, DISPATCHER_PROPERTIES);
|
||||
this.currentObjectPosition = grabbedProperties.position;
|
||||
this.grabRadius = intersection.distance;
|
||||
|
||||
|
@ -369,8 +352,51 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
}
|
||||
};
|
||||
|
||||
this.checkForUnexpectedChildren = function (controllerData) {
|
||||
// sometimes things can get parented to a hand and this script is unaware. Search for such entities and
|
||||
// unhook them.
|
||||
|
||||
var now = Date.now();
|
||||
var UNEXPECTED_CHILDREN_CHECK_TIME = 0.1; // seconds
|
||||
if (now - this.lastUnexpectedChildrenCheckTime > MSECS_PER_SEC * UNEXPECTED_CHILDREN_CHECK_TIME) {
|
||||
this.lastUnexpectedChildrenCheckTime = now;
|
||||
|
||||
var children = findFarGrabJointChildEntities(this.hand);
|
||||
var _this = this;
|
||||
|
||||
children.forEach(function(childID) {
|
||||
// we appear to be holding something and this script isn't in a state that would be holding something.
|
||||
// unhook it. if we previously took note of this entity's parent, put it back where it was. This
|
||||
// works around some problems that happen when more than one hand or avatar is passing something around.
|
||||
if (_this.previousParentID[childID]) {
|
||||
var previousParentID = _this.previousParentID[childID];
|
||||
var previousParentJointIndex = _this.previousParentJointIndex[childID];
|
||||
|
||||
// The main flaw with keeping track of previous parentage in individual scripts is:
|
||||
// (1) A grabs something (2) B takes it from A (3) A takes it from B (4) A releases it
|
||||
// now A and B will take turns passing it back to the other. Detect this and stop the loop here...
|
||||
var UNHOOK_LOOP_DETECT_MS = 200;
|
||||
if (_this.previouslyUnhooked[childID]) {
|
||||
if (now - _this.previouslyUnhooked[childID] < UNHOOK_LOOP_DETECT_MS) {
|
||||
previousParentID = Uuid.NULL;
|
||||
previousParentJointIndex = -1;
|
||||
}
|
||||
}
|
||||
_this.previouslyUnhooked[childID] = now;
|
||||
|
||||
Entities.editEntity(childID, {
|
||||
parentID: previousParentID,
|
||||
parentJointIndex: previousParentJointIndex
|
||||
});
|
||||
} else {
|
||||
Entities.editEntity(childID, { parentID: Uuid.NULL });
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.targetIsNull = function() {
|
||||
var properties = Entities.getEntityProperties(this.targetEntityID, GRABBABLE_PROPERTIES);
|
||||
var properties = Entities.getEntityProperties(this.targetEntityID, DISPATCHER_PROPERTIES);
|
||||
if (Object.keys(properties).length === 0 && this.distanceHolding) {
|
||||
return true;
|
||||
}
|
||||
|
@ -380,7 +406,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
this.getTargetProps = function (controllerData) {
|
||||
var targetEntity = controllerData.rayPicks[this.hand].objectID;
|
||||
if (targetEntity) {
|
||||
var gtProps = Entities.getEntityProperties(targetEntity, GRABBABLE_PROPERTIES);
|
||||
var gtProps = Entities.getEntityProperties(targetEntity, DISPATCHER_PROPERTIES);
|
||||
if (entityIsGrabbable(gtProps)) {
|
||||
// give haptic feedback
|
||||
if (gtProps.id !== this.hapticTargetID) {
|
||||
|
@ -416,6 +442,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
return makeRunningValues(true, [], []);
|
||||
}
|
||||
} else {
|
||||
this.checkForUnexpectedChildren(controllerData);
|
||||
this.destroyContextOverlay();
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
@ -480,11 +507,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
var entityID = rayPickInfo.objectID;
|
||||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity);
|
||||
this.highlightedEntity = null;
|
||||
var targetProps = Entities.getEntityProperties(entityID, [
|
||||
"dynamic", "shapeType", "position",
|
||||
"rotation", "dimensions", "density",
|
||||
"userData", "locked", "type", "href"
|
||||
]);
|
||||
var targetProps = Entities.getEntityProperties(entityID, DISPATCHER_PROPERTIES);
|
||||
if (targetProps.href !== "") {
|
||||
AddressManager.handleLookupString(targetProps.href);
|
||||
return makeRunningValues(false, [], []);
|
||||
|
@ -533,11 +556,7 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
var targetEntityID = rayPickInfo.objectID;
|
||||
if (this.highlightedEntity !== targetEntityID) {
|
||||
Selection.removeFromSelectedItemsList(DISPATCHER_HOVERING_LIST, "entity", this.highlightedEntity);
|
||||
var selectionTargetProps = Entities.getEntityProperties(targetEntityID, [
|
||||
"dynamic", "shapeType", "position",
|
||||
"rotation", "dimensions", "density",
|
||||
"userData", "locked", "type", "href"
|
||||
]);
|
||||
var selectionTargetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES);
|
||||
|
||||
var selectionTargetObject = new TargetObject(targetEntityID, selectionTargetProps);
|
||||
selectionTargetObject.parentProps = getEntityParents(selectionTargetProps);
|
||||
|
@ -567,7 +586,8 @@ Script.include("/~/system/libraries/Xform.js");
|
|||
if (!_this.entityWithContextOverlay &&
|
||||
_this.contextOverlayTimer &&
|
||||
_this.potentialEntityWithContextOverlay === rayPickInfo.objectID) {
|
||||
var cotProps = Entities.getEntityProperties(rayPickInfo.objectID);
|
||||
var cotProps = Entities.getEntityProperties(rayPickInfo.objectID,
|
||||
DISPATCHER_PROPERTIES);
|
||||
var pointerEvent = {
|
||||
type: "Move",
|
||||
id: _this.hand + 1, // 0 is reserved for hardware mouse
|
||||
|
|
|
@ -6,19 +6,18 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset,
|
||||
/* global Script, RIGHT_HAND, LEFT_HAND, MyAvatar,
|
||||
makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
|
||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams
|
||||
getGrabbableData, makeLaserParams, DISPATCHER_PROPERTIES
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
|
||||
(function() {
|
||||
function entityWantsNearTrigger(props) {
|
||||
function entityWantsFarTrigger(props) {
|
||||
var grabbableData = getGrabbableData(props);
|
||||
return grabbableData.triggerable || grabbableData.wantsTrigger;
|
||||
return grabbableData.triggerable;
|
||||
}
|
||||
|
||||
function FarTriggerEntity(hand) {
|
||||
|
@ -37,11 +36,10 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
makeLaserParams(this.hand, false));
|
||||
|
||||
this.getTargetProps = function (controllerData) {
|
||||
// nearbyEntityProperties is already sorted by length from controller
|
||||
var targetEntity = controllerData.rayPicks[this.hand].objectID;
|
||||
if (targetEntity) {
|
||||
var targetProperties = Entities.getEntityProperties(targetEntity);
|
||||
if (entityWantsNearTrigger(targetProperties)) {
|
||||
var targetProperties = Entities.getEntityProperties(targetEntity, DISPATCHER_PROPERTIES);
|
||||
if (entityWantsFarTrigger(targetProperties)) {
|
||||
return targetProperties;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset,
|
||||
makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
|
||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData, makeLaserParams, entityIsCloneable, Messages, print
|
||||
*/
|
||||
/* global Script, MyAvatar, entityIsCloneable, Messages, print */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
@ -134,7 +130,7 @@
|
|||
rightHighlightNearbyEntities.removeEntityFromHighlightList(data.entityID);
|
||||
}
|
||||
} catch (e) {
|
||||
print("Failed to parse message");
|
||||
print("highlightNearbyEntities -- Failed to parse message: " + JSON.stringify(message));
|
||||
}
|
||||
} else if (channel === 'Hifi-unhighlight-all') {
|
||||
leftHighlightNearbyEntities.clearAll();
|
||||
|
|
|
@ -10,16 +10,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
|
||||
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities,
|
||||
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
|
||||
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI,
|
||||
makeLaserParams
|
||||
|
||||
*/
|
||||
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, HMD, makeLaserParams */
|
||||
(function() {
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
var ControllerDispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
|
@ -72,7 +63,7 @@
|
|||
|
||||
this.processLaser = function(controllerData) {
|
||||
var controllerLocation = controllerData.controllerLocations[this.hand];
|
||||
var otherModuleRunning = this.getOtherModule().running;
|
||||
// var otherModuleRunning = this.getOtherModule().running;
|
||||
if ((controllerData.triggerValues[this.hand] < ControllerDispatcherUtils.TRIGGER_ON_VALUE || !controllerLocation.valid) ||
|
||||
this.pointingAtTablet(controllerData)) {
|
||||
return false;
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
||||
Messages, makeDispatcherModuleParameters, HMD, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE,
|
||||
getEnabledModuleByName, PICK_MAX_DISTANCE, isInEditMode, Picks, makeLaserParams, Entities
|
||||
Messages, makeDispatcherModuleParameters, HMD, getEnabledModuleByName, TRIGGER_ON_VALUE, isInEditMode, Picks,
|
||||
makeLaserParams
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
|
@ -24,9 +23,9 @@ Script.include("/~/system/libraries/utils.js");
|
|||
this.triggerClicked = false;
|
||||
this.selectedTarget = null;
|
||||
this.reticleMinX = MARGIN;
|
||||
this.reticleMaxX;
|
||||
this.reticleMaxX = null;
|
||||
this.reticleMinY = MARGIN;
|
||||
this.reticleMaxY;
|
||||
this.reticleMaxY = null;
|
||||
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
160,
|
||||
|
@ -49,8 +48,8 @@ Script.include("/~/system/libraries/utils.js");
|
|||
};
|
||||
|
||||
this.pointingAtTablet = function(objectID) {
|
||||
return (HMD.tabletScreenID && objectID === HMD.tabletScreenID)
|
||||
|| (HMD.homeButtonID && objectID === HMD.homeButtonID);
|
||||
return (HMD.tabletScreenID && objectID === HMD.tabletScreenID) ||
|
||||
(HMD.homeButtonID && objectID === HMD.homeButtonID);
|
||||
};
|
||||
|
||||
this.calculateNewReticlePosition = function(intersection) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global Script, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule,
|
||||
/* global Script, HMD, Messages, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule,
|
||||
makeDispatcherModuleParameters, makeRunningValues, getEnabledModuleByName, makeLaserParams
|
||||
*/
|
||||
|
||||
|
@ -22,17 +22,17 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
var NO_HAND_LASER = -1; // Invalid hand parameter so that default laser is not displayed.
|
||||
this.parameters = makeDispatcherModuleParameters(
|
||||
200, // Not too high otherwise the tablet laser doesn't work.
|
||||
this.hand === RIGHT_HAND
|
||||
? ["rightHand", "rightHandEquip", "rightHandTrigger"]
|
||||
: ["leftHand", "leftHandEquip", "leftHandTrigger"],
|
||||
this.hand === RIGHT_HAND ?
|
||||
["rightHand", "rightHandEquip", "rightHandTrigger"] :
|
||||
["leftHand", "leftHandEquip", "leftHandTrigger"],
|
||||
[],
|
||||
100,
|
||||
makeLaserParams(NO_HAND_LASER, false)
|
||||
);
|
||||
|
||||
this.pointingAtTablet = function (objectID) {
|
||||
return (HMD.tabletScreenID && objectID === HMD.tabletScreenID)
|
||||
|| (HMD.homeButtonID && objectID === HMD.homeButtonID);
|
||||
return (HMD.tabletScreenID && objectID === HMD.tabletScreenID) ||
|
||||
(HMD.homeButtonID && objectID === HMD.homeButtonID);
|
||||
};
|
||||
|
||||
this.isReady = function (controllerData) {
|
||||
|
@ -49,9 +49,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
}
|
||||
|
||||
// Tablet stylus.
|
||||
var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||
? "RightTabletStylusInput"
|
||||
: "LeftTabletStylusInput");
|
||||
var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND ?
|
||||
"RightTabletStylusInput" :
|
||||
"LeftTabletStylusInput");
|
||||
if (tabletStylusInput) {
|
||||
var tabletReady = tabletStylusInput.isReady(controllerData);
|
||||
if (tabletReady.active) {
|
||||
|
@ -60,9 +60,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
}
|
||||
|
||||
// Tablet surface.
|
||||
var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||
? "RightWebSurfaceLaserInput"
|
||||
: "LeftWebSurfaceLaserInput");
|
||||
var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND ?
|
||||
"RightWebSurfaceLaserInput" :
|
||||
"LeftWebSurfaceLaserInput");
|
||||
if (overlayLaser) {
|
||||
var overlayLaserReady = overlayLaser.isReady(controllerData);
|
||||
var target = controllerData.rayPicks[this.hand].objectID;
|
||||
|
@ -72,9 +72,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
}
|
||||
|
||||
// Tablet grabbing.
|
||||
var nearOverlay = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||
? "RightNearParentingGrabOverlay"
|
||||
: "LeftNearParentingGrabOverlay");
|
||||
var nearOverlay = getEnabledModuleByName(this.hand === RIGHT_HAND ?
|
||||
"RightNearParentingGrabOverlay" :
|
||||
"LeftNearParentingGrabOverlay");
|
||||
if (nearOverlay) {
|
||||
var nearOverlayReady = nearOverlay.isReady(controllerData);
|
||||
if (nearOverlayReady.active && HMD.tabletID && nearOverlay.grabbedThingID === HMD.tabletID) {
|
||||
|
@ -83,9 +83,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
}
|
||||
|
||||
// Teleport.
|
||||
var teleporter = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||
? "RightTeleporter"
|
||||
: "LeftTeleporter");
|
||||
var teleporter = getEnabledModuleByName(this.hand === RIGHT_HAND ?
|
||||
"RightTeleporter" :
|
||||
"LeftTeleporter");
|
||||
if (teleporter) {
|
||||
var teleporterReady = teleporter.isReady(controllerData);
|
||||
if (teleporterReady.active) {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* global Script, HMD, Reticle, Vec3, Controller */
|
||||
|
||||
(function() {
|
||||
var ControllerDispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
|
||||
|
@ -121,7 +123,7 @@
|
|||
if (this.mouseActivity.expired(now) || this.triggersPressed(controllerData, now) || !hmdActive) {
|
||||
if (!hmdActive) {
|
||||
Reticle.visible = true;
|
||||
} else {
|
||||
} else {
|
||||
Reticle.visible = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, print, Entities, Picks, HMD, Controller, MyAvatar, isInEditMode*/
|
||||
/* global Script, print, Entities, Messages, Picks, HMD, MyAvatar, isInEditMode, DISPATCHER_PROPERTIES */
|
||||
|
||||
|
||||
(function() {
|
||||
|
@ -46,11 +46,7 @@
|
|||
var targetEntityID = pickResult.objectID;
|
||||
|
||||
if (this.highlightedEntity !== targetEntityID) {
|
||||
var targetProps = Entities.getEntityProperties(targetEntityID, [
|
||||
"dynamic", "shapeType", "position",
|
||||
"rotation", "dimensions", "density",
|
||||
"userData", "locked", "type", "href"
|
||||
]);
|
||||
var targetProps = Entities.getEntityProperties(targetEntityID, DISPATCHER_PROPERTIES);
|
||||
|
||||
if (this.highlightedEntity) {
|
||||
dispatcherUtils.unhighlightTargetEntity(this.highlightedEntity);
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable,
|
||||
Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues,
|
||||
TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity,
|
||||
HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, unhighlightTargetEntity, Uuid
|
||||
HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, unhighlightTargetEntity, Uuid,
|
||||
DISPATCHER_PROPERTIES
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
|
@ -62,12 +63,12 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
||||
|
||||
var grabbableData = getGrabbableData(targetProps);
|
||||
this.ignoreIK = grabbableData.ignoreIK;
|
||||
this.kinematicGrab = grabbableData.kinematic;
|
||||
this.grabFollowsController = grabbableData.grabFollowsController;
|
||||
this.kinematicGrab = grabbableData.grabKinematic;
|
||||
|
||||
var handRotation;
|
||||
var handPosition;
|
||||
if (this.ignoreIK) {
|
||||
if (this.grabFollowsController) {
|
||||
var controllerID =
|
||||
(this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||
var controllerLocation = getControllerWorldLocation(controllerID, false);
|
||||
|
@ -99,7 +100,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
ttl: ACTION_TTL,
|
||||
kinematic: this.kinematicGrab,
|
||||
kinematicSetVelocity: true,
|
||||
ignoreIK: this.ignoreIK
|
||||
ignoreIK: this.grabFollowsController
|
||||
});
|
||||
if (this.actionID === Uuid.NULL) {
|
||||
this.actionID = null;
|
||||
|
@ -136,7 +137,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
ttl: ACTION_TTL,
|
||||
kinematic: this.kinematicGrab,
|
||||
kinematicSetVelocity: true,
|
||||
ignoreIK: this.ignoreIK
|
||||
ignoreIK: this.grabFollowsController
|
||||
});
|
||||
if (success) {
|
||||
this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC);
|
||||
|
@ -238,7 +239,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
var targetCloneable = entityIsCloneable(targetProps);
|
||||
if (targetCloneable) {
|
||||
var cloneID = cloneEntity(targetProps);
|
||||
var cloneProps = Entities.getEntityProperties(cloneID);
|
||||
var cloneProps = Entities.getEntityProperties(cloneID, DISPATCHER_PROPERTIES);
|
||||
this.targetEntityID = cloneID;
|
||||
this.startNearGrabAction(controllerData, cloneProps);
|
||||
} else {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH,
|
||||
HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME,
|
||||
TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity,
|
||||
distanceBetweenEntityLocalPositionAndBoundingBox, GRAB_POINT_SPHERE_OFFSET
|
||||
distanceBetweenEntityLocalPositionAndBoundingBox, getGrabbableData, getGrabPointSphereOffset, DISPATCHER_PROPERTIES
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
|
@ -28,16 +28,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; // x = upward, y = forward, z = lateral
|
||||
|
||||
function getGrabOffset(handController) {
|
||||
var offset = GRAB_POINT_SPHERE_OFFSET;
|
||||
if (handController === Controller.Standard.LeftHand) {
|
||||
offset = {
|
||||
x: -GRAB_POINT_SPHERE_OFFSET.x,
|
||||
y: GRAB_POINT_SPHERE_OFFSET.y,
|
||||
z: GRAB_POINT_SPHERE_OFFSET.z
|
||||
};
|
||||
}
|
||||
|
||||
offset.y = -GRAB_POINT_SPHERE_OFFSET.y;
|
||||
var offset = getGrabPointSphereOffset(handController, true);
|
||||
offset.y = -offset.y;
|
||||
return Vec3.multiply(MyAvatar.sensorToWorldScale, offset);
|
||||
}
|
||||
|
||||
|
@ -101,6 +93,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
};
|
||||
|
||||
this.startNearParentingGrabEntity = function (controllerData, targetProps) {
|
||||
var grabData = getGrabbableData(targetProps);
|
||||
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
||||
unhighlightTargetEntity(this.targetEntityID);
|
||||
this.highlightedEntity = null;
|
||||
|
@ -111,12 +104,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
|
||||
Messages.sendLocalMessage('Hifi-unhighlight-entity', JSON.stringify(message));
|
||||
var handJointIndex;
|
||||
// if (this.ignoreIK) {
|
||||
// handJointIndex = this.controllerJointIndex;
|
||||
// } else {
|
||||
// handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||
// }
|
||||
handJointIndex = getControllerJointIndex(this.hand);
|
||||
if (grabData.grabFollowsController) {
|
||||
handJointIndex = getControllerJointIndex(this.hand);
|
||||
} else {
|
||||
handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||
}
|
||||
|
||||
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
|
||||
Entities.callEntityMethod(targetProps.id, "startNearGrab", args);
|
||||
|
@ -368,7 +360,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
if (this.cloneAllowed) {
|
||||
var cloneID = cloneEntity(targetProps);
|
||||
if (cloneID !== null) {
|
||||
var cloneProps = Entities.getEntityProperties(cloneID);
|
||||
var cloneProps = Entities.getEntityProperties(cloneID, DISPATCHER_PROPERTIES);
|
||||
this.grabbing = true;
|
||||
this.targetEntityID = cloneID;
|
||||
this.startNearParentingGrabEntity(controllerData, cloneProps);
|
||||
|
|
|
@ -16,7 +16,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
|
||||
function entityWantsNearTrigger(props) {
|
||||
var grabbableData = getGrabbableData(props);
|
||||
return grabbableData.triggerable || grabbableData.wantsTrigger;
|
||||
return grabbableData.triggerable;
|
||||
}
|
||||
|
||||
function NearTriggerEntity(hand) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global Script, Vec3, MyAvatar, RIGHT_HAND */
|
||||
/* global Script, Vec3, MyAvatar, Entities, RIGHT_HAND */
|
||||
|
||||
(function() {
|
||||
var dispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
||||
enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
||||
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC,
|
||||
HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset,
|
||||
getEnabledModuleByName, Pointers, Picks, PickType
|
||||
/* global Script, MyAvatar, Controller, Uuid, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule,
|
||||
makeRunningValues, Vec3, makeDispatcherModuleParameters, Overlays, HMD, Settings, getEnabledModuleByName, Pointers,
|
||||
Picks, PickType
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
|
@ -200,7 +198,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
|
||||
Overlays.hoverEnterOverlay.connect(mouseHoverEnter);
|
||||
Overlays.hoverLeaveOverlay.connect(mouseHoverLeave);
|
||||
Overlays.mousePressOnOverlay.connect(mousePress);
|
||||
Overlays.mousePressOnOverlay.connect(mousePress);
|
||||
|
||||
this.cleanup = function () {
|
||||
leftTabletStylusInput.cleanup();
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
||||
/* global Script, Entities, MyAvatar, Controller, Quat, RIGHT_HAND, LEFT_HAND,
|
||||
enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Vec3,
|
||||
HMD, Uuid, AvatarList, Picks, Pointers, PickType
|
||||
*/
|
||||
|
@ -680,8 +680,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
|
||||
this.teleportLocked = function () {
|
||||
// Lock teleport if in advanced movement mode and have just transitioned from pressing a direction button.
|
||||
return Controller.getValue(Controller.Hardware.Application.AdvancedMovement)
|
||||
&& (_this.axisButtonStateX !== 0 || _this.axisButtonStateY !== 0);
|
||||
return Controller.getValue(Controller.Hardware.Application.AdvancedMovement) &&
|
||||
(_this.axisButtonStateX !== 0 || _this.axisButtonStateY !== 0);
|
||||
};
|
||||
|
||||
this.buttonPress = function (value) {
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule,
|
||||
makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD,
|
||||
INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE,
|
||||
TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, ContextOverlay, Picks, makeLaserParams
|
||||
/* global Script, Entities, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
||||
makeDispatcherModuleParameters, Overlays, HMD, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, getEnabledModuleByName,
|
||||
ContextOverlay, Picks, makeLaserParams, Settings, MyAvatar, RIGHT_HAND, LEFT_HAND, DISPATCHER_PROPERTIES
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
|
@ -82,7 +80,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
return overlayType === "web3d" || triggerPressed;
|
||||
}
|
||||
} else if (intersection.type === Picks.INTERSECTED_ENTITY) {
|
||||
var entityProperties = Entities.getEntityProperties(objectID);
|
||||
var entityProperties = Entities.getEntityProperties(objectID, DISPATCHER_PROPERTIES);
|
||||
var entityType = entityProperties.type;
|
||||
var isLocked = entityProperties.locked;
|
||||
return entityType === "Web" && (!isLocked || triggerPressed);
|
||||
|
@ -91,8 +89,9 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
};
|
||||
|
||||
this.deleteContextOverlay = function() {
|
||||
var farGrabModule = getEnabledModuleByName(this.hand === RIGHT_HAND
|
||||
? "RightFarActionGrabEntity" : "LeftFarActionGrabEntity");
|
||||
var farGrabModule = getEnabledModuleByName(this.hand === RIGHT_HAND ?
|
||||
"RightFarActionGrabEntity" :
|
||||
"LeftFarActionGrabEntity");
|
||||
if (farGrabModule) {
|
||||
var entityWithContextOverlay = farGrabModule.entityWithContextOverlay;
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* global Script, Menu */
|
||||
|
||||
var CONTOLLER_SCRIPTS = [
|
||||
"squeezeHands.js",
|
||||
"controllerDisplayManager.js",
|
||||
|
@ -19,8 +21,8 @@ var CONTOLLER_SCRIPTS = [
|
|||
"controllerModules/nearParentGrabEntity.js",
|
||||
"controllerModules/nearParentGrabOverlay.js",
|
||||
"controllerModules/nearActionGrabEntity.js",
|
||||
// "controllerModules/farActionGrabEntity.js",
|
||||
// "controllerModules/farParentGrabEntity.js",
|
||||
"controllerModules/farActionGrabEntityDynOnly.js",
|
||||
"controllerModules/farParentGrabEntity.js",
|
||||
"controllerModules/stylusInput.js",
|
||||
"controllerModules/equipEntity.js",
|
||||
"controllerModules/nearTrigger.js",
|
||||
|
@ -38,25 +40,22 @@ var CONTOLLER_SCRIPTS = [
|
|||
"controllerModules/mouseHighlightEntities.js"
|
||||
];
|
||||
|
||||
if (Settings.getValue("useFarGrabJoints", false)) {
|
||||
CONTOLLER_SCRIPTS.push("controllerModules/farActionGrabEntityDynOnly.js");
|
||||
CONTOLLER_SCRIPTS.push("controllerModules/farParentGrabEntity.js");
|
||||
} else {
|
||||
CONTOLLER_SCRIPTS.push("controllerModules/farActionGrabEntity.js");
|
||||
}
|
||||
|
||||
var DEBUG_MENU_ITEM = "Debug defaultScripts.js";
|
||||
|
||||
|
||||
function runDefaultsTogether() {
|
||||
for (var j in CONTOLLER_SCRIPTS) {
|
||||
Script.include(CONTOLLER_SCRIPTS[j]);
|
||||
if (CONTOLLER_SCRIPTS.hasOwnProperty(j)) {
|
||||
Script.include(CONTOLLER_SCRIPTS[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runDefaultsSeparately() {
|
||||
for (var i in CONTOLLER_SCRIPTS) {
|
||||
Script.load(CONTOLLER_SCRIPTS[i]);
|
||||
if (CONTOLLER_SCRIPTS.hasOwnProperty(i)) {
|
||||
Script.load(CONTOLLER_SCRIPTS[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* global MyAvatar, Entities, Script, Camera, Vec3, Reticle, Overlays, getEntityCustomData, Messages, Quat, Controller,
|
||||
isInEditMode, HMD entityIsGrabbable, Picks, PickType, Pointers, unhighlightTargetEntity*/
|
||||
|
||||
/* global MyAvatar, Entities, Script, HMD, Camera, Vec3, Reticle, Overlays, getEntityCustomData, Messages, Quat, Controller,
|
||||
isInEditMode, entityIsGrabbable, Picks, PickType, Pointers, unhighlightTargetEntity, DISPATCHER_PROPERTIES,
|
||||
entityIsGrabbable, entityIsEquipped, getMainTabletIDs
|
||||
*/
|
||||
/* jslint bitwise: true */
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
||||
|
@ -37,7 +39,6 @@ var IDENTITY_QUAT = {
|
|||
z: 0,
|
||||
w: 0
|
||||
};
|
||||
var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with handControllerGrab.js
|
||||
|
||||
var DEFAULT_GRABBABLE_DATA = {
|
||||
grabbable: true,
|
||||
|
@ -339,16 +340,14 @@ Grabber.prototype.pressEvent = function(event) {
|
|||
return;
|
||||
}
|
||||
|
||||
var props = Entities.getEntityProperties(pickResults.objectID, ["dynamic", "userData", "locked", "type"]);
|
||||
var props = Entities.getEntityProperties(pickResults.objectID, DISPATCHER_PROPERTIES);
|
||||
var isDynamic = props.dynamic;
|
||||
var isGrabbable = props.grabbable;
|
||||
if (!entityIsGrabbable(props)) {
|
||||
// only grab grabbable objects
|
||||
return;
|
||||
}
|
||||
|
||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, pickResults.objectID, DEFAULT_GRABBABLE_DATA);
|
||||
if (grabbableData.grabbable === false) {
|
||||
if (!props.grab.grabbable) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -359,7 +358,7 @@ Grabber.prototype.pressEvent = function(event) {
|
|||
mouse.startDrag(event);
|
||||
|
||||
var clickedEntity = pickResults.objectID;
|
||||
var entityProperties = Entities.getEntityProperties(clickedEntity);
|
||||
var entityProperties = Entities.getEntityProperties(clickedEntity, DISPATCHER_PROPERTIES);
|
||||
this.startPosition = entityProperties.position;
|
||||
this.lastRotation = entityProperties.rotation;
|
||||
this.madeDynamic = false;
|
||||
|
@ -484,7 +483,7 @@ Grabber.prototype.moveEvent = function(event) {
|
|||
Grabber.prototype.moveEventProcess = function() {
|
||||
this.moveEventTimer = null;
|
||||
// see if something added/restored gravity
|
||||
var entityProperties = Entities.getEntityProperties(this.entityID);
|
||||
var entityProperties = Entities.getEntityProperties(this.entityID, DISPATCHER_PROPERTIES);
|
||||
if (!entityProperties || !entityProperties.gravity || HMD.active) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Overlays, Controller, Vec3, MyAvatar, Entities
|
||||
/* global Script, Overlays, Controller, Vec3, MyAvatar, Entities, RayPick
|
||||
*/
|
||||
|
||||
(function () {
|
||||
|
@ -22,8 +22,8 @@
|
|||
var MSECONDS_AFTER_LOAD = 2000;
|
||||
var updateFingerWithIndex = 0;
|
||||
var untouchableEntities = [];
|
||||
|
||||
// Keys to access finger data
|
||||
|
||||
// Keys to access finger data
|
||||
var fingerKeys = ["pinky", "ring", "middle", "index", "thumb"];
|
||||
|
||||
// Additionally close the hands to achieve a grabbing effect
|
||||
|
@ -47,7 +47,7 @@
|
|||
left: new Palm(),
|
||||
right: new Palm()
|
||||
};
|
||||
|
||||
|
||||
var handJointNames = {left: "LeftHand", right: "RightHand"};
|
||||
|
||||
// Store which fingers are touching - if all false restate the default poses
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
/* global Script, MyAvatar, Messages, Controller */
|
||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||
|
||||
(function() { // BEGIN LOCAL_SCOPE
|
||||
|
@ -20,7 +21,7 @@ var lastRightTrigger = 0;
|
|||
var leftHandOverlayAlpha = 0;
|
||||
var rightHandOverlayAlpha = 0;
|
||||
|
||||
var CONTROLLER_DEAD_SPOT = 0.25;
|
||||
// var CONTROLLER_DEAD_SPOT = 0.25;
|
||||
var TRIGGER_SMOOTH_TIMESCALE = 0.1;
|
||||
var OVERLAY_RAMP_RATE = 8.0;
|
||||
|
||||
|
@ -42,9 +43,9 @@ function clamp(val, min, max) {
|
|||
return Math.min(Math.max(val, min), max);
|
||||
}
|
||||
|
||||
function normalizeControllerValue(val) {
|
||||
return clamp((val - CONTROLLER_DEAD_SPOT) / (1 - CONTROLLER_DEAD_SPOT), 0, 1);
|
||||
}
|
||||
// function normalizeControllerValue(val) {
|
||||
// return clamp((val - CONTROLLER_DEAD_SPOT) / (1 - CONTROLLER_DEAD_SPOT), 0, 1);
|
||||
// }
|
||||
|
||||
function lerp(a, b, alpha) {
|
||||
return a * (1 - alpha) + b * alpha;
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* globals TOUCH_CONTROLLER_CONFIGURATION_LEFT:true TOUCH_CONTROLLER_CONFIGURATION_RIGHT:true */
|
||||
/* globals TOUCH_CONTROLLER_CONFIGURATION_LEFT:true, TOUCH_CONTROLLER_CONFIGURATION_RIGHT:true,
|
||||
Quat, Vec3, Script, MyAvatar, Controller */
|
||||
/* eslint camelcase: ["error", { "properties": "never" }] */
|
||||
|
||||
var leftBaseRotation = Quat.multiply(
|
||||
|
@ -22,9 +23,9 @@ var rightBaseRotation = Quat.multiply(
|
|||
|
||||
// keep these in sync with the values from OculusHelpers.cpp
|
||||
var CONTROLLER_LENGTH_OFFSET = 0.0762;
|
||||
var CONTROLLER_LATERAL_OFFSET = 0.0381;
|
||||
var CONTROLLER_VERTICAL_OFFSET = 0.0381;
|
||||
var CONTROLLER_FORWARD_OFFSET = 0.1524;
|
||||
// var CONTROLLER_LATERAL_OFFSET = 0.0381;
|
||||
// var CONTROLLER_VERTICAL_OFFSET = 0.0381;
|
||||
// var CONTROLLER_FORWARD_OFFSET = 0.1524;
|
||||
|
||||
var leftBasePosition = Vec3.multiplyQbyV(leftBaseRotation, {
|
||||
x: -CONTROLLER_LENGTH_OFFSET / 2.0,
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/* globals VIVE_CONTROLLER_CONFIGURATION_LEFT:true VIVE_CONTROLLER_CONFIGURATION_RIGHT:true */
|
||||
/* globals VIVE_CONTROLLER_CONFIGURATION_LEFT:true, VIVE_CONTROLLER_CONFIGURATION_RIGHT:true,
|
||||
MyAvatar, Quat, Script, Vec3, Controller */
|
||||
/* eslint camelcase: ["error", { "properties": "never" }] */
|
||||
|
||||
var LEFT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_LEFTHAND");
|
||||
var RIGHT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_RIGHTHAND");
|
||||
// var LEFT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_LEFTHAND");
|
||||
// var RIGHT_JOINT_INDEX = MyAvatar.getJointIndex("_CONTROLLER_RIGHTHAND");
|
||||
|
||||
var leftBaseRotation = Quat.multiply(
|
||||
Quat.fromPitchYawRollDegrees(0, 0, 45),
|
||||
|
@ -58,10 +59,10 @@ var viveNaturalPosition = {
|
|||
};
|
||||
|
||||
var BASE_URL = Script.resourcesPath();
|
||||
var TIP_TEXTURE_BASE_URL = BASE_URL + "meshes/controller/vive_tips.fbm/";
|
||||
// var TIP_TEXTURE_BASE_URL = BASE_URL + "meshes/controller/vive_tips.fbm/";
|
||||
|
||||
var viveModelURL = BASE_URL + "meshes/controller/vive_body.fbx";
|
||||
var viveTipsModelURL = BASE_URL + "meshes/controller/vive_tips.fbx";
|
||||
// var viveTipsModelURL = BASE_URL + "meshes/controller/vive_tips.fbx";
|
||||
var viveTriggerModelURL = "meshes/controller/vive_trigger.fbx";
|
||||
|
||||
VIVE_CONTROLLER_CONFIGURATION_LEFT = {
|
||||
|
@ -340,4 +341,3 @@ VIVE_CONTROLLER_CONFIGURATION_RIGHT = {
|
|||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
|
|
@ -345,11 +345,15 @@ var toolBar = (function () {
|
|||
|
||||
position = grid.snapToSurface(grid.snapToGrid(position, false, dimensions), dimensions);
|
||||
properties.position = position;
|
||||
|
||||
if (!properties.grab) {
|
||||
properties.grab = {};
|
||||
}
|
||||
if (Menu.isOptionChecked(MENU_CREATE_ENTITIES_GRABBABLE) &&
|
||||
!(properties.type === "Zone" || properties.type === "Light" || properties.type === "ParticleEffect")) {
|
||||
properties.userData = JSON.stringify({ grabbableKey: { grabbable: true } });
|
||||
properties.grab.grabbable = true;
|
||||
} else {
|
||||
properties.userData = JSON.stringify({ grabbableKey: { grabbable: false } });
|
||||
properties.grab.grabbable = false;
|
||||
}
|
||||
|
||||
SelectionManager.saveProperties();
|
||||
|
|
|
@ -134,8 +134,8 @@
|
|||
<label for="property-cloneable">Cloneable</label>
|
||||
</div>
|
||||
<div class="property checkbox">
|
||||
<input type="checkbox" id="property-ignore-ik">
|
||||
<label for="property-ignore-ik">Ignore inverse kinematics</label>
|
||||
<input type="checkbox" id="property-grab-follows-controller">
|
||||
<label for="property-grab-follows-controller">Follow Controller</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global alert, augmentSpinButtons, clearTimeout, console, document, Element, EventBridge,
|
||||
HifiEntityUI, JSONEditor, openEventBridge, setTimeout, window, _ $ */
|
||||
/* global alert, augmentSpinButtons, clearTimeout, document, Element, EventBridge,
|
||||
JSONEditor, openEventBridge, setTimeout, window, $ */
|
||||
|
||||
var PI = 3.14159265358979;
|
||||
var DEGREES_TO_RADIANS = PI / 180.0;
|
||||
|
@ -364,12 +364,6 @@ function multiDataUpdater(groupName, updateKeyPair, userDataElement, defaults, r
|
|||
|
||||
updateProperties(properties);
|
||||
}
|
||||
function userDataChanger(groupName, keyName, values, userDataElement, defaultValue, removeKeys) {
|
||||
var val = {}, def = {};
|
||||
val[keyName] = values;
|
||||
def[keyName] = defaultValue;
|
||||
multiDataUpdater(groupName, val, userDataElement, def, removeKeys);
|
||||
}
|
||||
|
||||
function setMaterialDataFromEditor(noUpdate) {
|
||||
var json = null;
|
||||
|
@ -712,6 +706,8 @@ function loaded() {
|
|||
var elCollisionSoundURL = document.getElementById("property-collision-sound-url");
|
||||
|
||||
var elGrabbable = document.getElementById("property-grabbable");
|
||||
var elTriggerable = document.getElementById("property-triggerable");
|
||||
var elGrabFollowsController = document.getElementById("property-grab-follows-controller");
|
||||
|
||||
var elCloneable = document.getElementById("property-cloneable");
|
||||
var elCloneableDynamic = document.getElementById("property-cloneable-dynamic");
|
||||
|
@ -720,9 +716,6 @@ function loaded() {
|
|||
var elCloneableLifetime = document.getElementById("property-cloneable-lifetime");
|
||||
var elCloneableLimit = document.getElementById("property-cloneable-limit");
|
||||
|
||||
var elTriggerable = document.getElementById("property-triggerable");
|
||||
var elIgnoreIK = document.getElementById("property-ignore-ik");
|
||||
|
||||
var elLifetime = document.getElementById("property-lifetime");
|
||||
var elScriptURL = document.getElementById("property-script-url");
|
||||
var elScriptTimestamp = document.getElementById("property-script-timestamp");
|
||||
|
@ -992,7 +985,7 @@ function loaded() {
|
|||
|
||||
elGrabbable.checked = false;
|
||||
elTriggerable.checked = false;
|
||||
elIgnoreIK.checked = false;
|
||||
elGrabFollowsController.checked = false;
|
||||
|
||||
elCloneable.checked = false;
|
||||
elCloneableDynamic.checked = false;
|
||||
|
@ -1037,7 +1030,7 @@ function loaded() {
|
|||
elCompoundShapeURL.value = "";
|
||||
elShapeType.value = "none";
|
||||
setDropdownText(elShapeType);
|
||||
elModelAnimationURL.value = ""
|
||||
elModelAnimationURL.value = "";
|
||||
elModelAnimationPlaying.checked = false;
|
||||
elModelAnimationFPS.value = "";
|
||||
elModelAnimationFrame.value = "";
|
||||
|
@ -1254,10 +1247,9 @@ function loaded() {
|
|||
elCollideMyAvatar.checked = properties.collidesWith.indexOf("myAvatar") > -1;
|
||||
elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1;
|
||||
|
||||
elGrabbable.checked = properties.dynamic;
|
||||
|
||||
elTriggerable.checked = false;
|
||||
elIgnoreIK.checked = true;
|
||||
elGrabbable.checked = properties.grab.grabbable;
|
||||
elTriggerable.checked = properties.grab.triggerable;
|
||||
elGrabFollowsController.checked = properties.grab.grabFollowsController;
|
||||
|
||||
elCloneable.checked = properties.cloneable;
|
||||
elCloneableDynamic.checked = properties.cloneDynamic;
|
||||
|
@ -1266,42 +1258,6 @@ function loaded() {
|
|||
elCloneableLimit.value = properties.cloneLimit;
|
||||
elCloneableLifetime.value = properties.cloneLifetime;
|
||||
|
||||
var grabbablesSet = false;
|
||||
var parsedUserData = {};
|
||||
try {
|
||||
parsedUserData = JSON.parse(properties.userData);
|
||||
|
||||
if ("grabbableKey" in parsedUserData) {
|
||||
grabbablesSet = true;
|
||||
var grabbableData = parsedUserData.grabbableKey;
|
||||
if ("grabbable" in grabbableData) {
|
||||
elGrabbable.checked = grabbableData.grabbable;
|
||||
} else {
|
||||
elGrabbable.checked = true;
|
||||
}
|
||||
if ("triggerable" in grabbableData) {
|
||||
elTriggerable.checked = grabbableData.triggerable;
|
||||
} else if ("wantsTrigger" in grabbableData) {
|
||||
elTriggerable.checked = grabbableData.wantsTrigger;
|
||||
} else {
|
||||
elTriggerable.checked = false;
|
||||
}
|
||||
if ("ignoreIK" in grabbableData) {
|
||||
elIgnoreIK.checked = grabbableData.ignoreIK;
|
||||
} else {
|
||||
elIgnoreIK.checked = true;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO: What should go here?
|
||||
}
|
||||
if (!grabbablesSet) {
|
||||
elGrabbable.checked = true;
|
||||
elTriggerable.checked = false;
|
||||
elIgnoreIK.checked = true;
|
||||
elCloneable.checked = false;
|
||||
}
|
||||
|
||||
elCollisionSoundURL.value = properties.collisionSoundURL;
|
||||
elLifetime.value = properties.lifetime;
|
||||
elScriptURL.value = properties.script;
|
||||
|
@ -1669,26 +1625,18 @@ function loaded() {
|
|||
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideOtherAvatar, 'otherAvatar');
|
||||
});
|
||||
|
||||
elGrabbable.addEventListener('change', function() {
|
||||
if (elCloneable.checked) {
|
||||
elGrabbable.checked = false;
|
||||
}
|
||||
userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, true);
|
||||
});
|
||||
|
||||
|
||||
elGrabbable.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('grab', 'grabbable'));
|
||||
elTriggerable.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('grab', 'triggerable'));
|
||||
elGrabFollowsController.addEventListener('change',
|
||||
createEmitGroupCheckedPropertyUpdateFunction('grab', 'grabFollowsController'));
|
||||
|
||||
elCloneable.addEventListener('change', createEmitCheckedPropertyUpdateFunction('cloneable'));
|
||||
elCloneableDynamic.addEventListener('change', createEmitCheckedPropertyUpdateFunction('cloneDynamic'));
|
||||
elCloneableAvatarEntity.addEventListener('change', createEmitCheckedPropertyUpdateFunction('cloneAvatarEntity'));
|
||||
elCloneableLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('cloneLifetime'));
|
||||
elCloneableLimit.addEventListener('change', createEmitNumberPropertyUpdateFunction('cloneLimit'));
|
||||
|
||||
elTriggerable.addEventListener('change', function() {
|
||||
userDataChanger("grabbableKey", "triggerable", elTriggerable, elUserData, false, ['wantsTrigger']);
|
||||
});
|
||||
elIgnoreIK.addEventListener('change', function() {
|
||||
userDataChanger("grabbableKey", "ignoreIK", elIgnoreIK, elUserData, true);
|
||||
});
|
||||
|
||||
elCollisionSoundURL.addEventListener('change', createEmitTextPropertyUpdateFunction('collisionSoundURL'));
|
||||
|
||||
elLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifetime'));
|
||||
|
|
|
@ -129,9 +129,7 @@ WebTablet = function (url, width, dpi, hand, clientOnly, location, visible) {
|
|||
url: modelURL, // for overlay
|
||||
grabbable: true, // for overlay
|
||||
loadPriority: 10.0, // for overlay
|
||||
userData: JSON.stringify({
|
||||
"grabbableKey": {"grabbable": true}
|
||||
}),
|
||||
grab: { grabbable: true },
|
||||
dimensions: { x: tabletWidth, y: tabletHeight, z: tabletDepth },
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
visible: visible,
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
BUMPER_ON_VALUE:true,
|
||||
getEntityParents:true,
|
||||
findHandChildEntities:true,
|
||||
findFarGrabJointChildEntities:true,
|
||||
makeLaserParams:true,
|
||||
TEAR_AWAY_DISTANCE:true,
|
||||
TEAR_AWAY_COUNT:true,
|
||||
|
@ -127,13 +128,25 @@ DISPATCHER_PROPERTIES = [
|
|||
"parentJointIndex",
|
||||
"density",
|
||||
"dimensions",
|
||||
"userData",
|
||||
"type",
|
||||
"href",
|
||||
"cloneable",
|
||||
"cloneDynamic",
|
||||
"localPosition",
|
||||
"localRotation"
|
||||
"localRotation",
|
||||
"grab.grabbable",
|
||||
"grab.grabKinematic",
|
||||
"grab.grabFollowsController",
|
||||
"grab.triggerable",
|
||||
"grab.equippable",
|
||||
"grab.equippableLeftPosition",
|
||||
"grab.equippableLeftRotation",
|
||||
"grab.equippableRightPosition",
|
||||
"grab.equippableRightRotation",
|
||||
"grab.equippableIndicatorURL",
|
||||
"grab.equippableIndicatorScale",
|
||||
"grab.equippableIndicatorOffset",
|
||||
"userData"
|
||||
];
|
||||
|
||||
// priority -- a lower priority means the module will be asked sooner than one with a higher priority in a given update step
|
||||
|
@ -215,25 +228,56 @@ getGrabbableData = function (ggdProps) {
|
|||
} catch (err) {
|
||||
userDataParsed = {};
|
||||
}
|
||||
|
||||
if (userDataParsed.grabbableKey) {
|
||||
grabbableData = userDataParsed.grabbableKey;
|
||||
} else {
|
||||
grabbableData = ggdProps.grab;
|
||||
}
|
||||
|
||||
// extract grab-related properties, provide defaults if any are missing
|
||||
if (!grabbableData.hasOwnProperty("grabbable")) {
|
||||
grabbableData.grabbable = true;
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("ignoreIK")) {
|
||||
grabbableData.ignoreIK = true;
|
||||
// kinematic has been renamed to grabKinematic
|
||||
if (!grabbableData.hasOwnProperty("grabKinematic") &&
|
||||
!grabbableData.hasOwnProperty("kinematic")) {
|
||||
grabbableData.grabKinematic = true;
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("kinematic")) {
|
||||
grabbableData.kinematic = true;
|
||||
if (!grabbableData.hasOwnProperty("grabKinematic")) {
|
||||
grabbableData.grabKinematic = grabbableData.kinematic;
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("wantsTrigger")) {
|
||||
grabbableData.wantsTrigger = false;
|
||||
// ignoreIK has been renamed to grabFollowsController
|
||||
if (!grabbableData.hasOwnProperty("grabFollowsController") &&
|
||||
!grabbableData.hasOwnProperty("ignoreIK")) {
|
||||
grabbableData.grabFollowsController = true;
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("triggerable")) {
|
||||
if (!grabbableData.hasOwnProperty("grabFollowsController")) {
|
||||
grabbableData.grabFollowsController = grabbableData.ignoreIK;
|
||||
}
|
||||
// wantsTrigger has been renamed to triggerable
|
||||
if (!grabbableData.hasOwnProperty("triggerable") &&
|
||||
!grabbableData.hasOwnProperty("wantsTrigger")) {
|
||||
grabbableData.triggerable = false;
|
||||
}
|
||||
|
||||
if (!grabbableData.hasOwnProperty("triggerable")) {
|
||||
grabbableData.triggerable = grabbableData.wantsTrigger;
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("equippable")) {
|
||||
grabbableData.equippable = false;
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("equippableLeftPosition")) {
|
||||
grabbableData.equippableLeftPosition = { x: 0, y: 0, z: 0 };
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("equippableLeftRotation")) {
|
||||
grabbableData.equippableLeftPosition = { x: 0, y: 0, z: 0, w: 1 };
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("equippableRightPosition")) {
|
||||
grabbableData.equippableRightPosition = { x: 0, y: 0, z: 0 };
|
||||
}
|
||||
if (!grabbableData.hasOwnProperty("equippableRightRotation")) {
|
||||
grabbableData.equippableRightPosition = { x: 0, y: 0, z: 0, w: 1 };
|
||||
}
|
||||
return grabbableData;
|
||||
};
|
||||
|
||||
|
@ -417,6 +461,18 @@ findHandChildEntities = function(hand) {
|
|||
});
|
||||
};
|
||||
|
||||
findFarGrabJointChildEntities = function(hand) {
|
||||
// find children of avatar's far-grab joint
|
||||
var farGrabJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ? "_FARGRAB_RIGHTHAND" : "_FARGRAB_LEFTHAND");
|
||||
var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, farGrabJointIndex);
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, farGrabJointIndex));
|
||||
|
||||
return children.filter(function (childID) {
|
||||
var childType = Entities.getNestableType(childID);
|
||||
return childType == "entity";
|
||||
});
|
||||
};
|
||||
|
||||
distanceBetweenEntityLocalPositionAndBoundingBox = function(entityProps, jointGrabOffset) {
|
||||
var DEFAULT_REGISTRATION_POINT = { x: 0.5, y: 0.5, z: 0.5 };
|
||||
var rotInv = Quat.inverse(entityProps.localRotation);
|
||||
|
|
|
@ -5,20 +5,25 @@
|
|||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
/* global MyAvatar, Vec3, Controller, Quat */
|
||||
/* global MyAvatar, Vec3, HMD, Controller, Camera, Quat, Settings,
|
||||
getGrabPointSphereOffset:true,
|
||||
setGrabCommunications:true,
|
||||
getGrabCommunications:true,
|
||||
getControllerWorldLocation:true
|
||||
*/
|
||||
|
||||
var GRAB_COMMUNICATIONS_SETTING = "io.highfidelity.isFarGrabbing";
|
||||
setGrabCommunications = function setFarGrabCommunications(on) {
|
||||
Settings.setValue(GRAB_COMMUNICATIONS_SETTING, on ? "on" : "");
|
||||
}
|
||||
};
|
||||
getGrabCommunications = function getFarGrabCommunications() {
|
||||
return !!Settings.getValue(GRAB_COMMUNICATIONS_SETTING, "");
|
||||
}
|
||||
};
|
||||
|
||||
// this offset needs to match the one in libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp:378
|
||||
var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; // x = upward, y = forward, z = lateral
|
||||
|
||||
getGrabPointSphereOffset = function(handController, ignoreSensorToWorldScale) {
|
||||
var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; // x = upward, y = forward, z = lateral
|
||||
var offset = GRAB_POINT_SPHERE_OFFSET;
|
||||
if (handController === Controller.Standard.LeftHand) {
|
||||
offset = {
|
||||
|
@ -39,7 +44,7 @@ getControllerWorldLocation = function (handController, doOffset) {
|
|||
var orientation;
|
||||
var position;
|
||||
var valid = false;
|
||||
|
||||
|
||||
if (handController >= 0) {
|
||||
var pose = Controller.getPoseValue(handController);
|
||||
valid = pose.valid;
|
||||
|
|
|
@ -215,7 +215,9 @@ SelectionManager = (function() {
|
|||
var grabJointNames = [
|
||||
'RightHand', 'LeftHand',
|
||||
'_CONTROLLER_RIGHTHAND', '_CONTROLLER_LEFTHAND',
|
||||
'_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND', '_CAMERA_RELATIVE_CONTROLLER_LEFTHAND'];
|
||||
'_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND', '_CAMERA_RELATIVE_CONTROLLER_LEFTHAND',
|
||||
'_FARGRAB_RIGHTHAND', '_FARGRAB_LEFTHAND', '_FARGRAB_MOUSE'
|
||||
];
|
||||
|
||||
for (var i = 0; i < grabJointNames.length; ++i) {
|
||||
if (avatar.getJointIndex(grabJointNames[i]) === properties.parentJointIndex) {
|
||||
|
|
|
@ -312,9 +312,7 @@ function printToPolaroid(image_url) {
|
|||
"dynamic": true,
|
||||
"collisionsWillMove": true,
|
||||
|
||||
"userData": {
|
||||
"grabbableKey": { "grabbable" : true }
|
||||
}
|
||||
"grab": { "grabbable": true }
|
||||
};
|
||||
|
||||
var polaroid = Entities.addEntity(properties);
|
||||
|
|
|
@ -45,11 +45,7 @@ var cow = Entities.addEntity({
|
|||
lifetime: 3600,
|
||||
shapeType: "box",
|
||||
script: SCRIPT_URL,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
grabbable: true
|
||||
}
|
||||
})
|
||||
grab: { grabbable: true }
|
||||
});
|
||||
|
||||
Script.stop();
|
||||
Script.stop();
|
||||
|
|
|
@ -37,11 +37,6 @@ var flashlight = Entities.addEntity({
|
|||
shapeType: 'box',
|
||||
lifetime: 3600,
|
||||
script: SCRIPT_URL,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
Script.stop();
|
||||
Script.stop();
|
||||
|
|
|
@ -53,35 +53,34 @@ var golfClubProperties = {
|
|||
y: -5.0,
|
||||
z: 0
|
||||
},
|
||||
userData: JSON.stringify({
|
||||
wearable: {
|
||||
joints: {
|
||||
LeftHand: [{
|
||||
x: -0.1631782054901123,
|
||||
y: 0.44648152589797974,
|
||||
z: 0.10100018978118896
|
||||
}, {
|
||||
x: -0.9181621670722961,
|
||||
y: -0.0772884339094162,
|
||||
z: -0.3870723247528076,
|
||||
w: -0.0343472845852375
|
||||
}],
|
||||
RightHand: [{
|
||||
x: 0.16826771199703217,
|
||||
y: 0.4757269620895386,
|
||||
z: 0.07139724493026733
|
||||
}, {
|
||||
x: -0.7976328134536743,
|
||||
y: -0.0011603273451328278,
|
||||
z: 0.6030101776123047,
|
||||
w: -0.012610925361514091
|
||||
}]
|
||||
}
|
||||
grab: {
|
||||
equippable: true,
|
||||
equippableLeftPosition: {
|
||||
x: -0.1631782054901123,
|
||||
y: 0.44648152589797974,
|
||||
z: 0.10100018978118896
|
||||
},
|
||||
equippableLeftRotation: {
|
||||
x: -0.9181621670722961,
|
||||
y: -0.0772884339094162,
|
||||
z: -0.3870723247528076,
|
||||
w: -0.0343472845852375
|
||||
},
|
||||
equippableRightPosition: {
|
||||
x: 0.16826771199703217,
|
||||
y: 0.4757269620895386,
|
||||
z: 0.07139724493026733
|
||||
},
|
||||
equippableRightRotation: {
|
||||
x: -0.7976328134536743,
|
||||
y: -0.0011603273451328278,
|
||||
z: 0.6030101776123047,
|
||||
w: -0.012610925361514091
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var golfClub = Entities.addEntity(golfClubProperties);
|
||||
|
||||
Script.stop();
|
||||
Script.stop();
|
||||
|
|
|
@ -37,35 +37,31 @@ var pingPongGunProperties = {
|
|||
},
|
||||
lifetime: 3600,
|
||||
dynamic: true,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true
|
||||
grab: {
|
||||
equippable: true,
|
||||
equippableLeftPosition: {
|
||||
x: 0.09151676297187805,
|
||||
y: 0.13639454543590546,
|
||||
z: 0.09354984760284424
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.1177130937576294,
|
||||
y: 0.12922893464565277,
|
||||
z: 0.08307232707738876
|
||||
}, {
|
||||
x: 0.4934672713279724,
|
||||
y: 0.3605862259864807,
|
||||
z: 0.6394805908203125,
|
||||
w: -0.4664038419723511
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.09151676297187805,
|
||||
y: 0.13639454543590546,
|
||||
z: 0.09354984760284424
|
||||
}, {
|
||||
x: -0.19628101587295532,
|
||||
y: 0.6418180465698242,
|
||||
z: 0.2830369472503662,
|
||||
w: 0.6851521730422974
|
||||
}]
|
||||
}
|
||||
equippableLeftRotation: {
|
||||
x: -0.19628101587295532,
|
||||
y: 0.6418180465698242,
|
||||
z: 0.2830369472503662,
|
||||
w: 0.6851521730422974
|
||||
},
|
||||
equippableRightPosition: {
|
||||
x: 0.1177130937576294,
|
||||
y: 0.12922893464565277,
|
||||
z: 0.08307232707738876
|
||||
},
|
||||
equippableRightRotation: {
|
||||
x: 0.4934672713279724,
|
||||
y: 0.3605862259864807,
|
||||
z: 0.6394805908203125,
|
||||
w: -0.4664038419723511
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var pingPongGun = Entities.addEntity(pingPongGunProperties);
|
||||
|
|
|
@ -37,38 +37,34 @@ var pistolProperties = {
|
|||
restitution: 0,
|
||||
damping: 0.5,
|
||||
collisionSoundURL: COLLISION_SOUND_URL,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true
|
||||
grab: {
|
||||
equippable: true,
|
||||
equippableLeftPosition: {
|
||||
x: 0.1802254319190979,
|
||||
y: 0.13442856073379517,
|
||||
z: 0.08504903316497803
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.07079616189002991,
|
||||
y: 0.20177987217903137,
|
||||
z: 0.06374628841876984
|
||||
}, {
|
||||
x: -0.5863648653030396,
|
||||
y: -0.46007341146469116,
|
||||
z: 0.46949487924575806,
|
||||
w: -0.4733745753765106
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: 0.1802254319190979,
|
||||
y: 0.13442856073379517,
|
||||
z: 0.08504903316497803
|
||||
}, {
|
||||
x: 0.2198076844215393,
|
||||
y: -0.7377811074256897,
|
||||
z: 0.2780133783817291,
|
||||
w: 0.574519157409668
|
||||
}]
|
||||
}
|
||||
equippableLeftRotation: {
|
||||
x: 0.2198076844215393,
|
||||
y: -0.7377811074256897,
|
||||
z: 0.2780133783817291,
|
||||
w: 0.574519157409668
|
||||
},
|
||||
equippableRightPosition: {
|
||||
x: 0.07079616189002991,
|
||||
y: 0.20177987217903137,
|
||||
z: 0.06374628841876984
|
||||
},
|
||||
equippableRightRotation: {
|
||||
x: -0.5863648653030396,
|
||||
y: -0.46007341146469116,
|
||||
z: 0.46949487924575806,
|
||||
w: -0.4733745753765106
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
var pistol = Entities.addEntity(pistolProperties);
|
||||
|
||||
|
||||
Script.stop();
|
||||
Script.stop();
|
||||
|
|
|
@ -29,11 +29,7 @@ var sword1 = Entities.addEntity({
|
|||
angularDamping: 0,
|
||||
damping: 0,
|
||||
script: SCRIPT_URL,
|
||||
userData:JSON.stringify({
|
||||
grabbableKey:{
|
||||
grabbable:true
|
||||
}
|
||||
})
|
||||
grab: { grabbable: true }
|
||||
});
|
||||
|
||||
var sword2 = Entities.addEntity({
|
||||
|
@ -45,11 +41,7 @@ var sword2 = Entities.addEntity({
|
|||
angularDamping: 0,
|
||||
damping: 0,
|
||||
script: SCRIPT_URL,
|
||||
userData:JSON.stringify({
|
||||
grabbableKey:{
|
||||
grabbable:true
|
||||
}
|
||||
})
|
||||
grab: { grabbable: true }
|
||||
});
|
||||
|
||||
Script.scriptEnding.connect(function scriptEnding() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
/* jslint vars: true, plusplus: true, forin: true*/
|
||||
/* globals Tablet, Script, AvatarList, Users, Entities, MyAvatar, Camera, Overlays, Vec3, Quat, Controller, print, getControllerWorldLocation */
|
||||
/* globals Script, Entities, MyAvatar, Vec3, Quat */
|
||||
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
||||
//
|
||||
// createTetherballStick.js
|
||||
|
@ -59,11 +59,7 @@ var ballID = Entities.addEntity({
|
|||
restitution: BALL_RESTITUTION,
|
||||
dynamic: true,
|
||||
collidesWith: "static,dynamic,otherAvatar,",
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
grabbable: false
|
||||
}
|
||||
})
|
||||
grab: { grabbable: false }
|
||||
});
|
||||
|
||||
var lineID = Entities.addEntity({
|
||||
|
@ -109,43 +105,38 @@ var STICK_PROPERTIES = {
|
|||
},
|
||||
shapeType: 'box',
|
||||
lifetime: LIFETIME,
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
invertSolidWhileHeld: true,
|
||||
ignoreIK: false
|
||||
grab: {
|
||||
grabbable: false,
|
||||
grabFollowsController: false,
|
||||
equippable: true,
|
||||
equippableLeftPosition: {
|
||||
x: -0.14998853206634521,
|
||||
y: 0.17033983767032623,
|
||||
z: 0.023199155926704407
|
||||
},
|
||||
wearable: {
|
||||
joints: {
|
||||
RightHand: [{
|
||||
x: 0.15539926290512085,
|
||||
y: 0.14493153989315033,
|
||||
z: 0.023641478270292282
|
||||
}, {
|
||||
x: 0.5481458902359009,
|
||||
y: -0.4470711946487427,
|
||||
z: -0.3148134648799896,
|
||||
w: 0.6328644752502441
|
||||
}],
|
||||
LeftHand: [{
|
||||
x: -0.14998853206634521,
|
||||
y: 0.17033983767032623,
|
||||
z: 0.023199155926704407
|
||||
},
|
||||
{
|
||||
x: 0.6623835563659668,
|
||||
y: -0.1671387255191803,
|
||||
z: 0.7071226835250854,
|
||||
w: 0.1823924481868744
|
||||
}]
|
||||
}
|
||||
equippableLeftRotation: {
|
||||
x: 0.6623835563659668,
|
||||
y: -0.1671387255191803,
|
||||
z: 0.7071226835250854,
|
||||
w: 0.1823924481868744
|
||||
},
|
||||
ownerID: MyAvatar.sessionUUID,
|
||||
ballID: ballID,
|
||||
lineID: lineID,
|
||||
actionID: actionID,
|
||||
lifetime: LIFETIME,
|
||||
maxDistanceBetweenBallAndStick: ACTION_DISTANCE * MAX_DISTANCE_MULTIPLIER
|
||||
})
|
||||
equippableRightPosition: {
|
||||
x: 0.15539926290512085,
|
||||
y: 0.14493153989315033,
|
||||
z: 0.023641478270292282
|
||||
},
|
||||
equippableRightRotation: {
|
||||
x: 0.5481458902359009,
|
||||
y: -0.4470711946487427,
|
||||
z: -0.3148134648799896,
|
||||
w: 0.6328644752502441
|
||||
}
|
||||
},
|
||||
ownerID: MyAvatar.sessionUUID,
|
||||
ballID: ballID,
|
||||
lineID: lineID,
|
||||
actionID: actionID,
|
||||
maxDistanceBetweenBallAndStick: ACTION_DISTANCE * MAX_DISTANCE_MULTIPLIER
|
||||
};
|
||||
|
||||
Entities.addEntity(STICK_PROPERTIES);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
range: DEFAULT_RANGE,
|
||||
maxVolume: DEFAULT_VOLUME,
|
||||
disabled: true,
|
||||
grabbableKey: { wantsTrigger: true },
|
||||
grab: { triggerable: true }
|
||||
};
|
||||
|
||||
var soundURL = "";
|
||||
|
@ -182,7 +182,7 @@
|
|||
entity = entityID;
|
||||
_this = this;
|
||||
|
||||
var props = Entities.getEntityProperties(entity, [ "userData" ]);
|
||||
var props = Entities.getEntityProperties(entity, [ "userData", "grab.triggerable" ]);
|
||||
var data = {};
|
||||
if (props.userData) {
|
||||
data = JSON.parse(props.userData);
|
||||
|
@ -194,14 +194,15 @@
|
|||
changed = true;
|
||||
}
|
||||
}
|
||||
if (!data.grabbableKey.wantsTrigger) {
|
||||
data.grabbableKey.wantsTrigger = true;
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
debugPrint("applying default values to userData");
|
||||
Entities.editEntity(entity, { userData: JSON.stringify(data) });
|
||||
}
|
||||
|
||||
if (!props.grab.triggerable) {
|
||||
Entities.editEntity(entity, { grab: { triggerable: true } });
|
||||
}
|
||||
|
||||
this._updateColor(data.disabled);
|
||||
this.updateSettings();
|
||||
|
||||
|
|
|
@ -52,32 +52,8 @@
|
|||
It will behave as the constructor
|
||||
*/
|
||||
preload: function(id) {
|
||||
/*
|
||||
We will now override any existing userdata with the grabbable property.
|
||||
Only retrieving userData
|
||||
*/
|
||||
var entityProperties = Entities.getEntityProperties(id, ['userData']);
|
||||
var userData = {
|
||||
grabbableKey: {}
|
||||
};
|
||||
// Check if existing userData field exists.
|
||||
if (entityProperties.userData && entityProperties.userData.length > 0) {
|
||||
try {
|
||||
userData = JSON.parse(entityProperties.userData);
|
||||
if (!userData.grabbableKey) {
|
||||
userData.grabbableKey = {}; // If by random change there is no grabbableKey in the userData.
|
||||
}
|
||||
} catch (e) {
|
||||
// if user data is not valid json, we will simply overwrite it.
|
||||
}
|
||||
}
|
||||
// Object must be triggerable inorder to bind releaseGrabEvent
|
||||
userData.grabbableKey.grabbable = true;
|
||||
|
||||
// Apply the new properties to entity of id
|
||||
Entities.editEntity(id, {
|
||||
userData: JSON.stringify(userData)
|
||||
});
|
||||
Entities.editEntity(id, { grab: { grabbable: true } });
|
||||
Script.scriptEnding.connect(function() {
|
||||
Script.removeEventHandler(id, "releaseGrab", this.releaseGrab);
|
||||
});
|
||||
|
|
|
@ -62,11 +62,7 @@
|
|||
position: originalProps.position,
|
||||
shapeType: originalProps.shapeType,
|
||||
visible: true,
|
||||
userData:JSON.stringify({
|
||||
grabbableKey:{
|
||||
grabbable:false
|
||||
}
|
||||
})
|
||||
grab: { grabbable: false }
|
||||
};
|
||||
_this.copy = Entities.addEntity(props);
|
||||
}
|
||||
|
|
|
@ -142,11 +142,7 @@
|
|||
position: originalProps.position,
|
||||
shapeType: originalProps.shapeType,
|
||||
visible: true,
|
||||
userData:JSON.stringify({
|
||||
grabbableKey:{
|
||||
grabbable:false
|
||||
}
|
||||
})
|
||||
grab: { grabbable: false }
|
||||
};
|
||||
_this.copy = Entities.addEntity(props);
|
||||
}
|
||||
|
|
|
@ -53,14 +53,10 @@
|
|||
y: SIZE,
|
||||
z: SIZE
|
||||
},
|
||||
userData: JSON.stringify({
|
||||
grabbableKey: {
|
||||
cloneable: true,
|
||||
grabbable: true,
|
||||
cloneLifetime: LIFETIME,
|
||||
cloneLimit: 9999
|
||||
}
|
||||
}),
|
||||
grab: { grabbable: true },
|
||||
cloneable: true,
|
||||
cloneLifetime: LIFETIME,
|
||||
cloneLimit: 9999
|
||||
position: Vec3.sum(MyAvatar.position, Vec3.sum(forwardOffset, forwardVector)),
|
||||
color: newColor(),
|
||||
script: SCRIPT_URL
|
||||
|
|
Loading…
Reference in a new issue