Agent bots can manipulate AvatarEntities again

This commit is contained in:
Andrew Meadows 2018-12-12 13:49:44 -08:00
parent 9b253690db
commit 9f404ef006
9 changed files with 73 additions and 7 deletions

View file

@ -21,6 +21,8 @@
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include <ResourceRequestObserver.h> #include <ResourceRequestObserver.h>
#include <AvatarLogging.h> #include <AvatarLogging.h>
#include <EntityItem.h>
#include <EntityItemProperties.h>
ScriptableAvatar::ScriptableAvatar() { ScriptableAvatar::ScriptableAvatar() {
@ -249,3 +251,52 @@ void ScriptableAvatar::setHasProceduralEyeFaceMovement(bool hasProceduralEyeFace
void ScriptableAvatar::setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement) { void ScriptableAvatar::setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement) {
_headData->setHasAudioEnabledFaceMovement(hasAudioEnabledFaceMovement); _headData->setHasAudioEnabledFaceMovement(hasAudioEnabledFaceMovement);
} }
void ScriptableAvatar::updateAvatarEntity(const QUuid& id, const QScriptValue& data) {
if (data.isNull()) {
// interpret this as a DELETE
std::map<QUuid, EntityItemPointer>::iterator itr = _entities.find(id);
if (itr != _entities.end()) {
_entities.erase(itr);
clearAvatarEntity(id);
}
} else {
EntityItemPointer entity;
EntityItemProperties properties;
bool honorReadOnly = true;
properties.copyFromScriptValue(data, honorReadOnly);
std::map<QUuid, EntityItemPointer>::iterator itr = _entities.find(id);
if (itr == _entities.end()) {
// this is an ADD
entity = EntityTypes::constructEntityItem(id, properties);
if (entity) {
OctreePacketData packetData(false, AvatarTraits::MAXIMUM_TRAIT_SIZE);
EncodeBitstreamParams params;
EntityTreeElementExtraEncodeDataPointer extra { nullptr };
OctreeElement::AppendState appendState = entity->appendEntityData(&packetData, params, extra);
if (appendState == OctreeElement::COMPLETED) {
_entities[id] = entity;
QByteArray tempArray((const char*)packetData.getUncompressedData(), packetData.getUncompressedSize());
storeAvatarEntityDataPayload(id, tempArray);
}
}
} else {
// this is an UPDATE
entity = itr->second;
bool somethingChanged = entity->setProperties(properties);
if (somethingChanged) {
OctreePacketData packetData(false, AvatarTraits::MAXIMUM_TRAIT_SIZE);
EncodeBitstreamParams params;
EntityTreeElementExtraEncodeDataPointer extra { nullptr };
OctreeElement::AppendState appendState = entity->appendEntityData(&packetData, params, extra);
if (appendState == OctreeElement::COMPLETED) {
QByteArray tempArray((const char*)packetData.getUncompressedData(), packetData.getUncompressedSize());
storeAvatarEntityDataPayload(id, tempArray);
}
}
}
}
}

View file

@ -16,6 +16,7 @@
#include <AnimSkeleton.h> #include <AnimSkeleton.h>
#include <AvatarData.h> #include <AvatarData.h>
#include <ScriptEngine.h> #include <ScriptEngine.h>
#include <EntityItem.h>
/**jsdoc /**jsdoc
* The <code>Avatar</code> API is used to manipulate scriptable avatars on the domain. This API is a subset of the * The <code>Avatar</code> API is used to manipulate scriptable avatars on the domain. This API is a subset of the
@ -184,6 +185,7 @@ public:
bool getHasProceduralEyeFaceMovement() const override { return _headData->getHasProceduralEyeFaceMovement(); } bool getHasProceduralEyeFaceMovement() const override { return _headData->getHasProceduralEyeFaceMovement(); }
void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement); void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement);
bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); } bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); }
void updateAvatarEntity(const QUuid& id, const QScriptValue& data) override;
public slots: public slots:
void update(float deltatime); void update(float deltatime);
@ -202,6 +204,7 @@ private:
QHash<QString, int> _fstJointIndices; ///< 1-based, since zero is returned for missing keys QHash<QString, int> _fstJointIndices; ///< 1-based, since zero is returned for missing keys
QStringList _fstJointNames; ///< in order of depth-first traversal QStringList _fstJointNames; ///< in order of depth-first traversal
QUrl _skeletonFBXURL; QUrl _skeletonFBXURL;
std::map<QUuid, EntityItemPointer> _entities;
/// Loads the joint indices, names from the FST file (if any) /// Loads the joint indices, names from the FST file (if any)
void updateJointMappings(); void updateJointMappings();

View file

@ -2061,6 +2061,10 @@ void MyAvatar::clearJointsData() {
_skeletonModel->getRig().clearJointStates(); _skeletonModel->getRig().clearJointStates();
} }
void MyAvatar::updateAvatarEntity(const QUuid& id, const QScriptValue& data) {
// TODO: implement this
}
void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
_skeletonModelChangeCount++; _skeletonModelChangeCount++;
int skeletonModelChangeCount = _skeletonModelChangeCount; int skeletonModelChangeCount = _skeletonModelChangeCount;

View file

@ -851,6 +851,8 @@ public:
virtual void clearJointData(const QString& name) override; virtual void clearJointData(const QString& name) override;
virtual void clearJointsData() override; virtual void clearJointsData() override;
void updateAvatarEntity(const QUuid& id, const QScriptValue& data) override;
/**jsdoc /**jsdoc
* @function MyAvatar.pinJoint * @function MyAvatar.pinJoint
* @param {number} index * @param {number} index

View file

@ -235,13 +235,13 @@ public:
void updateDisplayNameAlpha(bool showDisplayName); void updateDisplayNameAlpha(bool showDisplayName);
virtual void setSessionDisplayName(const QString& sessionDisplayName) override { }; // no-op virtual void setSessionDisplayName(const QString& sessionDisplayName) override { }; // no-op
virtual void updateAvatarEntity(const QUuid& entityID, const QScriptValue& entityData) override { }; // no-op
virtual int parseDataFromBuffer(const QByteArray& buffer) override; virtual int parseDataFromBuffer(const QByteArray& buffer) override;
static void renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2, static void renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2,
float radius1, float radius2, const glm::vec4& color); float radius1, float radius2, const glm::vec4& color);
virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { }
/**jsdoc /**jsdoc
* Set the offset applied to the current avatar. The offset adjusts the position that the avatar is rendered. For example, * Set the offset applied to the current avatar. The offset adjusts the position that the avatar is rendered. For example,
* with an offset of <code>{ x: 0, y: 0.1, z: 0 }</code>, your avatar will appear to be raised off the ground slightly. * with an offset of <code>{ x: 0, y: 0.1, z: 0 }</code>, your avatar will appear to be raised off the ground slightly.

View file

@ -2776,8 +2776,8 @@ void AvatarData::storeAvatarEntityDataPayload(const QUuid& entityID, const QByte
} }
} }
void AvatarData::updateAvatarEntity(const QUuid& entityID, const QString& entityPropertiesString) { void AvatarData::updateAvatarEntity(const QUuid& id, const QScriptValue& data) {
// TODO: implement this to expose AvatarEntity to JS // no op
} }
void AvatarData::clearAvatarEntity(const QUuid& entityID, bool requiresRemovalFromTree) { void AvatarData::clearAvatarEntity(const QUuid& entityID, bool requiresRemovalFromTree) {

View file

@ -957,9 +957,9 @@ public:
/**jsdoc /**jsdoc
* @function MyAvatar.updateAvatarEntity * @function MyAvatar.updateAvatarEntity
* @param {Uuid} entityID * @param {Uuid} entityID
* @param {string} entityData * @param {object} entityData
*/ */
Q_INVOKABLE virtual void updateAvatarEntity(const QUuid& entityID, const QString& entityPropertiesString); Q_INVOKABLE virtual void updateAvatarEntity(const QUuid& id, const QScriptValue& data);
/**jsdoc /**jsdoc
* @function MyAvatar.clearAvatarEntity * @function MyAvatar.clearAvatarEntity
@ -1140,10 +1140,11 @@ public:
Q_INVOKABLE AvatarEntityMap getAvatarEntityData() const; Q_INVOKABLE AvatarEntityMap getAvatarEntityData() const;
/**jsdoc /**jsdoc
* Temporarily disabled. Use updateAvatarEntity(id, properties) in the meantime.
* @function MyAvatar.setAvatarEntityData * @function MyAvatar.setAvatarEntityData
* @param {object} avatarEntityData * @param {object} avatarEntityData
*/ */
Q_INVOKABLE void setAvatarEntityData(const AvatarEntityMap& avatarEntityData); void setAvatarEntityData(const AvatarEntityMap& avatarEntityData);
virtual void setAvatarEntityDataChanged(bool value) { _avatarEntityDataChanged = value; } virtual void setAvatarEntityDataChanged(bool value) { _avatarEntityDataChanged = value; }
void insertDetachedEntityID(const QUuid entityID); void insertDetachedEntityID(const QUuid entityID);

View file

@ -151,3 +151,7 @@ EntityItemPointer EntityTypes::constructEntityItem(const unsigned char* data, in
} }
return nullptr; return nullptr;
} }
EntityItemPointer EntityTypes::constructEntityItem(const QUuid& id, const EntityItemProperties& properties) {
return constructEntityItem(properties.getType(), id, properties);
}

View file

@ -116,6 +116,7 @@ public:
static void extractEntityTypeAndID(const unsigned char* data, int dataLength, EntityTypes::EntityType& typeOut, QUuid& idOut); static void extractEntityTypeAndID(const unsigned char* data, int dataLength, EntityTypes::EntityType& typeOut, QUuid& idOut);
static EntityItemPointer constructEntityItem(EntityType entityType, const EntityItemID& entityID, const EntityItemProperties& properties); static EntityItemPointer constructEntityItem(EntityType entityType, const EntityItemID& entityID, const EntityItemProperties& properties);
static EntityItemPointer constructEntityItem(const unsigned char* data, int bytesToRead); static EntityItemPointer constructEntityItem(const unsigned char* data, int bytesToRead);
static EntityItemPointer constructEntityItem(const QUuid& id, const EntityItemProperties& properties);
private: private:
static QMap<EntityType, QString> _typeToNameMap; static QMap<EntityType, QString> _typeToNameMap;