mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 12:09:52 +02:00
Merge branch 'protocol_changes' into sound
This commit is contained in:
commit
aa5e8e635e
12 changed files with 130 additions and 75 deletions
|
@ -1123,37 +1123,7 @@ void ModelEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entit
|
||||||
entity->setModel({});
|
entity->setModel({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelPointer& model) {
|
void ModelEntityRenderer::updateJointData(const QVector<glm::vec3>& translations, const QVector<glm::quat>& rotations, const TypedEntityPointer& entity, const ModelPointer& model) {
|
||||||
if (!_animation || !_animation->isLoaded()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<EntityJointData> jointsData;
|
|
||||||
|
|
||||||
const QVector<HFMAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy
|
|
||||||
int frameCount = frames.size();
|
|
||||||
if (frameCount <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
float currentFrame = fmod(entity->getAnimationCurrentFrame(), (float)(frameCount));
|
|
||||||
if (currentFrame < 0.0f) {
|
|
||||||
currentFrame += (float)frameCount;
|
|
||||||
}
|
|
||||||
int currentIntegerFrame = (int)(glm::floor(currentFrame));
|
|
||||||
if (currentIntegerFrame == _lastKnownCurrentFrame) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_lastKnownCurrentFrame = currentIntegerFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_jointMapping.size() != model->getJointStateCount()) {
|
|
||||||
qCWarning(entitiesrenderer) << "RenderableModelEntityItem::getAnimationFrame -- joint count mismatch"
|
|
||||||
<< _jointMapping.size() << model->getJointStateCount();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList animationJointNames = _animation->getHFMModel().getJointNames();
|
QStringList animationJointNames = _animation->getHFMModel().getJointNames();
|
||||||
auto& hfmJoints = _animation->getHFMModel().joints;
|
auto& hfmJoints = _animation->getHFMModel().joints;
|
||||||
|
|
||||||
|
@ -1162,10 +1132,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelP
|
||||||
|
|
||||||
bool allowTranslation = entity->getAnimationAllowTranslation();
|
bool allowTranslation = entity->getAnimationAllowTranslation();
|
||||||
|
|
||||||
const QVector<glm::quat>& rotations = frames[_lastKnownCurrentFrame].rotations;
|
QVector<EntityJointData> jointsData(_jointMapping.size());
|
||||||
const QVector<glm::vec3>& translations = frames[_lastKnownCurrentFrame].translations;
|
|
||||||
|
|
||||||
jointsData.resize(_jointMapping.size());
|
|
||||||
for (int j = 0; j < _jointMapping.size(); j++) {
|
for (int j = 0; j < _jointMapping.size(); j++) {
|
||||||
int index = _jointMapping[j];
|
int index = _jointMapping[j];
|
||||||
|
|
||||||
|
@ -1206,6 +1173,58 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelP
|
||||||
entity->copyAnimationJointDataToModel();
|
entity->copyAnimationJointDataToModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelPointer& model) {
|
||||||
|
if (!_animation || !_animation->isLoaded()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QVector<HFMAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy
|
||||||
|
int frameCount = frames.size();
|
||||||
|
if (frameCount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float currentFrame = fmod(entity->getAnimationCurrentFrame(), (float)(frameCount));
|
||||||
|
if (currentFrame < 0.0f) {
|
||||||
|
currentFrame += (float)frameCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool smoothFrames = entity->getAnimationSmoothFrames();
|
||||||
|
const int currentIntegerFrame = (int)(glm::floor(currentFrame));
|
||||||
|
if (!smoothFrames && currentIntegerFrame == _lastKnownCurrentIntegerFrame) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_lastKnownCurrentIntegerFrame = currentIntegerFrame;
|
||||||
|
|
||||||
|
if (_jointMapping.size() != model->getJointStateCount()) {
|
||||||
|
qCWarning(entitiesrenderer) << "RenderableModelEntityItem::getAnimationFrame -- joint count mismatch"
|
||||||
|
<< _jointMapping.size() << model->getJointStateCount();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smoothFrames) {
|
||||||
|
QVector<glm::quat> rotations = frames[_lastKnownCurrentIntegerFrame].rotations;
|
||||||
|
QVector<glm::vec3> translations = frames[_lastKnownCurrentIntegerFrame].translations;
|
||||||
|
|
||||||
|
const int nextIntegerFrame = entity->getAnimationNextFrame(_lastKnownCurrentIntegerFrame, frameCount);
|
||||||
|
|
||||||
|
const QVector<glm::quat>& nextRotations = frames[nextIntegerFrame].rotations;
|
||||||
|
const QVector<glm::vec3>& nextTranslations = frames[nextIntegerFrame].translations;
|
||||||
|
|
||||||
|
const float frac = glm::fract(currentFrame);
|
||||||
|
for (int i = 0; i < translations.size(); i++) {
|
||||||
|
translations[i] = glm::mix(translations[i], nextTranslations[i], frac);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < rotations.size(); i++) {
|
||||||
|
rotations[i] = glm::slerp(rotations[i], nextRotations[i], frac);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateJointData(translations, rotations, entity, model);
|
||||||
|
} else {
|
||||||
|
updateJointData(frames[_lastKnownCurrentIntegerFrame].translations, frames[_lastKnownCurrentIntegerFrame].rotations, entity, model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||||
if (entity->blendshapesChanged()) {
|
if (entity->blendshapesChanged()) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -175,6 +175,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void animate(const TypedEntityPointer& entity, const ModelPointer& model);
|
void animate(const TypedEntityPointer& entity, const ModelPointer& model);
|
||||||
|
void updateJointData(const QVector<glm::vec3>& translations, const QVector<glm::quat>& rotations, const TypedEntityPointer& entity, const ModelPointer& model);
|
||||||
void mapJoints(const TypedEntityPointer& entity, const ModelPointer& model);
|
void mapJoints(const TypedEntityPointer& entity, const ModelPointer& model);
|
||||||
|
|
||||||
// Transparency is handled in ModelMeshPartPayload
|
// Transparency is handled in ModelMeshPartPayload
|
||||||
|
@ -184,7 +185,7 @@ private:
|
||||||
ModelPointer _model;
|
ModelPointer _model;
|
||||||
QString _textures;
|
QString _textures;
|
||||||
bool _texturesLoaded { false };
|
bool _texturesLoaded { false };
|
||||||
int _lastKnownCurrentFrame { -1 };
|
int _lastKnownCurrentIntegerFrame { -1 };
|
||||||
#ifdef MODEL_ENTITY_USE_FADE_EFFECT
|
#ifdef MODEL_ENTITY_USE_FADE_EFFECT
|
||||||
bool _hasTransitioned{ false };
|
bool _hasTransitioned{ false };
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,20 +32,8 @@ bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b
|
||||||
(a._lastFrame == b._lastFrame) &&
|
(a._lastFrame == b._lastFrame) &&
|
||||||
(a._fps == b._fps) &&
|
(a._fps == b._fps) &&
|
||||||
(a._allowTranslation == b._allowTranslation) &&
|
(a._allowTranslation == b._allowTranslation) &&
|
||||||
(a._url == b._url);
|
(a._url == b._url) &&
|
||||||
}
|
(a._smoothFrames == b._smoothFrames);
|
||||||
|
|
||||||
bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b) {
|
|
||||||
return
|
|
||||||
(a._currentFrame != b._currentFrame) ||
|
|
||||||
(a._running != b._running) ||
|
|
||||||
(a._loop != b._loop) ||
|
|
||||||
(a._hold != b._hold) ||
|
|
||||||
(a._firstFrame != b._firstFrame) ||
|
|
||||||
(a._lastFrame != b._lastFrame) ||
|
|
||||||
(a._fps != b._fps) ||
|
|
||||||
(a._allowTranslation != b._allowTranslation) ||
|
|
||||||
(a._url != b._url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,6 +54,8 @@ bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b
|
||||||
* it isn't.
|
* it isn't.
|
||||||
* @property {boolean} hold=false - <code>true</code> if the rotations and translations of the last frame played are
|
* @property {boolean} hold=false - <code>true</code> if the rotations and translations of the last frame played are
|
||||||
* maintained when the animation stops playing, <code>false</code> if they aren't.
|
* maintained when the animation stops playing, <code>false</code> if they aren't.
|
||||||
|
* @property {boolean} smoothFrames=true - <code>true</code> if the frames of the animation should be linearly interpolated to
|
||||||
|
* create smoother movement, <code>false</code> if the frames should not be interpolated.
|
||||||
*/
|
*/
|
||||||
void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, ScriptValue& properties, ScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url);
|
||||||
|
@ -77,6 +67,7 @@ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desire
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold);
|
||||||
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_SMOOTH_FRAMES, Animation, animation, SmoothFrames, smoothFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,6 +87,7 @@ void AnimationPropertyGroup::copyFromScriptValue(const ScriptValue& object, cons
|
||||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame);
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, firstFrame, float, setFirstFrame);
|
||||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame);
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, lastFrame, float, setLastFrame);
|
||||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold);
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, hold, bool, setHold);
|
||||||
|
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(animation, smoothFrames, bool, setSmoothFrames);
|
||||||
|
|
||||||
// legacy property support
|
// legacy property support
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_GETTER(animationFPS, float, setFPS, getFPS);
|
||||||
|
@ -113,6 +105,7 @@ void AnimationPropertyGroup::merge(const AnimationPropertyGroup& other) {
|
||||||
COPY_PROPERTY_IF_CHANGED(firstFrame);
|
COPY_PROPERTY_IF_CHANGED(firstFrame);
|
||||||
COPY_PROPERTY_IF_CHANGED(lastFrame);
|
COPY_PROPERTY_IF_CHANGED(lastFrame);
|
||||||
COPY_PROPERTY_IF_CHANGED(hold);
|
COPY_PROPERTY_IF_CHANGED(hold);
|
||||||
|
COPY_PROPERTY_IF_CHANGED(smoothFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
|
void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
|
||||||
|
@ -120,19 +113,23 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
|
||||||
// if it includes fps, currentFrame, or running, those values will be parsed out and
|
// if it includes fps, currentFrame, or running, those values will be parsed out and
|
||||||
// will over ride the regular animation settings
|
// will over ride the regular animation settings
|
||||||
|
|
||||||
|
bool allowTranslation = getAllowTranslation();
|
||||||
float fps = getFPS();
|
float fps = getFPS();
|
||||||
float currentFrame = getCurrentFrame();
|
float currentFrame = getCurrentFrame();
|
||||||
bool running = getRunning();
|
bool running = getRunning();
|
||||||
|
bool loop = getLoop();
|
||||||
float firstFrame = getFirstFrame();
|
float firstFrame = getFirstFrame();
|
||||||
float lastFrame = getLastFrame();
|
float lastFrame = getLastFrame();
|
||||||
bool loop = getLoop();
|
|
||||||
bool hold = getHold();
|
bool hold = getHold();
|
||||||
bool allowTranslation = getAllowTranslation();
|
|
||||||
|
|
||||||
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
|
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
|
||||||
QJsonObject settingsAsJsonObject = settingsAsJson.object();
|
QJsonObject settingsAsJsonObject = settingsAsJson.object();
|
||||||
QVariantMap settingsMap = settingsAsJsonObject.toVariantMap();
|
QVariantMap settingsMap = settingsAsJsonObject.toVariantMap();
|
||||||
|
|
||||||
|
if (settingsMap.contains("allowTranslation")) {
|
||||||
|
allowTranslation = settingsMap["allowTranslation"].toBool();
|
||||||
|
}
|
||||||
|
|
||||||
if (settingsMap.contains("fps")) {
|
if (settingsMap.contains("fps")) {
|
||||||
fps = settingsMap["fps"].toFloat();
|
fps = settingsMap["fps"].toFloat();
|
||||||
}
|
}
|
||||||
|
@ -150,30 +147,25 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
|
||||||
firstFrame = settingsMap["firstFrame"].toFloat();
|
firstFrame = settingsMap["firstFrame"].toFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("loop")) {
|
||||||
|
loop = settingsMap["loop"].toBool();
|
||||||
|
}
|
||||||
|
|
||||||
if (settingsMap.contains("lastFrame")) {
|
if (settingsMap.contains("lastFrame")) {
|
||||||
lastFrame = settingsMap["lastFrame"].toFloat();
|
lastFrame = settingsMap["lastFrame"].toFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settingsMap.contains("loop")) {
|
|
||||||
running = settingsMap["loop"].toBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settingsMap.contains("hold")) {
|
if (settingsMap.contains("hold")) {
|
||||||
running = settingsMap["hold"].toBool();
|
hold = settingsMap["hold"].toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settingsMap.contains("allowTranslation")) {
|
|
||||||
allowTranslation = settingsMap["allowTranslation"].toBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
setAllowTranslation(allowTranslation);
|
setAllowTranslation(allowTranslation);
|
||||||
setFPS(fps);
|
setFPS(fps);
|
||||||
setCurrentFrame(currentFrame);
|
setCurrentFrame(currentFrame);
|
||||||
setRunning(running);
|
setRunning(running);
|
||||||
|
setLoop(loop);
|
||||||
setFirstFrame(firstFrame);
|
setFirstFrame(firstFrame);
|
||||||
setLastFrame(lastFrame);
|
setLastFrame(lastFrame);
|
||||||
setLoop(loop);
|
|
||||||
setHold(hold);
|
setHold(hold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +205,9 @@ void AnimationPropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||||
if (holdChanged()) {
|
if (holdChanged()) {
|
||||||
out << "animation-hold";
|
out << "animation-hold";
|
||||||
}
|
}
|
||||||
|
if (smoothFramesChanged()) {
|
||||||
|
out << "animation-smoothFrames";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,6 +229,7 @@ bool AnimationPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SMOOTH_FRAMES, getSmoothFrames());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -253,6 +249,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame);
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame);
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame);
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame);
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold);
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_SMOOTH_FRAMES, bool, setSmoothFrames);
|
||||||
|
|
||||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL);
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_URL, URL);
|
||||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_ALLOW_TRANSLATION, AllowTranslation);
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_ALLOW_TRANSLATION, AllowTranslation);
|
||||||
|
@ -263,6 +260,7 @@ bool AnimationPropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyF
|
||||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame);
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_FIRST_FRAME, FirstFrame);
|
||||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame);
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_LAST_FRAME, LastFrame);
|
||||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold);
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_HOLD, Hold);
|
||||||
|
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_ANIMATION_SMOOTH_FRAMES, SmoothFrames);
|
||||||
|
|
||||||
processedBytes += bytesRead;
|
processedBytes += bytesRead;
|
||||||
|
|
||||||
|
@ -281,6 +279,7 @@ void AnimationPropertyGroup::markAllChanged() {
|
||||||
_firstFrameChanged = true;
|
_firstFrameChanged = true;
|
||||||
_lastFrameChanged = true;
|
_lastFrameChanged = true;
|
||||||
_holdChanged = true;
|
_holdChanged = true;
|
||||||
|
_smoothFramesChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const {
|
EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const {
|
||||||
|
@ -295,6 +294,7 @@ EntityPropertyFlags AnimationPropertyGroup::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame);
|
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FIRST_FRAME, firstFrame);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame);
|
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_LAST_FRAME, lastFrame);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold);
|
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_HOLD, hold);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_SMOOTH_FRAMES, smoothFrames);
|
||||||
|
|
||||||
return changedProperties;
|
return changedProperties;
|
||||||
}
|
}
|
||||||
|
@ -309,6 +309,7 @@ void AnimationPropertyGroup::getProperties(EntityItemProperties& properties) con
|
||||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame);
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, FirstFrame, getFirstFrame);
|
||||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame);
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, LastFrame, getLastFrame);
|
||||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold);
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, Hold, getHold);
|
||||||
|
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Animation, SmoothFrames, getSmoothFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimationPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
bool AnimationPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||||
|
@ -323,6 +324,7 @@ bool AnimationPropertyGroup::setProperties(const EntityItemProperties& propertie
|
||||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame);
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, FirstFrame, firstFrame, setFirstFrame);
|
||||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame);
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, LastFrame, lastFrame, setLastFrame);
|
||||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold);
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, Hold, hold, setHold);
|
||||||
|
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Animation, SmoothFrames, smoothFrames, setSmoothFrames);
|
||||||
return somethingChanged;
|
return somethingChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,6 +340,7 @@ EntityPropertyFlags AnimationPropertyGroup::getEntityProperties(EncodeBitstreamP
|
||||||
requestedProperties += PROP_ANIMATION_FIRST_FRAME;
|
requestedProperties += PROP_ANIMATION_FIRST_FRAME;
|
||||||
requestedProperties += PROP_ANIMATION_LAST_FRAME;
|
requestedProperties += PROP_ANIMATION_LAST_FRAME;
|
||||||
requestedProperties += PROP_ANIMATION_HOLD;
|
requestedProperties += PROP_ANIMATION_HOLD;
|
||||||
|
requestedProperties += PROP_ANIMATION_SMOOTH_FRAMES;
|
||||||
|
|
||||||
return requestedProperties;
|
return requestedProperties;
|
||||||
}
|
}
|
||||||
|
@ -361,6 +364,7 @@ void AnimationPropertyGroup::appendSubclassData(OctreePacketData* packetData, En
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, getFirstFrame());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, getLastFrame());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, getHold());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SMOOTH_FRAMES, getSmoothFrames());
|
||||||
}
|
}
|
||||||
|
|
||||||
int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||||
|
@ -380,6 +384,7 @@ int AnimationPropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame);
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_FIRST_FRAME, float, setFirstFrame);
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame);
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_LAST_FRAME, float, setLastFrame);
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold);
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_HOLD, bool, setHold);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_SMOOTH_FRAMES, bool, setSmoothFrames);
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,11 @@ public:
|
||||||
DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame
|
DEFINE_PROPERTY(PROP_ANIMATION_LAST_FRAME, LastFrame, lastFrame, float, MAXIMUM_POSSIBLE_FRAME); // was animationSettings.lastFrame
|
||||||
DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold
|
DEFINE_PROPERTY(PROP_ANIMATION_HOLD, Hold, hold, bool, false); // was animationSettings.hold
|
||||||
DEFINE_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, AllowTranslation, allowTranslation, bool, true);
|
DEFINE_PROPERTY(PROP_ANIMATION_ALLOW_TRANSLATION, AllowTranslation, allowTranslation, bool, true);
|
||||||
|
DEFINE_PROPERTY(PROP_ANIMATION_SMOOTH_FRAMES, SmoothFrames, smoothFrames, bool, true);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b);
|
friend bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b);
|
||||||
friend bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b);
|
friend bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b) { return !(a == b); }
|
||||||
void setFromOldAnimationSettings(const QString& value);
|
void setFromOldAnimationSettings(const QString& value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2905,6 +2905,7 @@ bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPr
|
||||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame);
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_FIRST_FRAME, Animation, animation, FirstFrame, firstFrame);
|
||||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame);
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_LAST_FRAME, Animation, animation, LastFrame, lastFrame);
|
||||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold);
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_HOLD, Animation, animation, Hold, hold);
|
||||||
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_ANIMATION_SMOOTH_FRAMES, Animation, animation, SmoothFrames, smoothFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Light
|
// Light
|
||||||
|
|
|
@ -237,6 +237,7 @@ enum EntityPropertyList {
|
||||||
PROP_ANIMATION_FIRST_FRAME = PROP_DERIVED_16,
|
PROP_ANIMATION_FIRST_FRAME = PROP_DERIVED_16,
|
||||||
PROP_ANIMATION_LAST_FRAME = PROP_DERIVED_17,
|
PROP_ANIMATION_LAST_FRAME = PROP_DERIVED_17,
|
||||||
PROP_ANIMATION_HOLD = PROP_DERIVED_18,
|
PROP_ANIMATION_HOLD = PROP_DERIVED_18,
|
||||||
|
PROP_ANIMATION_SMOOTH_FRAMES = PROP_DERIVED_19,
|
||||||
|
|
||||||
// Light
|
// Light
|
||||||
PROP_IS_SPOTLIGHT = PROP_DERIVED_0,
|
PROP_IS_SPOTLIGHT = PROP_DERIVED_0,
|
||||||
|
|
|
@ -2892,6 +2892,11 @@ bool EntityTree::readFromMap(QVariantMap& map, const bool isImport) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before, animations weren't smoothed
|
||||||
|
if (contentVersion < (int)EntityVersion::AnimationSmoothFrames && properties.getType() == EntityTypes::EntityType::Model) {
|
||||||
|
properties.getAnimation().setSmoothFrames(false);
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer entity = addEntity(entityItemID, properties, isImport);
|
EntityItemPointer entity = addEntity(entityItemID, properties, isImport);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
||||||
|
|
|
@ -34,12 +34,10 @@ EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const E
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID),
|
ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID),
|
||||||
_blendshapeCoefficientsVector((int)Blendshapes::BlendshapeCount, 0.0f)
|
_blendshapeCoefficientsVector((int)Blendshapes::BlendshapeCount, 0.0f),
|
||||||
|
_lastAnimated(usecTimestampNow())
|
||||||
{
|
{
|
||||||
_lastAnimated = usecTimestampNow();
|
|
||||||
// set the last animated when interface (re)starts
|
|
||||||
_type = EntityTypes::Model;
|
_type = EntityTypes::Model;
|
||||||
_lastKnownCurrentFrame = -1;
|
|
||||||
_visuallyReady = false;
|
_visuallyReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,6 +641,22 @@ bool ModelEntityItem::isAnimatingSomething() const {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ModelEntityItem::getAnimationSmoothFrames() const {
|
||||||
|
return resultWithReadLock<bool>([&] {
|
||||||
|
return _animationProperties.getSmoothFrames();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModelEntityItem::getAnimationNextFrame(int currentFrame, int frameCount) const {
|
||||||
|
return resultWithReadLock<int>([&] {
|
||||||
|
int result = currentFrame + 1;
|
||||||
|
if (result > _animationProperties.getLastFrame() || result > (frameCount - 1)) {
|
||||||
|
result = _animationProperties.getFirstFrame();
|
||||||
|
}
|
||||||
|
return std::max(result, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool ModelEntityItem::applyNewAnimationProperties(AnimationPropertyGroup newProperties) {
|
bool ModelEntityItem::applyNewAnimationProperties(AnimationPropertyGroup newProperties) {
|
||||||
// call applyNewAnimationProperties() whenever trying to update _animationProperties
|
// call applyNewAnimationProperties() whenever trying to update _animationProperties
|
||||||
// because there is some reset logic we need to do whenever the animation "config" properties change
|
// because there is some reset logic we need to do whenever the animation "config" properties change
|
||||||
|
|
|
@ -56,8 +56,6 @@ public:
|
||||||
void setShapeType(ShapeType type) override;
|
void setShapeType(ShapeType type) override;
|
||||||
virtual ShapeType getShapeType() const override;
|
virtual ShapeType getShapeType() const override;
|
||||||
|
|
||||||
// TODO: Move these to subclasses, or other appropriate abstraction
|
|
||||||
// getters/setters applicable to models and particles
|
|
||||||
glm::u8vec3 getColor() const;
|
glm::u8vec3 getColor() const;
|
||||||
void setColor(const glm::u8vec3& value);
|
void setColor(const glm::u8vec3& value);
|
||||||
|
|
||||||
|
@ -89,6 +87,8 @@ public:
|
||||||
float getAnimationCurrentFrame() const;
|
float getAnimationCurrentFrame() const;
|
||||||
bool getAnimationAllowTranslation() const;
|
bool getAnimationAllowTranslation() const;
|
||||||
bool isAnimatingSomething() const;
|
bool isAnimatingSomething() const;
|
||||||
|
bool getAnimationSmoothFrames() const;
|
||||||
|
int getAnimationNextFrame(int currentFrame, int frameCount) const;
|
||||||
|
|
||||||
void setRelayParentJoints(bool relayJoints);
|
void setRelayParentJoints(bool relayJoints);
|
||||||
bool getRelayParentJoints() const;
|
bool getRelayParentJoints() const;
|
||||||
|
@ -148,7 +148,6 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
QVector<ModelJointData> _localJointData;
|
QVector<ModelJointData> _localJointData;
|
||||||
int _lastKnownCurrentFrame{-1};
|
|
||||||
|
|
||||||
glm::u8vec3 _color;
|
glm::u8vec3 _color;
|
||||||
glm::vec3 _modelScale { 1.0f };
|
glm::vec3 _modelScale { 1.0f };
|
||||||
|
|
|
@ -294,6 +294,7 @@ enum class EntityVersion : PacketVersion {
|
||||||
EntityTags,
|
EntityTags,
|
||||||
WantsKeyboardFocus,
|
WantsKeyboardFocus,
|
||||||
AudioZones,
|
AudioZones,
|
||||||
|
AnimationSmoothFrames,
|
||||||
SoundEntities,
|
SoundEntities,
|
||||||
|
|
||||||
// Add new versions above here
|
// Add new versions above here
|
||||||
|
|
|
@ -215,6 +215,9 @@
|
||||||
"animation.fps": {
|
"animation.fps": {
|
||||||
"tooltip": "The speed of the animation."
|
"tooltip": "The speed of the animation."
|
||||||
},
|
},
|
||||||
|
"animation.smoothFrames": {
|
||||||
|
"tooltip": "If enabled, the frames of the animation will be linearly interpolated to create smoother movement."
|
||||||
|
},
|
||||||
"textures": {
|
"textures": {
|
||||||
"tooltip": "A JSON string containing a texture. Use a name from the Original Texture property to override it."
|
"tooltip": "A JSON string containing a texture. Use a name from the Original Texture property to override it."
|
||||||
},
|
},
|
||||||
|
|
|
@ -729,6 +729,11 @@ const GROUPS = [
|
||||||
type: "number-draggable",
|
type: "number-draggable",
|
||||||
propertyID: "animation.fps",
|
propertyID: "animation.fps",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Smooth Animation",
|
||||||
|
type: "bool",
|
||||||
|
propertyID: "animation.smoothFrames",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "Texture",
|
label: "Texture",
|
||||||
type: "textarea",
|
type: "textarea",
|
||||||
|
|
Loading…
Reference in a new issue