mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 16:13:43 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into run
This commit is contained in:
commit
1e847cf32e
16 changed files with 249 additions and 21 deletions
interface/src/avatar
libraries
avatars-renderer/src/avatars-renderer
entities-renderer/src
entities/src
EntityItemProperties.cppEntityItemProperties.hEntityItemPropertiesDefaults.hEntityPropertyFlags.hModelEntityItem.cppModelEntityItem.h
networking/src/udt
render-utils/src
scripts/developer/tests
|
@ -537,6 +537,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
// we've achived our final adjusted position and rotation for the avatar
|
||||
// and all of its joints, now update our attachements.
|
||||
Avatar::simulateAttachments(deltaTime);
|
||||
relayJointDataToChildren();
|
||||
|
||||
if (!_skeletonModel->hasSkeleton()) {
|
||||
// All the simulation that can be done has been done
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include <shared/Camera.h>
|
||||
#include <SoftAttachmentModel.h>
|
||||
#include <render/TransitionStage.h>
|
||||
#include "ModelEntityItem.h"
|
||||
#include "RenderableModelEntityItem.h"
|
||||
|
||||
#include "Logging.h"
|
||||
|
||||
|
@ -347,6 +349,65 @@ void Avatar::updateAvatarEntities() {
|
|||
setAvatarEntityDataChanged(false);
|
||||
}
|
||||
|
||||
void Avatar::relayJointDataToChildren() {
|
||||
forEachChild([&](SpatiallyNestablePointer child) {
|
||||
if (child->getNestableType() == NestableType::Entity) {
|
||||
auto modelEntity = std::dynamic_pointer_cast<RenderableModelEntityItem>(child);
|
||||
if (modelEntity) {
|
||||
if (modelEntity->getRelayParentJoints()) {
|
||||
if (!modelEntity->getJointMapCompleted() || _reconstructSoftEntitiesJointMap) {
|
||||
QStringList modelJointNames = modelEntity->getJointNames();
|
||||
int numJoints = modelJointNames.count();
|
||||
std::vector<int> map;
|
||||
map.reserve(numJoints);
|
||||
for (int jointIndex = 0; jointIndex < numJoints; jointIndex++) {
|
||||
QString jointName = modelJointNames.at(jointIndex);
|
||||
int avatarJointIndex = getJointIndex(jointName);
|
||||
glm::quat jointRotation;
|
||||
glm::vec3 jointTranslation;
|
||||
if (avatarJointIndex < 0) {
|
||||
jointRotation = modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex);
|
||||
jointTranslation = modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex);
|
||||
map.push_back(-1);
|
||||
} else {
|
||||
int jointIndex = getJointIndex(jointName);
|
||||
jointRotation = getJointRotation(jointIndex);
|
||||
jointTranslation = getJointTranslation(jointIndex);
|
||||
map.push_back(avatarJointIndex);
|
||||
}
|
||||
modelEntity->setLocalJointRotation(jointIndex, jointRotation);
|
||||
modelEntity->setLocalJointTranslation(jointIndex, jointTranslation);
|
||||
}
|
||||
modelEntity->setJointMap(map);
|
||||
} else {
|
||||
QStringList modelJointNames = modelEntity->getJointNames();
|
||||
int numJoints = modelJointNames.count();
|
||||
for (int jointIndex = 0; jointIndex < numJoints; jointIndex++) {
|
||||
int avatarJointIndex = modelEntity->avatarJointIndex(jointIndex);
|
||||
glm::quat jointRotation;
|
||||
glm::vec3 jointTranslation;
|
||||
if (avatarJointIndex >=0) {
|
||||
jointRotation = getJointRotation(avatarJointIndex);
|
||||
jointTranslation = getJointTranslation(avatarJointIndex);
|
||||
} else {
|
||||
jointRotation = modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex);
|
||||
jointTranslation = modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex);
|
||||
}
|
||||
modelEntity->setLocalJointRotation(jointIndex, jointRotation);
|
||||
modelEntity->setLocalJointTranslation(jointIndex, jointTranslation);
|
||||
}
|
||||
}
|
||||
Transform avatarTransform = _skeletonModel->getTransform();
|
||||
avatarTransform.setScale(_skeletonModel->getScale());
|
||||
modelEntity->setOverrideTransform(avatarTransform, _skeletonModel->getOffset());
|
||||
modelEntity->simulateRelayedJoints();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
_reconstructSoftEntitiesJointMap = false;
|
||||
}
|
||||
|
||||
void Avatar::simulate(float deltaTime, bool inView) {
|
||||
PROFILE_RANGE(simulation, "simulate");
|
||||
|
||||
|
@ -379,6 +440,7 @@ void Avatar::simulate(float deltaTime, bool inView) {
|
|||
}
|
||||
head->setScale(getModelScale());
|
||||
head->simulate(deltaTime);
|
||||
relayJointDataToChildren();
|
||||
} else {
|
||||
// a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated.
|
||||
_skeletonModel->simulate(deltaTime, false);
|
||||
|
@ -1197,6 +1259,7 @@ void Avatar::setModelURLFinished(bool success) {
|
|||
invalidateJointIndicesCache();
|
||||
|
||||
_isAnimatingScale = true;
|
||||
_reconstructSoftEntitiesJointMap = true;
|
||||
|
||||
if (!success && _skeletonModelURL != AvatarData::defaultFullAvatarModelUrl()) {
|
||||
const int MAX_SKELETON_DOWNLOAD_ATTEMPTS = 4; // NOTE: we don't want to be as generous as ResourceCache is, we only want 4 attempts
|
||||
|
|
|
@ -330,6 +330,7 @@ protected:
|
|||
|
||||
// protected methods...
|
||||
bool isLookingAtMe(AvatarSharedPointer avatar) const;
|
||||
void relayJointDataToChildren();
|
||||
|
||||
void fade(render::Transaction& transaction, render::Transition::Type type);
|
||||
|
||||
|
@ -382,6 +383,7 @@ protected:
|
|||
bool _isAnimatingScale { false };
|
||||
bool _mustFadeIn { false };
|
||||
bool _isFading { false };
|
||||
bool _reconstructSoftEntitiesJointMap { false };
|
||||
float _modelScale { 1.0f };
|
||||
|
||||
static int _jointConesID;
|
||||
|
|
|
@ -708,6 +708,26 @@ void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape)
|
|||
}
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::setJointMap(std::vector<int> jointMap) {
|
||||
if (jointMap.size() > 0) {
|
||||
_jointMap = jointMap;
|
||||
_jointMapCompleted = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_jointMapCompleted = false;
|
||||
};
|
||||
|
||||
int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) {
|
||||
int result = -1;
|
||||
int mapSize = (int) _jointMap.size();
|
||||
if (modelJointIndex >=0 && modelJointIndex < mapSize) {
|
||||
result = _jointMap[modelJointIndex];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
|
||||
auto model = getModel();
|
||||
if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) {
|
||||
|
@ -813,6 +833,10 @@ bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int ind
|
|||
return setLocalJointTranslation(index, jointRelativePose.trans());
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::getJointMapCompleted() {
|
||||
return _jointMapCompleted;
|
||||
}
|
||||
|
||||
glm::quat RenderableModelEntityItem::getLocalJointRotation(int index) const {
|
||||
auto model = getModel();
|
||||
if (model) {
|
||||
|
@ -835,6 +859,13 @@ glm::vec3 RenderableModelEntityItem::getLocalJointTranslation(int index) const {
|
|||
return glm::vec3();
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::setOverrideTransform(const Transform& transform, const glm::vec3& offset) {
|
||||
auto model = getModel();
|
||||
if (model) {
|
||||
model->overrideModelTransformAndOffset(transform, offset);
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::setLocalJointRotation(int index, const glm::quat& rotation) {
|
||||
autoResizeJointArrays();
|
||||
bool result = false;
|
||||
|
@ -929,6 +960,26 @@ bool RenderableModelEntityItem::getMeshes(MeshProxyList& result) {
|
|||
return !result.isEmpty();
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::simulateRelayedJoints() {
|
||||
ModelPointer model = getModel();
|
||||
if (model && model->isLoaded()) {
|
||||
copyAnimationJointDataToModel();
|
||||
model->simulate(0.0f);
|
||||
model->updateRenderItems();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::stopModelOverrideIfNoParent() {
|
||||
auto model = getModel();
|
||||
if (model) {
|
||||
bool overriding = model->isOverridingModelTransformAndOffset();
|
||||
QUuid parentID = getParentID();
|
||||
if (overriding && (!_relayParentJoints || parentID.isNull())) {
|
||||
model->stopTransformAndOffsetOverride();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::copyAnimationJointDataToModel() {
|
||||
auto model = getModel();
|
||||
if (!model || !model->isLoaded()) {
|
||||
|
@ -1280,6 +1331,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
|||
}
|
||||
|
||||
entity->updateModelBounds();
|
||||
entity->stopModelOverrideIfNoParent();
|
||||
|
||||
if (model->isVisible() != _visible) {
|
||||
// FIXME: this seems like it could be optimized if we tracked our last known visible state in
|
||||
|
|
|
@ -81,8 +81,14 @@ public:
|
|||
void setCollisionShape(const btCollisionShape* shape) override;
|
||||
|
||||
virtual bool contains(const glm::vec3& point) const override;
|
||||
void stopModelOverrideIfNoParent();
|
||||
|
||||
virtual bool shouldBePhysical() const override;
|
||||
void simulateRelayedJoints();
|
||||
bool getJointMapCompleted();
|
||||
void setJointMap(std::vector<int> jointMap);
|
||||
int avatarJointIndex(int modelJointIndex);
|
||||
void setOverrideTransform(const Transform& transform, const glm::vec3& offset);
|
||||
|
||||
// these are in the frame of this object (model space)
|
||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
|
||||
|
@ -90,7 +96,6 @@ public:
|
|||
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override;
|
||||
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override;
|
||||
|
||||
|
||||
virtual glm::quat getLocalJointRotation(int index) const override;
|
||||
virtual glm::vec3 getLocalJointTranslation(int index) const override;
|
||||
virtual bool setLocalJointRotation(int index, const glm::quat& rotation) override;
|
||||
|
@ -119,7 +124,9 @@ private:
|
|||
|
||||
void getCollisionGeometryResource();
|
||||
GeometryResource::Pointer _compoundShapeResource;
|
||||
bool _jointMapCompleted { false };
|
||||
bool _originalTexturesRead { false };
|
||||
std::vector<int> _jointMap;
|
||||
QVariantMap _originalTextures;
|
||||
bool _dimensionsInitialized { true };
|
||||
bool _needsJointSimulation { false };
|
||||
|
|
|
@ -395,6 +395,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
|
||||
CHECK_PROPERTY_CHANGE(PROP_SHAPE, shape);
|
||||
CHECK_PROPERTY_CHANGE(PROP_DPI, dpi);
|
||||
CHECK_PROPERTY_CHANGE(PROP_RELAY_PARENT_JOINTS, relayParentJoints);
|
||||
|
||||
changedProperties += _animation.getChangedProperties();
|
||||
changedProperties += _keyLight.getChangedProperties();
|
||||
|
@ -527,6 +528,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RELAY_PARENT_JOINTS, relayParentJoints);
|
||||
}
|
||||
|
||||
if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) {
|
||||
|
@ -755,6 +757,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusStart, float, setRadiusStart);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusFinish, float, setRadiusFinish);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(relayParentJoints, bool, setRelayParentJoints);
|
||||
|
||||
// Certifiable Properties
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(itemName, QString, setItemName);
|
||||
|
@ -1163,6 +1166,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector<glm::vec3>);
|
||||
ADD_PROPERTY_TO_MAP(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool);
|
||||
|
||||
ADD_PROPERTY_TO_MAP(PROP_SHAPE, Shape, shape, QString);
|
||||
|
||||
|
@ -1386,6 +1390,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, properties.getJointRotations());
|
||||
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, properties.getJointTranslationsSet());
|
||||
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, properties.getJointTranslations());
|
||||
APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, properties.getRelayParentJoints());
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::Light) {
|
||||
|
@ -1745,6 +1750,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector<glm::quat>, setJointRotations);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector<bool>, setJointTranslationsSet);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector<glm::vec3>, setJointTranslations);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints);
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::Light) {
|
||||
|
@ -2089,6 +2095,7 @@ void EntityItemProperties::markAllChanged() {
|
|||
_owningAvatarIDChanged = true;
|
||||
|
||||
_dpiChanged = true;
|
||||
_relayParentJointsChanged = true;
|
||||
}
|
||||
|
||||
// The minimum bounding box for the entity.
|
||||
|
@ -2455,6 +2462,9 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (jointTranslationsChanged()) {
|
||||
out += "jointTranslations";
|
||||
}
|
||||
if (relayParentJointsChanged()) {
|
||||
out += "relayParentJoints";
|
||||
}
|
||||
if (queryAACubeChanged()) {
|
||||
out += "queryAACube";
|
||||
}
|
||||
|
|
|
@ -255,6 +255,7 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid, ENTITY_ITEM_DEFAULT_LAST_EDITED_BY);
|
||||
|
||||
DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS);
|
||||
DEFINE_PROPERTY(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool, ENTITY_ITEM_DEFAULT_RELAY_PARENT_JOINTS);
|
||||
|
||||
static QString getComponentModeString(uint32_t mode);
|
||||
static QString getComponentModeAsString(uint32_t mode);
|
||||
|
|
|
@ -92,4 +92,6 @@ const uint16_t ENTITY_ITEM_DEFAULT_DPI = 30;
|
|||
|
||||
const QUuid ENTITY_ITEM_DEFAULT_LAST_EDITED_BY = QUuid();
|
||||
|
||||
const bool ENTITY_ITEM_DEFAULT_RELAY_PARENT_JOINTS = false;
|
||||
|
||||
#endif // hifi_EntityItemPropertiesDefaults_h
|
||||
|
|
|
@ -40,6 +40,7 @@ enum EntityPropertyList {
|
|||
PROP_ANIMATION_FRAME_INDEX,
|
||||
PROP_ANIMATION_PLAYING,
|
||||
PROP_ANIMATION_ALLOW_TRANSLATION,
|
||||
PROP_RELAY_PARENT_JOINTS,
|
||||
|
||||
// these properties are supported by the EntityItem base class
|
||||
PROP_REGISTRATION_POINT,
|
||||
|
|
|
@ -62,7 +62,7 @@ EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredP
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotations, getJointRotations);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslationsSet, getJointTranslationsSet);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslations, getJointTranslations);
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(relayParentJoints, getRelayParentJoints);
|
||||
_animationProperties.getProperties(properties);
|
||||
return properties;
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) {
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotations, setJointRotations);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslationsSet, setJointTranslationsSet);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslations, setJointTranslations);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(relayParentJoints, setRelayParentJoints);
|
||||
|
||||
bool somethingChangedInAnimations = _animationProperties.setProperties(properties);
|
||||
|
||||
|
@ -115,6 +116,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL);
|
||||
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
||||
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
||||
READ_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints);
|
||||
|
||||
int bytesFromAnimation;
|
||||
withWriteLock([&] {
|
||||
|
@ -155,6 +157,7 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams&
|
|||
requestedProperties += PROP_JOINT_ROTATIONS;
|
||||
requestedProperties += PROP_JOINT_TRANSLATIONS_SET;
|
||||
requestedProperties += PROP_JOINT_TRANSLATIONS;
|
||||
requestedProperties += PROP_RELAY_PARENT_JOINTS;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
@ -173,6 +176,7 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
|
|||
APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, getModelURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
|
||||
APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, getRelayParentJoints());
|
||||
|
||||
withReadLock([&] {
|
||||
_animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
|
||||
|
@ -586,6 +590,18 @@ QString ModelEntityItem::getModelURL() const {
|
|||
});
|
||||
}
|
||||
|
||||
void ModelEntityItem::setRelayParentJoints(bool relayJoints) {
|
||||
withWriteLock([&] {
|
||||
_relayParentJoints = relayJoints;
|
||||
});
|
||||
}
|
||||
|
||||
bool ModelEntityItem::getRelayParentJoints() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return _relayParentJoints;
|
||||
});
|
||||
}
|
||||
|
||||
QString ModelEntityItem::getCompoundShapeURL() const {
|
||||
return _compoundShapeURL.get();
|
||||
}
|
||||
|
|
|
@ -99,6 +99,9 @@ public:
|
|||
void setAnimationHold(bool hold);
|
||||
bool getAnimationHold() const;
|
||||
|
||||
void setRelayParentJoints(bool relayJoints);
|
||||
bool getRelayParentJoints() const;
|
||||
|
||||
void setAnimationFirstFrame(float firstFrame);
|
||||
float getAnimationFirstFrame() const;
|
||||
|
||||
|
@ -157,6 +160,7 @@ protected:
|
|||
|
||||
rgbColor _color;
|
||||
QString _modelURL;
|
||||
bool _relayParentJoints;
|
||||
|
||||
ThreadSafeValueCache<QString> _compoundShapeURL;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::EntityEdit:
|
||||
case PacketType::EntityData:
|
||||
case PacketType::EntityPhysics:
|
||||
return static_cast<PacketVersion>(EntityVersion::ZoneStageRemoved);
|
||||
return static_cast<PacketVersion>(EntityVersion::SoftEntities);
|
||||
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::RemovedJurisdictions);
|
||||
|
|
|
@ -205,7 +205,8 @@ enum class EntityVersion : PacketVersion {
|
|||
StaticCertJsonVersionOne,
|
||||
OwnershipChallengeFix,
|
||||
ZoneLightInheritModes = 82,
|
||||
ZoneStageRemoved
|
||||
ZoneStageRemoved,
|
||||
SoftEntities
|
||||
};
|
||||
|
||||
enum class EntityScriptCallMethodVersion : PacketVersion {
|
||||
|
|
|
@ -145,7 +145,13 @@ void Model::setTransformNoUpdateRenderItems(const Transform& transform) {
|
|||
}
|
||||
|
||||
Transform Model::getTransform() const {
|
||||
if (_spatiallyNestableOverride) {
|
||||
if (_overrideModelTransform) {
|
||||
Transform transform;
|
||||
transform.setTranslation(getOverrideTranslation());
|
||||
transform.setRotation(getOverrideRotation());
|
||||
transform.setScale(getScale());
|
||||
return transform;
|
||||
} else if (_spatiallyNestableOverride) {
|
||||
bool success;
|
||||
Transform transform = _spatiallyNestableOverride->getTransform(success);
|
||||
if (success) {
|
||||
|
@ -1381,6 +1387,14 @@ void Model::deleteGeometry() {
|
|||
_collisionGeometry.reset();
|
||||
}
|
||||
|
||||
void Model::overrideModelTransformAndOffset(const Transform& transform, const glm::vec3& offset) {
|
||||
_overrideTranslation = transform.getTranslation();
|
||||
_overrideRotation = transform.getRotation();
|
||||
_overrideModelTransform = true;
|
||||
setScale(transform.getScale());
|
||||
setOffset(offset);
|
||||
}
|
||||
|
||||
AABox Model::getRenderableMeshBound() const {
|
||||
if (!isLoaded()) {
|
||||
return AABox();
|
||||
|
|
|
@ -212,10 +212,15 @@ public:
|
|||
|
||||
void setTranslation(const glm::vec3& translation);
|
||||
void setRotation(const glm::quat& rotation);
|
||||
void overrideModelTransformAndOffset(const Transform& transform, const glm::vec3& offset);
|
||||
bool isOverridingModelTransformAndOffset() { return _overrideModelTransform; };
|
||||
void stopTransformAndOffsetOverride() { _overrideModelTransform = false; };
|
||||
void setTransformNoUpdateRenderItems(const Transform& transform); // temporary HACK
|
||||
|
||||
const glm::vec3& getTranslation() const { return _translation; }
|
||||
const glm::quat& getRotation() const { return _rotation; }
|
||||
const glm::vec3& getOverrideTranslation() const { return _overrideTranslation; }
|
||||
const glm::quat& getOverrideRotation() const { return _overrideRotation; }
|
||||
|
||||
glm::vec3 getNaturalDimensions() const;
|
||||
|
||||
|
@ -343,6 +348,9 @@ protected:
|
|||
glm::quat _rotation;
|
||||
glm::vec3 _scale;
|
||||
|
||||
glm::vec3 _overrideTranslation;
|
||||
glm::quat _overrideRotation;
|
||||
|
||||
// For entity models this is the translation for the minimum extent of the model (in original mesh coordinate space)
|
||||
// to the model's registration point. For avatar models this is the translation from the avatar's hips, as determined
|
||||
// by the default pose, to the origin.
|
||||
|
@ -403,6 +411,7 @@ protected:
|
|||
|
||||
QMutex _mutex;
|
||||
|
||||
bool _overrideModelTransform { false };
|
||||
bool _triangleSetsValid { false };
|
||||
void calculateTriangleSets();
|
||||
QVector<TriangleSet> _modelSpaceMeshTriangleSets; // model space triangles for all sub meshes
|
||||
|
|
|
@ -57,7 +57,7 @@ ToggleButtonBuddy.prototype.addToggleHandler = function (callback) {
|
|||
};
|
||||
ToggleButtonBuddy.prototype.removeToggleHandler = function (callback) {
|
||||
var index = this.callbacks.indexOf(callback);
|
||||
if (index != -1) {
|
||||
if (index !== -1) {
|
||||
this.callbacks.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
@ -86,13 +86,23 @@ var coatButton = new ToggleButtonBuddy(buttonPositionX, buttonPositionY, BUTTON_
|
|||
down: "https://s3.amazonaws.com/hifi-public/tony/icons/coat-down.svg"
|
||||
});
|
||||
|
||||
buttonPositionY += BUTTON_HEIGHT + BUTTON_PADDING;
|
||||
var coatButton2 = new ToggleButtonBuddy(buttonPositionX, buttonPositionY, BUTTON_WIDTH, BUTTON_HEIGHT, {
|
||||
up: "https://s3.amazonaws.com/hifi-public/tony/icons/coat-up.svg",
|
||||
down: "https://s3.amazonaws.com/hifi-public/tony/icons/coat-down.svg"
|
||||
});
|
||||
|
||||
var AVATAR_ATTACHMENT = 0;
|
||||
var AVATAR_SOFT_ATTACHMENT = 1;
|
||||
var ENTITY_ATTACHMENT = 2;
|
||||
|
||||
var HAT_ATTACHMENT = {
|
||||
modelURL: "https://s3.amazonaws.com/hifi-public/tony/cowboy-hat.fbx",
|
||||
jointName: "Head",
|
||||
translation: {"x": 0, "y": 0.25, "z": 0.03},
|
||||
rotation: {"x": 0, "y": 0, "z": 0, "w": 1},
|
||||
scale: 0.052,
|
||||
isSoft: false
|
||||
type: AVATAR_ATTACHMENT
|
||||
};
|
||||
|
||||
var COAT_ATTACHMENT = {
|
||||
|
@ -101,7 +111,16 @@ var COAT_ATTACHMENT = {
|
|||
translation: {"x": 0, "y": 0, "z": 0},
|
||||
rotation: {"x": 0, "y": 0, "z": 0, "w": 1},
|
||||
scale: 1,
|
||||
isSoft: true
|
||||
type: AVATAR_SOFT_ATTACHMENT
|
||||
};
|
||||
|
||||
var COAT_ENTITY_ATTACHMENT = {
|
||||
modelURL: "https://hifi-content.s3.amazonaws.com/ozan/dev/clothes/coat/coat_rig.fbx",
|
||||
jointName: "Hips",
|
||||
translation: {"x": 0, "y": 0, "z": 0},
|
||||
rotation: {"x": 0, "y": 0, "z": 0, "w": 1},
|
||||
scale: 1,
|
||||
type: ENTITY_ATTACHMENT
|
||||
};
|
||||
|
||||
hatButton.addToggleHandler(function (isDown) {
|
||||
|
@ -120,28 +139,54 @@ coatButton.addToggleHandler(function (isDown) {
|
|||
}
|
||||
});
|
||||
|
||||
coatButton2.addToggleHandler(function (isDown) {
|
||||
if (isDown) {
|
||||
wearAttachment(COAT_ENTITY_ATTACHMENT);
|
||||
} else {
|
||||
removeAttachment(COAT_ENTITY_ATTACHMENT);
|
||||
}
|
||||
});
|
||||
|
||||
function wearAttachment(attachment) {
|
||||
MyAvatar.attach(attachment.modelURL,
|
||||
attachment.jointName,
|
||||
attachment.translation,
|
||||
attachment.rotation,
|
||||
attachment.scale,
|
||||
attachment.isSoft);
|
||||
if (attachment.type === AVATAR_ATTACHMENT || attachment.type === AVATAR_SOFT_ATTACHMENT) {
|
||||
MyAvatar.attach(attachment.modelURL,
|
||||
attachment.jointName,
|
||||
attachment.translation,
|
||||
attachment.rotation,
|
||||
attachment.scale,
|
||||
(attachment.type === AVATAR_SOFT_ATTACHMENT));
|
||||
} else {
|
||||
attachment.entityID = Entities.addEntity({
|
||||
name: "attachment",
|
||||
type: "Model",
|
||||
modelURL: attachment.modelURL,
|
||||
parentID: MyAvatar.sessionUUID,
|
||||
relayParentJoints: true,
|
||||
position: attachment.position,
|
||||
rotation: attachment.rotation,
|
||||
parentJointIndex: -1
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
function removeAttachment(attachment) {
|
||||
var attachments = MyAvatar.attachmentData;
|
||||
var i, l = attachments.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
if (attachments[i].modelURL === attachment.modelURL) {
|
||||
attachments.splice(i, 1);
|
||||
MyAvatar.attachmentData = attachments;
|
||||
break;
|
||||
if (attachment.type === AVATAR_ATTACHMENT || attachment.type === AVATAR_SOFT_ATTACHMENT) {
|
||||
var attachments = MyAvatar.attachmentData;
|
||||
var i, l = attachments.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
if (attachments[i].modelURL === attachment.modelURL) {
|
||||
attachments.splice(i, 1);
|
||||
MyAvatar.attachmentData = attachments;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Entities.deleteEntity(attachment.entityID);
|
||||
}
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
hatButton.destroy();
|
||||
coatButton.destroy();
|
||||
coatButton2.destroy();
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue