mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-10 20:58:37 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into chessgame
This commit is contained in:
commit
a0afcdfe79
16 changed files with 538 additions and 102 deletions
|
@ -22,6 +22,9 @@ EntityPropertyDialogBox = (function () {
|
||||||
var dimensionZ;
|
var dimensionZ;
|
||||||
var rescalePercentage;
|
var rescalePercentage;
|
||||||
var editModelID = -1;
|
var editModelID = -1;
|
||||||
|
var previousAnimationIsPlaying;
|
||||||
|
var previousAnimationFrameIndex;
|
||||||
|
var previousAnimationSettings;
|
||||||
|
|
||||||
that.cleanup = function () {
|
that.cleanup = function () {
|
||||||
};
|
};
|
||||||
|
@ -47,10 +50,15 @@ EntityPropertyDialogBox = (function () {
|
||||||
array.push({ label: "Animation URL:", value: properties.animationURL });
|
array.push({ label: "Animation URL:", value: properties.animationURL });
|
||||||
index++;
|
index++;
|
||||||
array.push({ label: "Animation is playing:", value: properties.animationIsPlaying });
|
array.push({ label: "Animation is playing:", value: properties.animationIsPlaying });
|
||||||
|
previousAnimationIsPlaying = properties.animationIsPlaying;
|
||||||
index++;
|
index++;
|
||||||
array.push({ label: "Animation FPS:", value: properties.animationFPS });
|
array.push({ label: "Animation FPS:", value: properties.animationFPS });
|
||||||
index++;
|
index++;
|
||||||
array.push({ label: "Animation Frame:", value: properties.animationFrameIndex });
|
array.push({ label: "Animation Frame:", value: properties.animationFrameIndex });
|
||||||
|
previousAnimationFrameIndex = properties.animationFrameIndex;
|
||||||
|
index++;
|
||||||
|
array.push({ label: "Animation Settings:", value: properties.animationSettings });
|
||||||
|
previousAnimationSettings = properties.animationSettings;
|
||||||
index++;
|
index++;
|
||||||
array.push({ label: "Textures:", value: properties.textures });
|
array.push({ label: "Textures:", value: properties.textures });
|
||||||
index++;
|
index++;
|
||||||
|
@ -237,9 +245,29 @@ EntityPropertyDialogBox = (function () {
|
||||||
if (properties.type == "Model") {
|
if (properties.type == "Model") {
|
||||||
properties.modelURL = array[index++].value;
|
properties.modelURL = array[index++].value;
|
||||||
properties.animationURL = array[index++].value;
|
properties.animationURL = array[index++].value;
|
||||||
properties.animationIsPlaying = array[index++].value;
|
|
||||||
|
var newAnimationIsPlaying = array[index++].value;
|
||||||
|
if (previousAnimationIsPlaying != newAnimationIsPlaying) {
|
||||||
|
properties.animationIsPlaying = newAnimationIsPlaying;
|
||||||
|
} else {
|
||||||
|
delete properties.animationIsPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
properties.animationFPS = array[index++].value;
|
properties.animationFPS = array[index++].value;
|
||||||
properties.animationFrameIndex = array[index++].value;
|
|
||||||
|
var newAnimationFrameIndex = array[index++].value;
|
||||||
|
if (previousAnimationFrameIndex != newAnimationFrameIndex) {
|
||||||
|
properties.animationFrameIndex = newAnimationFrameIndex;
|
||||||
|
} else {
|
||||||
|
delete properties.animationFrameIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newAnimationSettings = array[index++].value;
|
||||||
|
if (previousAnimationSettings != newAnimationSettings) {
|
||||||
|
properties.animationSettings = newAnimationSettings;
|
||||||
|
} else {
|
||||||
|
delete properties.animationSettings;
|
||||||
|
}
|
||||||
properties.textures = array[index++].value;
|
properties.textures = array[index++].value;
|
||||||
index++; // skip textureNames label
|
index++; // skip textureNames label
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ void AnimationHandle::setPriority(float priority) {
|
||||||
if (_priority == priority) {
|
if (_priority == priority) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_running) {
|
if (isRunning()) {
|
||||||
_model->_runningAnimations.removeOne(_self);
|
_model->_runningAnimations.removeOne(_self);
|
||||||
if (priority < _priority) {
|
if (priority < _priority) {
|
||||||
replaceMatchingPriorities(priority);
|
replaceMatchingPriorities(priority);
|
||||||
|
@ -47,7 +47,8 @@ void AnimationHandle::setPriority(float priority) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationHandle::setStartAutomatically(bool startAutomatically) {
|
void AnimationHandle::setStartAutomatically(bool startAutomatically) {
|
||||||
if ((_startAutomatically = startAutomatically) && !_running) {
|
_animationLoop.setStartAutomatically(startAutomatically);
|
||||||
|
if (getStartAutomatically() && !isRunning()) {
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,48 +59,59 @@ void AnimationHandle::setMaskedJoints(const QStringList& maskedJoints) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationHandle::setRunning(bool running) {
|
void AnimationHandle::setRunning(bool running) {
|
||||||
if (_running == running) {
|
if (isRunning() == running) {
|
||||||
|
// if we're already running, this is the same as a restart
|
||||||
if (running) {
|
if (running) {
|
||||||
// move back to the beginning
|
// move back to the beginning
|
||||||
_frameIndex = _firstFrame;
|
setFrameIndex(getFirstFrame());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((_running = running)) {
|
_animationLoop.setRunning(running);
|
||||||
|
if (isRunning()) {
|
||||||
if (!_model->_runningAnimations.contains(_self)) {
|
if (!_model->_runningAnimations.contains(_self)) {
|
||||||
insertSorted(_model->_runningAnimations, _self);
|
insertSorted(_model->_runningAnimations, _self);
|
||||||
}
|
}
|
||||||
_frameIndex = _firstFrame;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_model->_runningAnimations.removeOne(_self);
|
_model->_runningAnimations.removeOne(_self);
|
||||||
replaceMatchingPriorities(0.0f);
|
replaceMatchingPriorities(0.0f);
|
||||||
}
|
}
|
||||||
emit runningChanged(_running);
|
emit runningChanged(isRunning());
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationHandle::AnimationHandle(Model* model) :
|
AnimationHandle::AnimationHandle(Model* model) :
|
||||||
QObject(model),
|
QObject(model),
|
||||||
_model(model),
|
_model(model),
|
||||||
_fps(30.0f),
|
_priority(1.0f)
|
||||||
_priority(1.0f),
|
{
|
||||||
_loop(false),
|
|
||||||
_hold(false),
|
|
||||||
_startAutomatically(false),
|
|
||||||
_firstFrame(0.0f),
|
|
||||||
_lastFrame(FLT_MAX),
|
|
||||||
_running(false) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationDetails AnimationHandle::getAnimationDetails() const {
|
AnimationDetails AnimationHandle::getAnimationDetails() const {
|
||||||
AnimationDetails details(_role, _url, _fps, _priority, _loop, _hold,
|
AnimationDetails details(_role, _url, getFPS(), _priority, getLoop(), getHold(),
|
||||||
_startAutomatically, _firstFrame, _lastFrame, _running, _frameIndex);
|
getStartAutomatically(), getFirstFrame(), getLastFrame(), isRunning(), getFrameIndex());
|
||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimationHandle::setAnimationDetails(const AnimationDetails& details) {
|
||||||
|
setRole(details.role);
|
||||||
|
setURL(details.url);
|
||||||
|
setFPS(details.fps);
|
||||||
|
setPriority(details.priority);
|
||||||
|
setLoop(details.loop);
|
||||||
|
setHold(details.hold);
|
||||||
|
setStartAutomatically(details.startAutomatically);
|
||||||
|
setFirstFrame(details.firstFrame);
|
||||||
|
setLastFrame(details.lastFrame);
|
||||||
|
setRunning(details.running);
|
||||||
|
setFrameIndex(details.frameIndex);
|
||||||
|
|
||||||
|
// NOTE: AnimationDetails doesn't support maskedJoints
|
||||||
|
//setMaskedJoints(const QStringList& maskedJoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AnimationHandle::simulate(float deltaTime) {
|
void AnimationHandle::simulate(float deltaTime) {
|
||||||
_frameIndex += deltaTime * _fps;
|
_animationLoop.simulate(deltaTime);
|
||||||
|
|
||||||
// update the joint mappings if necessary/possible
|
// update the joint mappings if necessary/possible
|
||||||
if (_jointMappings.isEmpty()) {
|
if (_jointMappings.isEmpty()) {
|
||||||
|
@ -125,26 +137,15 @@ void AnimationHandle::simulate(float deltaTime) {
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float endFrameIndex = qMin(_lastFrame, animationGeometry.animationFrames.size() - (_loop ? 0.0f : 1.0f));
|
|
||||||
float startFrameIndex = qMin(_firstFrame, endFrameIndex);
|
|
||||||
if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) {
|
|
||||||
// passed the end; apply the last frame
|
|
||||||
applyFrame(glm::clamp(_frameIndex, startFrameIndex, endFrameIndex));
|
|
||||||
if (!_hold) {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// wrap within the the desired range
|
|
||||||
if (_frameIndex < startFrameIndex) {
|
|
||||||
_frameIndex = endFrameIndex - glm::mod(endFrameIndex - _frameIndex, endFrameIndex - startFrameIndex);
|
|
||||||
|
|
||||||
} else if (_frameIndex > endFrameIndex) {
|
|
||||||
_frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// TODO: When moving the loop/frame calculations to AnimationLoop class, we changed this behavior
|
||||||
|
// see AnimationLoop class for more details. Do we need to support clamping the endFrameIndex to
|
||||||
|
// the max number of frames in the geometry???
|
||||||
|
//
|
||||||
|
// float endFrameIndex = qMin(_lastFrame, animationGeometry.animationFrames.size() - (_loop ? 0.0f : 1.0f));
|
||||||
|
|
||||||
// blend between the closest two frames
|
// blend between the closest two frames
|
||||||
applyFrame(_frameIndex);
|
applyFrame(getFrameIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationHandle::applyFrame(float frameIndex) {
|
void AnimationHandle::applyFrame(float frameIndex) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include <AnimationCache.h>
|
#include <AnimationCache.h>
|
||||||
|
#include <AnimationLoop.h>
|
||||||
|
|
||||||
class AnimationHandle;
|
class AnimationHandle;
|
||||||
class Model;
|
class Model;
|
||||||
|
@ -38,38 +39,40 @@ public:
|
||||||
|
|
||||||
void setURL(const QUrl& url);
|
void setURL(const QUrl& url);
|
||||||
const QUrl& getURL() const { return _url; }
|
const QUrl& getURL() const { return _url; }
|
||||||
|
|
||||||
void setFPS(float fps) { _fps = fps; }
|
|
||||||
float getFPS() const { return _fps; }
|
|
||||||
|
|
||||||
void setPriority(float priority);
|
void setPriority(float priority);
|
||||||
float getPriority() const { return _priority; }
|
float getPriority() const { return _priority; }
|
||||||
|
|
||||||
void setLoop(bool loop) { _loop = loop; }
|
|
||||||
bool getLoop() const { return _loop; }
|
|
||||||
|
|
||||||
void setHold(bool hold) { _hold = hold; }
|
|
||||||
bool getHold() const { return _hold; }
|
|
||||||
|
|
||||||
void setStartAutomatically(bool startAutomatically);
|
|
||||||
bool getStartAutomatically() const { return _startAutomatically; }
|
|
||||||
|
|
||||||
void setFirstFrame(float firstFrame) { _firstFrame = firstFrame; }
|
|
||||||
float getFirstFrame() const { return _firstFrame; }
|
|
||||||
|
|
||||||
void setLastFrame(float lastFrame) { _lastFrame = lastFrame; }
|
|
||||||
float getLastFrame() const { return _lastFrame; }
|
|
||||||
|
|
||||||
void setMaskedJoints(const QStringList& maskedJoints);
|
void setMaskedJoints(const QStringList& maskedJoints);
|
||||||
const QStringList& getMaskedJoints() const { return _maskedJoints; }
|
const QStringList& getMaskedJoints() const { return _maskedJoints; }
|
||||||
|
|
||||||
void setRunning(bool running);
|
|
||||||
bool isRunning() const { return _running; }
|
|
||||||
|
|
||||||
void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(_frameIndex, _firstFrame, _lastFrame); }
|
void setFPS(float fps) { _animationLoop.setFPS(fps); }
|
||||||
float getFrameIndex() const { return _frameIndex; }
|
float getFPS() const { return _animationLoop.getFPS(); }
|
||||||
|
|
||||||
|
void setLoop(bool loop) { _animationLoop.setLoop(loop); }
|
||||||
|
bool getLoop() const { return _animationLoop.getLoop(); }
|
||||||
|
|
||||||
|
void setHold(bool hold) { _animationLoop.setHold(hold); }
|
||||||
|
bool getHold() const { return _animationLoop.getHold(); }
|
||||||
|
|
||||||
|
void setStartAutomatically(bool startAutomatically);
|
||||||
|
bool getStartAutomatically() const { return _animationLoop.getStartAutomatically(); }
|
||||||
|
|
||||||
|
void setFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); }
|
||||||
|
float getFirstFrame() const { return _animationLoop.getFirstFrame(); }
|
||||||
|
|
||||||
|
void setLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); }
|
||||||
|
float getLastFrame() const { return _animationLoop.getLastFrame(); }
|
||||||
|
|
||||||
|
void setRunning(bool running);
|
||||||
|
bool isRunning() const { return _animationLoop.isRunning(); }
|
||||||
|
|
||||||
|
void setFrameIndex(float frameIndex) { _animationLoop.setFrameIndex(frameIndex); }
|
||||||
|
float getFrameIndex() const { return _animationLoop.getFrameIndex(); }
|
||||||
|
|
||||||
AnimationDetails getAnimationDetails() const;
|
AnimationDetails getAnimationDetails() const;
|
||||||
|
void setAnimationDetails(const AnimationDetails& details);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
@ -95,17 +98,12 @@ private:
|
||||||
AnimationPointer _animation;
|
AnimationPointer _animation;
|
||||||
QString _role;
|
QString _role;
|
||||||
QUrl _url;
|
QUrl _url;
|
||||||
float _fps;
|
|
||||||
float _priority;
|
float _priority;
|
||||||
bool _loop;
|
|
||||||
bool _hold;
|
|
||||||
bool _startAutomatically;
|
|
||||||
float _firstFrame;
|
|
||||||
float _lastFrame;
|
|
||||||
QStringList _maskedJoints;
|
QStringList _maskedJoints;
|
||||||
bool _running;
|
|
||||||
QVector<int> _jointMappings;
|
QVector<int> _jointMappings;
|
||||||
float _frameIndex;
|
|
||||||
|
AnimationLoop _animationLoop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,5 +94,4 @@ Q_DECLARE_METATYPE(AnimationDetails);
|
||||||
QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& event);
|
QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& event);
|
||||||
void animationDetailsFromScriptValue(const QScriptValue& object, AnimationDetails& event);
|
void animationDetailsFromScriptValue(const QScriptValue& object, AnimationDetails& event);
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_AnimationCache_h
|
#endif // hifi_AnimationCache_h
|
||||||
|
|
95
libraries/animation/src/AnimationLoop.cpp
Normal file
95
libraries/animation/src/AnimationLoop.cpp
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
//
|
||||||
|
// AnimationLoop.cpp
|
||||||
|
// libraries/animation
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 11/12/14.
|
||||||
|
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "AnimationCache.h"
|
||||||
|
#include "AnimationLoop.h"
|
||||||
|
|
||||||
|
AnimationLoop::AnimationLoop() :
|
||||||
|
_fps(30.0f),
|
||||||
|
_loop(false),
|
||||||
|
_hold(false),
|
||||||
|
_startAutomatically(false),
|
||||||
|
_firstFrame(0.0f),
|
||||||
|
_lastFrame(FLT_MAX),
|
||||||
|
_running(false),
|
||||||
|
_frameIndex(0.0f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationLoop::AnimationLoop(const AnimationDetails& animationDetails) :
|
||||||
|
_fps(animationDetails.fps),
|
||||||
|
_loop(animationDetails.loop),
|
||||||
|
_hold(animationDetails.hold),
|
||||||
|
_startAutomatically(animationDetails.startAutomatically),
|
||||||
|
_firstFrame(animationDetails.firstFrame),
|
||||||
|
_lastFrame(animationDetails.lastFrame),
|
||||||
|
_running(animationDetails.running),
|
||||||
|
_frameIndex(animationDetails.frameIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomatically, float firstFrame,
|
||||||
|
float lastFrame, bool running, float frameIndex) :
|
||||||
|
_fps(fps),
|
||||||
|
_loop(loop),
|
||||||
|
_hold(hold),
|
||||||
|
_startAutomatically(startAutomatically),
|
||||||
|
_firstFrame(firstFrame),
|
||||||
|
_lastFrame(lastFrame),
|
||||||
|
_running(running),
|
||||||
|
_frameIndex(frameIndex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimationLoop::simulate(float deltaTime) {
|
||||||
|
_frameIndex += deltaTime * _fps;
|
||||||
|
|
||||||
|
|
||||||
|
// If we knew the number of frames from the animation, we'd consider using it here
|
||||||
|
// animationGeometry.animationFrames.size()
|
||||||
|
float maxFrame = _lastFrame;
|
||||||
|
float endFrameIndex = qMin(_lastFrame, maxFrame - (_loop ? 0.0f : 1.0f));
|
||||||
|
float startFrameIndex = qMin(_firstFrame, endFrameIndex);
|
||||||
|
if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) {
|
||||||
|
// passed the end; apply the last frame
|
||||||
|
_frameIndex = glm::clamp(_frameIndex, startFrameIndex, endFrameIndex);
|
||||||
|
if (!_hold) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// wrap within the the desired range
|
||||||
|
if (_frameIndex < startFrameIndex) {
|
||||||
|
_frameIndex = endFrameIndex - glm::mod(endFrameIndex - _frameIndex, endFrameIndex - startFrameIndex);
|
||||||
|
|
||||||
|
} else if (_frameIndex > endFrameIndex) {
|
||||||
|
_frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimationLoop::setStartAutomatically(bool startAutomatically) {
|
||||||
|
if ((_startAutomatically = startAutomatically) && !isRunning()) {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimationLoop::setRunning(bool running) {
|
||||||
|
if (_running == running) {
|
||||||
|
if (running) {
|
||||||
|
// move back to the beginning
|
||||||
|
_frameIndex = _firstFrame;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((_running = running)) {
|
||||||
|
_frameIndex = _firstFrame;
|
||||||
|
}
|
||||||
|
}
|
63
libraries/animation/src/AnimationLoop.h
Normal file
63
libraries/animation/src/AnimationLoop.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
//
|
||||||
|
// AnimationLoop.h
|
||||||
|
// libraries/script-engine/src/
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 11/12/14.
|
||||||
|
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// 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_AnimationLoop_h
|
||||||
|
#define hifi_AnimationLoop_h
|
||||||
|
|
||||||
|
class AnimationDetails;
|
||||||
|
|
||||||
|
class AnimationLoop {
|
||||||
|
public:
|
||||||
|
AnimationLoop();
|
||||||
|
AnimationLoop(const AnimationDetails& animationDetails);
|
||||||
|
AnimationLoop(float fps, bool loop, bool hold, bool startAutomatically, float firstFrame,
|
||||||
|
float lastFrame, bool running, float frameIndex);
|
||||||
|
|
||||||
|
void setFPS(float fps) { _fps = fps; }
|
||||||
|
float getFPS() const { return _fps; }
|
||||||
|
|
||||||
|
void setLoop(bool loop) { _loop = loop; }
|
||||||
|
bool getLoop() const { return _loop; }
|
||||||
|
|
||||||
|
void setHold(bool hold) { _hold = hold; }
|
||||||
|
bool getHold() const { return _hold; }
|
||||||
|
|
||||||
|
void setStartAutomatically(bool startAutomatically);
|
||||||
|
bool getStartAutomatically() const { return _startAutomatically; }
|
||||||
|
|
||||||
|
void setFirstFrame(float firstFrame) { _firstFrame = firstFrame; }
|
||||||
|
float getFirstFrame() const { return _firstFrame; }
|
||||||
|
|
||||||
|
void setLastFrame(float lastFrame) { _lastFrame = lastFrame; }
|
||||||
|
float getLastFrame() const { return _lastFrame; }
|
||||||
|
|
||||||
|
void setRunning(bool running);
|
||||||
|
bool isRunning() const { return _running; }
|
||||||
|
|
||||||
|
void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(frameIndex, _firstFrame, _lastFrame); }
|
||||||
|
float getFrameIndex() const { return _frameIndex; }
|
||||||
|
|
||||||
|
void start() { setRunning(true); }
|
||||||
|
void stop() { setRunning(false); }
|
||||||
|
void simulate(float deltaTime);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float _fps;
|
||||||
|
bool _loop;
|
||||||
|
bool _hold;
|
||||||
|
bool _startAutomatically;
|
||||||
|
float _firstFrame;
|
||||||
|
float _lastFrame;
|
||||||
|
bool _running;
|
||||||
|
float _frameIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_AnimationLoop_h
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QtCore/QJsonDocument>
|
||||||
|
|
||||||
#include <ByteCountCoding.h>
|
#include <ByteCountCoding.h>
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
@ -66,6 +67,7 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
_animationIsPlaying(ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING),
|
_animationIsPlaying(ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING),
|
||||||
_animationFrameIndex(ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX),
|
_animationFrameIndex(ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX),
|
||||||
_animationFPS(ModelEntityItem::DEFAULT_ANIMATION_FPS),
|
_animationFPS(ModelEntityItem::DEFAULT_ANIMATION_FPS),
|
||||||
|
_animationSettings(""),
|
||||||
_glowLevel(0.0f),
|
_glowLevel(0.0f),
|
||||||
_localRenderAlpha(1.0f),
|
_localRenderAlpha(1.0f),
|
||||||
_isSpotlight(false),
|
_isSpotlight(false),
|
||||||
|
@ -76,6 +78,8 @@ EntityItemProperties::EntityItemProperties() :
|
||||||
_animationIsPlayingChanged(false),
|
_animationIsPlayingChanged(false),
|
||||||
_animationFrameIndexChanged(false),
|
_animationFrameIndexChanged(false),
|
||||||
_animationFPSChanged(false),
|
_animationFPSChanged(false),
|
||||||
|
_animationSettingsChanged(false),
|
||||||
|
|
||||||
_glowLevelChanged(false),
|
_glowLevelChanged(false),
|
||||||
_localRenderAlphaChanged(false),
|
_localRenderAlphaChanged(false),
|
||||||
_isSpotlightChanged(false),
|
_isSpotlightChanged(false),
|
||||||
|
@ -117,6 +121,58 @@ void EntityItemProperties::setSittingPoints(const QVector<SittingPoint>& sitting
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityItemProperties::setAnimationSettings(const QString& value) {
|
||||||
|
// the animations setting is a JSON string that may contain various animation settings.
|
||||||
|
// if it includes fps, frameIndex, or running, those values will be parsed out and
|
||||||
|
// will over ride the regular animation settings
|
||||||
|
|
||||||
|
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
|
||||||
|
QJsonObject settingsAsJsonObject = settingsAsJson.object();
|
||||||
|
QVariantMap settingsMap = settingsAsJsonObject.toVariantMap();
|
||||||
|
if (settingsMap.contains("fps")) {
|
||||||
|
float fps = settingsMap["fps"].toFloat();
|
||||||
|
setAnimationFPS(fps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("frameIndex")) {
|
||||||
|
float frameIndex = settingsMap["frameIndex"].toFloat();
|
||||||
|
setAnimationFrameIndex(frameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("running")) {
|
||||||
|
bool running = settingsMap["running"].toBool();
|
||||||
|
setAnimationIsPlaying(running);
|
||||||
|
}
|
||||||
|
|
||||||
|
_animationSettings = value;
|
||||||
|
_animationSettingsChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EntityItemProperties::getAnimationSettings() const {
|
||||||
|
// the animations setting is a JSON string that may contain various animation settings.
|
||||||
|
// if it includes fps, frameIndex, or running, those values will be parsed out and
|
||||||
|
// will over ride the regular animation settings
|
||||||
|
QString value = _animationSettings;
|
||||||
|
|
||||||
|
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
|
||||||
|
QJsonObject settingsAsJsonObject = settingsAsJson.object();
|
||||||
|
QVariantMap settingsMap = settingsAsJsonObject.toVariantMap();
|
||||||
|
|
||||||
|
QVariant fpsValue(getAnimationFPS());
|
||||||
|
settingsMap["fps"] = fpsValue;
|
||||||
|
|
||||||
|
QVariant frameIndexValue(getAnimationFrameIndex());
|
||||||
|
settingsMap["frameIndex"] = frameIndexValue;
|
||||||
|
|
||||||
|
QVariant runningValue(getAnimationIsPlaying());
|
||||||
|
settingsMap["running"] = runningValue;
|
||||||
|
|
||||||
|
settingsAsJsonObject = QJsonObject::fromVariantMap(settingsMap);
|
||||||
|
QJsonDocument newDocument(settingsAsJsonObject);
|
||||||
|
QByteArray jsonByteArray = newDocument.toJson(QJsonDocument::Compact);
|
||||||
|
QString jsonByteString(jsonByteArray);
|
||||||
|
return jsonByteString;
|
||||||
|
}
|
||||||
|
|
||||||
void EntityItemProperties::debugDump() const {
|
void EntityItemProperties::debugDump() const {
|
||||||
qDebug() << "EntityItemProperties...";
|
qDebug() << "EntityItemProperties...";
|
||||||
|
@ -149,6 +205,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, animationIsPlaying);
|
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, animationIsPlaying);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex);
|
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, animationFPS);
|
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, animationFPS);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_ANIMATION_SETTINGS, animationSettings);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible);
|
CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_REGISTRATION_POINT, registrationPoint);
|
CHECK_PROPERTY_CHANGE(PROP_REGISTRATION_POINT, registrationPoint);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity);
|
||||||
|
@ -201,8 +258,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(modelURL);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(modelURL);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(animationURL);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(animationURL);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(animationIsPlaying);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(animationIsPlaying);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(animationFrameIndex);
|
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(animationFPS);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(animationFPS);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(animationFrameIndex);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(animationSettings,getAnimationSettings());
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(ignoreForCollisions);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(ignoreForCollisions);
|
||||||
|
@ -276,6 +334,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(animationIsPlaying, setAnimationIsPlaying);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(animationIsPlaying, setAnimationIsPlaying);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFPS, setAnimationFPS);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFPS, setAnimationFPS);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFrameIndex, setAnimationFrameIndex);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFrameIndex, setAnimationFrameIndex);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(animationSettings, setAnimationSettings);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(glowLevel, setGlowLevel);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(glowLevel, setGlowLevel);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(localRenderAlpha, setLocalRenderAlpha);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(localRenderAlpha, setLocalRenderAlpha);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(ignoreForCollisions, setIgnoreForCollisions);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(ignoreForCollisions, setIgnoreForCollisions);
|
||||||
|
@ -452,6 +511,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
APPEND_ENTITY_PROPERTY(PROP_CUTOFF, appendValue, properties.getCutoff());
|
APPEND_ENTITY_PROPERTY(PROP_CUTOFF, appendValue, properties.getCutoff());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, properties.getLocked());
|
APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, properties.getLocked());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, properties.getTextures());
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, properties.getTextures());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, appendValue, properties.getAnimationSettings());
|
||||||
}
|
}
|
||||||
if (propertyCount > 0) {
|
if (propertyCount > 0) {
|
||||||
int endOfEntityItemData = packetData->getUncompressedByteOffset();
|
int endOfEntityItemData = packetData->getUncompressedByteOffset();
|
||||||
|
@ -661,7 +721,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CUTOFF, float, setCutoff);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CUTOFF, float, setCutoff);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked);
|
||||||
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_TEXTURES, setTextures);
|
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_TEXTURES, setTextures);
|
||||||
|
READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, setAnimationSettings);
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,6 +775,7 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_animationIsPlayingChanged = true;
|
_animationIsPlayingChanged = true;
|
||||||
_animationFrameIndexChanged = true;
|
_animationFrameIndexChanged = true;
|
||||||
_animationFPSChanged = true;
|
_animationFPSChanged = true;
|
||||||
|
_animationSettingsChanged = true;
|
||||||
_glowLevelChanged = true;
|
_glowLevelChanged = true;
|
||||||
_localRenderAlphaChanged = true;
|
_localRenderAlphaChanged = true;
|
||||||
_isSpotlightChanged = true;
|
_isSpotlightChanged = true;
|
||||||
|
|
|
@ -80,8 +80,9 @@ enum EntityPropertyList {
|
||||||
|
|
||||||
// used by Model entities
|
// used by Model entities
|
||||||
PROP_TEXTURES,
|
PROP_TEXTURES,
|
||||||
|
PROP_ANIMATION_SETTINGS,
|
||||||
|
|
||||||
PROP_LAST_ITEM = PROP_CUTOFF
|
PROP_LAST_ITEM = PROP_ANIMATION_SETTINGS
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
|
||||||
|
@ -178,6 +179,8 @@ public:
|
||||||
float getAnimationFrameIndex() const { return _animationFrameIndex; }
|
float getAnimationFrameIndex() const { return _animationFrameIndex; }
|
||||||
bool getAnimationIsPlaying() const { return _animationIsPlaying; }
|
bool getAnimationIsPlaying() const { return _animationIsPlaying; }
|
||||||
float getAnimationFPS() const { return _animationFPS; }
|
float getAnimationFPS() const { return _animationFPS; }
|
||||||
|
QString getAnimationSettings() const;
|
||||||
|
|
||||||
float getGlowLevel() const { return _glowLevel; }
|
float getGlowLevel() const { return _glowLevel; }
|
||||||
float getLocalRenderAlpha() const { return _localRenderAlpha; }
|
float getLocalRenderAlpha() const { return _localRenderAlpha; }
|
||||||
const QString& getScript() const { return _script; }
|
const QString& getScript() const { return _script; }
|
||||||
|
@ -189,6 +192,8 @@ public:
|
||||||
void setAnimationFrameIndex(float value) { _animationFrameIndex = value; _animationFrameIndexChanged = true; }
|
void setAnimationFrameIndex(float value) { _animationFrameIndex = value; _animationFrameIndexChanged = true; }
|
||||||
void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; _animationIsPlayingChanged = true; }
|
void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; _animationIsPlayingChanged = true; }
|
||||||
void setAnimationFPS(float value) { _animationFPS = value; _animationFPSChanged = true; }
|
void setAnimationFPS(float value) { _animationFPS = value; _animationFPSChanged = true; }
|
||||||
|
void setAnimationSettings(const QString& value);
|
||||||
|
|
||||||
void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; }
|
void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; }
|
||||||
void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; }
|
void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; }
|
||||||
void setScript(const QString& value) { _script = value; _scriptChanged = true; }
|
void setScript(const QString& value) { _script = value; _scriptChanged = true; }
|
||||||
|
@ -342,6 +347,7 @@ private:
|
||||||
bool _animationIsPlaying;
|
bool _animationIsPlaying;
|
||||||
float _animationFrameIndex;
|
float _animationFrameIndex;
|
||||||
float _animationFPS;
|
float _animationFPS;
|
||||||
|
QString _animationSettings;
|
||||||
float _glowLevel;
|
float _glowLevel;
|
||||||
float _localRenderAlpha;
|
float _localRenderAlpha;
|
||||||
bool _isSpotlight;
|
bool _isSpotlight;
|
||||||
|
@ -352,6 +358,7 @@ private:
|
||||||
bool _animationIsPlayingChanged;
|
bool _animationIsPlayingChanged;
|
||||||
bool _animationFrameIndexChanged;
|
bool _animationFrameIndexChanged;
|
||||||
bool _animationFPSChanged;
|
bool _animationFPSChanged;
|
||||||
|
bool _animationSettingsChanged;
|
||||||
bool _glowLevelChanged;
|
bool _glowLevelChanged;
|
||||||
bool _localRenderAlphaChanged;
|
bool _localRenderAlphaChanged;
|
||||||
bool _isSpotlightChanged;
|
bool _isSpotlightChanged;
|
||||||
|
|
|
@ -40,6 +40,18 @@
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define READ_ENTITY_PROPERTY_SETTER(P,T,M) \
|
||||||
|
if (propertyFlags.getHasProperty(P)) { \
|
||||||
|
T fromBuffer; \
|
||||||
|
memcpy(&fromBuffer, dataAt, sizeof(fromBuffer)); \
|
||||||
|
dataAt += sizeof(fromBuffer); \
|
||||||
|
bytesRead += sizeof(fromBuffer); \
|
||||||
|
if (overwriteLocalData) { \
|
||||||
|
M(fromBuffer); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define READ_ENTITY_PROPERTY_QUAT(P,M) \
|
#define READ_ENTITY_PROPERTY_QUAT(P,M) \
|
||||||
if (propertyFlags.getHasProperty(P)) { \
|
if (propertyFlags.getHasProperty(P)) { \
|
||||||
glm::quat fromBuffer; \
|
glm::quat fromBuffer; \
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QtCore/QJsonDocument>
|
||||||
|
|
||||||
#include <ByteCountCoding.h>
|
#include <ByteCountCoding.h>
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
|
@ -33,7 +35,6 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI
|
||||||
{
|
{
|
||||||
_type = EntityTypes::Model;
|
_type = EntityTypes::Model;
|
||||||
setProperties(properties, true);
|
setProperties(properties, true);
|
||||||
_animationFrameIndex = 0.0f;
|
|
||||||
_lastAnimated = usecTimestampNow();
|
_lastAnimated = usecTimestampNow();
|
||||||
_jointMappingCompleted = false;
|
_jointMappingCompleted = false;
|
||||||
_color[0] = _color[1] = _color[2] = 0;
|
_color[0] = _color[1] = _color[2] = 0;
|
||||||
|
@ -50,6 +51,7 @@ EntityItemProperties ModelEntityItem::getProperties() const {
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFPS, getAnimationFPS);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFPS, getAnimationFPS);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(glowLevel, getGlowLevel);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(glowLevel, getGlowLevel);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationSettings, getAnimationSettings);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +66,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties, bool
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFrameIndex, setAnimationFrameIndex);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFrameIndex, setAnimationFrameIndex);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFPS, setAnimationFPS);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFPS, setAnimationFPS);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationSettings, setAnimationSettings);
|
||||||
|
|
||||||
if (somethingChanged) {
|
if (somethingChanged) {
|
||||||
bool wantDebug = false;
|
bool wantDebug = false;
|
||||||
|
@ -100,10 +103,29 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
||||||
READ_ENTITY_PROPERTY_COLOR(PROP_COLOR, _color);
|
READ_ENTITY_PROPERTY_COLOR(PROP_COLOR, _color);
|
||||||
READ_ENTITY_PROPERTY_STRING(PROP_MODEL_URL, setModelURL);
|
READ_ENTITY_PROPERTY_STRING(PROP_MODEL_URL, setModelURL);
|
||||||
READ_ENTITY_PROPERTY_STRING(PROP_ANIMATION_URL, setAnimationURL);
|
READ_ENTITY_PROPERTY_STRING(PROP_ANIMATION_URL, setAnimationURL);
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationFPS);
|
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationFrameIndex);
|
// Because we're using AnimationLoop which will reset the frame index if you change it's running state
|
||||||
READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationIsPlaying);
|
// we want to read these values in the order they appear in the buffer, but call our setters in an
|
||||||
|
// order that allows AnimationLoop to preserve the correct frame rate.
|
||||||
|
float animationFPS = getAnimationFPS();
|
||||||
|
float animationFrameIndex = getAnimationFrameIndex();
|
||||||
|
bool animationIsPlaying = getAnimationIsPlaying();
|
||||||
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, animationFPS);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, animationFrameIndex);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, animationIsPlaying);
|
||||||
|
|
||||||
|
if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) {
|
||||||
|
setAnimationIsPlaying(animationIsPlaying);
|
||||||
|
}
|
||||||
|
if (propertyFlags.getHasProperty(PROP_ANIMATION_FPS)) {
|
||||||
|
setAnimationFPS(animationFPS);
|
||||||
|
}
|
||||||
|
if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) {
|
||||||
|
setAnimationFrameIndex(animationFrameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
READ_ENTITY_PROPERTY_STRING(PROP_TEXTURES, setTextures);
|
READ_ENTITY_PROPERTY_STRING(PROP_TEXTURES, setTextures);
|
||||||
|
READ_ENTITY_PROPERTY_STRING(PROP_ANIMATION_SETTINGS, setAnimationSettings);
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
@ -199,19 +221,25 @@ int ModelEntityItem::oldVersionReadEntityDataFromBuffer(const unsigned char* dat
|
||||||
bytesRead += animationURLLength;
|
bytesRead += animationURLLength;
|
||||||
|
|
||||||
// animationIsPlaying
|
// animationIsPlaying
|
||||||
memcpy(&_animationIsPlaying, dataAt, sizeof(_animationIsPlaying));
|
bool animationIsPlaying;
|
||||||
dataAt += sizeof(_animationIsPlaying);
|
memcpy(&animationIsPlaying, dataAt, sizeof(animationIsPlaying));
|
||||||
bytesRead += sizeof(_animationIsPlaying);
|
dataAt += sizeof(animationIsPlaying);
|
||||||
|
bytesRead += sizeof(animationIsPlaying);
|
||||||
|
setAnimationIsPlaying(animationIsPlaying);
|
||||||
|
|
||||||
// animationFrameIndex
|
// animationFrameIndex
|
||||||
memcpy(&_animationFrameIndex, dataAt, sizeof(_animationFrameIndex));
|
float animationFrameIndex;
|
||||||
dataAt += sizeof(_animationFrameIndex);
|
memcpy(&animationFrameIndex, dataAt, sizeof(animationFrameIndex));
|
||||||
bytesRead += sizeof(_animationFrameIndex);
|
dataAt += sizeof(animationFrameIndex);
|
||||||
|
bytesRead += sizeof(animationFrameIndex);
|
||||||
|
setAnimationFrameIndex(animationFrameIndex);
|
||||||
|
|
||||||
// animationFPS
|
// animationFPS
|
||||||
memcpy(&_animationFPS, dataAt, sizeof(_animationFPS));
|
float animationFPS;
|
||||||
dataAt += sizeof(_animationFPS);
|
memcpy(&animationFPS, dataAt, sizeof(animationFPS));
|
||||||
bytesRead += sizeof(_animationFPS);
|
dataAt += sizeof(animationFPS);
|
||||||
|
bytesRead += sizeof(animationFPS);
|
||||||
|
setAnimationFPS(animationFPS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
|
@ -227,6 +255,7 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams&
|
||||||
requestedProperties += PROP_ANIMATION_FPS;
|
requestedProperties += PROP_ANIMATION_FPS;
|
||||||
requestedProperties += PROP_ANIMATION_FRAME_INDEX;
|
requestedProperties += PROP_ANIMATION_FRAME_INDEX;
|
||||||
requestedProperties += PROP_ANIMATION_PLAYING;
|
requestedProperties += PROP_ANIMATION_PLAYING;
|
||||||
|
requestedProperties += PROP_ANIMATION_SETTINGS;
|
||||||
requestedProperties += PROP_TEXTURES;
|
requestedProperties += PROP_TEXTURES;
|
||||||
|
|
||||||
return requestedProperties;
|
return requestedProperties;
|
||||||
|
@ -249,6 +278,7 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, appendValue, getAnimationFrameIndex());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, appendValue, getAnimationFrameIndex());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, appendValue, getAnimationIsPlaying());
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, appendValue, getAnimationIsPlaying());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, getTextures());
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, getTextures());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, appendValue, getAnimationSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,7 +344,7 @@ QVector<glm::quat> ModelEntityItem::getAnimationFrame() {
|
||||||
int frameCount = frames.size();
|
int frameCount = frames.size();
|
||||||
|
|
||||||
if (frameCount > 0) {
|
if (frameCount > 0) {
|
||||||
int animationFrameIndex = (int)(glm::floor(_animationFrameIndex)) % frameCount;
|
int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount;
|
||||||
|
|
||||||
if (animationFrameIndex < 0 || animationFrameIndex > frameCount) {
|
if (animationFrameIndex < 0 || animationFrameIndex > frameCount) {
|
||||||
animationFrameIndex = 0;
|
animationFrameIndex = 0;
|
||||||
|
@ -363,7 +393,7 @@ void ModelEntityItem::update(const quint64& updateTime) {
|
||||||
if (getAnimationIsPlaying()) {
|
if (getAnimationIsPlaying()) {
|
||||||
float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND;
|
float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND;
|
||||||
_lastAnimated = now;
|
_lastAnimated = now;
|
||||||
_animationFrameIndex += deltaTime * _animationFPS;
|
_animationLoop.simulate(deltaTime);
|
||||||
} else {
|
} else {
|
||||||
_lastAnimated = now;
|
_lastAnimated = now;
|
||||||
}
|
}
|
||||||
|
@ -377,3 +407,94 @@ void ModelEntityItem::debugDump() const {
|
||||||
qDebug() << " model URL:" << getModelURL();
|
qDebug() << " model URL:" << getModelURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelEntityItem::setAnimationSettings(const QString& value) {
|
||||||
|
// the animations setting is a JSON string that may contain various animation settings.
|
||||||
|
// if it includes fps, frameIndex, or running, those values will be parsed out and
|
||||||
|
// will over ride the regular animation settings
|
||||||
|
|
||||||
|
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
|
||||||
|
QJsonObject settingsAsJsonObject = settingsAsJson.object();
|
||||||
|
QVariantMap settingsMap = settingsAsJsonObject.toVariantMap();
|
||||||
|
if (settingsMap.contains("fps")) {
|
||||||
|
float fps = settingsMap["fps"].toFloat();
|
||||||
|
setAnimationFPS(fps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("frameIndex")) {
|
||||||
|
float frameIndex = settingsMap["frameIndex"].toFloat();
|
||||||
|
setAnimationFrameIndex(frameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("running")) {
|
||||||
|
bool running = settingsMap["running"].toBool();
|
||||||
|
setAnimationIsPlaying(running);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("firstFrame")) {
|
||||||
|
float firstFrame = settingsMap["firstFrame"].toFloat();
|
||||||
|
setAnimationFirstFrame(firstFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("lastFrame")) {
|
||||||
|
float lastFrame = settingsMap["lastFrame"].toFloat();
|
||||||
|
setAnimationLastFrame(lastFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("loop")) {
|
||||||
|
bool loop = settingsMap["loop"].toBool();
|
||||||
|
setAnimationLoop(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("hold")) {
|
||||||
|
bool hold = settingsMap["hold"].toBool();
|
||||||
|
setAnimationHold(hold);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsMap.contains("startAutomatically")) {
|
||||||
|
bool startAutomatically = settingsMap["startAutomatically"].toBool();
|
||||||
|
setAnimationStartAutomatically(startAutomatically);
|
||||||
|
}
|
||||||
|
|
||||||
|
_animationSettings = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ModelEntityItem::getAnimationSettings() const {
|
||||||
|
// the animations setting is a JSON string that may contain various animation settings.
|
||||||
|
// if it includes fps, frameIndex, or running, those values will be parsed out and
|
||||||
|
// will over ride the regular animation settings
|
||||||
|
QString value = _animationSettings;
|
||||||
|
|
||||||
|
QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8());
|
||||||
|
QJsonObject settingsAsJsonObject = settingsAsJson.object();
|
||||||
|
QVariantMap settingsMap = settingsAsJsonObject.toVariantMap();
|
||||||
|
|
||||||
|
QVariant fpsValue(getAnimationFPS());
|
||||||
|
settingsMap["fps"] = fpsValue;
|
||||||
|
|
||||||
|
QVariant frameIndexValue(getAnimationFrameIndex());
|
||||||
|
settingsMap["frameIndex"] = frameIndexValue;
|
||||||
|
|
||||||
|
QVariant runningValue(getAnimationIsPlaying());
|
||||||
|
settingsMap["running"] = runningValue;
|
||||||
|
|
||||||
|
QVariant firstFrameValue(getAnimationFirstFrame());
|
||||||
|
settingsMap["firstFrame"] = firstFrameValue;
|
||||||
|
|
||||||
|
QVariant lastFrameValue(getAnimationLastFrame());
|
||||||
|
settingsMap["lastFrame"] = lastFrameValue;
|
||||||
|
|
||||||
|
QVariant loopValue(getAnimationLoop());
|
||||||
|
settingsMap["loop"] = loopValue;
|
||||||
|
|
||||||
|
QVariant holdValue(getAnimationHold());
|
||||||
|
settingsMap["hold"] = holdValue;
|
||||||
|
|
||||||
|
QVariant startAutomaticallyValue(getAnimationStartAutomatically());
|
||||||
|
settingsMap["startAutomatically"] = startAutomaticallyValue;
|
||||||
|
|
||||||
|
settingsAsJsonObject = QJsonObject::fromVariantMap(settingsMap);
|
||||||
|
QJsonDocument newDocument(settingsAsJsonObject);
|
||||||
|
QByteArray jsonByteArray = newDocument.toJson(QJsonDocument::Compact);
|
||||||
|
QString jsonByteString(jsonByteArray);
|
||||||
|
return jsonByteString;
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#ifndef hifi_ModelEntityItem_h
|
#ifndef hifi_ModelEntityItem_h
|
||||||
#define hifi_ModelEntityItem_h
|
#define hifi_ModelEntityItem_h
|
||||||
|
|
||||||
|
#include <AnimationLoop.h>
|
||||||
|
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
|
|
||||||
class ModelEntityItem : public EntityItem {
|
class ModelEntityItem : public EntityItem {
|
||||||
|
@ -73,21 +75,38 @@ public:
|
||||||
void setModelURL(const QString& url) { _modelURL = url; }
|
void setModelURL(const QString& url) { _modelURL = url; }
|
||||||
void setAnimationURL(const QString& url) { _animationURL = url; }
|
void setAnimationURL(const QString& url) { _animationURL = url; }
|
||||||
static const float DEFAULT_ANIMATION_FRAME_INDEX;
|
static const float DEFAULT_ANIMATION_FRAME_INDEX;
|
||||||
void setAnimationFrameIndex(float value) { _animationFrameIndex = value; }
|
void setAnimationFrameIndex(float value) { _animationLoop.setFrameIndex(value); }
|
||||||
|
void setAnimationSettings(const QString& value);
|
||||||
|
|
||||||
static const bool DEFAULT_ANIMATION_IS_PLAYING;
|
static const bool DEFAULT_ANIMATION_IS_PLAYING;
|
||||||
void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; }
|
void setAnimationIsPlaying(bool value) { _animationLoop.setRunning(value); }
|
||||||
|
|
||||||
static const float DEFAULT_ANIMATION_FPS;
|
static const float DEFAULT_ANIMATION_FPS;
|
||||||
void setAnimationFPS(float value) { _animationFPS = value; }
|
void setAnimationFPS(float value) { _animationLoop.setFPS(value); }
|
||||||
|
|
||||||
|
void setAnimationLoop(bool loop) { _animationLoop.setLoop(loop); }
|
||||||
|
bool getAnimationLoop() const { return _animationLoop.getLoop(); }
|
||||||
|
|
||||||
|
void setAnimationHold(bool hold) { _animationLoop.setHold(hold); }
|
||||||
|
bool getAnimationHold() const { return _animationLoop.getHold(); }
|
||||||
|
|
||||||
|
void setAnimationStartAutomatically(bool startAutomatically) { _animationLoop.setStartAutomatically(startAutomatically); }
|
||||||
|
bool getAnimationStartAutomatically() const { return _animationLoop.getStartAutomatically(); }
|
||||||
|
|
||||||
|
void setAnimationFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); }
|
||||||
|
float getAnimationFirstFrame() const { return _animationLoop.getFirstFrame(); }
|
||||||
|
|
||||||
|
void setAnimationLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); }
|
||||||
|
float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); }
|
||||||
|
|
||||||
void mapJoints(const QStringList& modelJointNames);
|
void mapJoints(const QStringList& modelJointNames);
|
||||||
QVector<glm::quat> getAnimationFrame();
|
QVector<glm::quat> getAnimationFrame();
|
||||||
bool jointsMapped() const { return _jointMappingCompleted; }
|
bool jointsMapped() const { return _jointMappingCompleted; }
|
||||||
|
|
||||||
bool getAnimationIsPlaying() const { return _animationIsPlaying; }
|
bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); }
|
||||||
float getAnimationFrameIndex() const { return _animationFrameIndex; }
|
float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); }
|
||||||
float getAnimationFPS() const { return _animationFPS; }
|
float getAnimationFPS() const { return _animationLoop.getFPS(); }
|
||||||
|
QString getAnimationSettings() const;
|
||||||
|
|
||||||
static const QString DEFAULT_TEXTURES;
|
static const QString DEFAULT_TEXTURES;
|
||||||
const QString& getTextures() const { return _textures; }
|
const QString& getTextures() const { return _textures; }
|
||||||
|
@ -106,9 +125,8 @@ protected:
|
||||||
|
|
||||||
quint64 _lastAnimated;
|
quint64 _lastAnimated;
|
||||||
QString _animationURL;
|
QString _animationURL;
|
||||||
float _animationFrameIndex; // we keep this as a float and round to int only when we need the exact index
|
AnimationLoop _animationLoop;
|
||||||
bool _animationIsPlaying;
|
QString _animationSettings;
|
||||||
float _animationFPS;
|
|
||||||
QString _textures;
|
QString _textures;
|
||||||
|
|
||||||
// used on client side
|
// used on client side
|
||||||
|
|
|
@ -75,7 +75,7 @@ PacketVersion versionForPacketType(PacketType type) {
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeEntityAddOrEdit:
|
case PacketTypeEntityAddOrEdit:
|
||||||
case PacketTypeEntityData:
|
case PacketTypeEntityData:
|
||||||
return VERSION_ENTITIES_SUPPORT_DIMENSIONS;
|
return VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS;
|
||||||
case PacketTypeEntityErase:
|
case PacketTypeEntityErase:
|
||||||
return 2;
|
return 2;
|
||||||
case PacketTypeAudioStreamStats:
|
case PacketTypeAudioStreamStats:
|
||||||
|
|
|
@ -124,6 +124,7 @@ const PacketVersion VERSION_ROOT_ELEMENT_HAS_DATA = 2;
|
||||||
const PacketVersion VERSION_ENTITIES_SUPPORT_SPLIT_MTU = 3;
|
const PacketVersion VERSION_ENTITIES_SUPPORT_SPLIT_MTU = 3;
|
||||||
const PacketVersion VERSION_ENTITIES_HAS_FILE_BREAKS = VERSION_ENTITIES_SUPPORT_SPLIT_MTU;
|
const PacketVersion VERSION_ENTITIES_HAS_FILE_BREAKS = VERSION_ENTITIES_SUPPORT_SPLIT_MTU;
|
||||||
const PacketVersion VERSION_ENTITIES_SUPPORT_DIMENSIONS = 4;
|
const PacketVersion VERSION_ENTITIES_SUPPORT_DIMENSIONS = 4;
|
||||||
|
const PacketVersion VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS = 5;
|
||||||
const PacketVersion VERSION_VOXELS_HAS_FILE_BREAKS = 1;
|
const PacketVersion VERSION_VOXELS_HAS_FILE_BREAKS = 1;
|
||||||
|
|
||||||
#endif // hifi_PacketHeaders_h
|
#endif // hifi_PacketHeaders_h
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <GeometryUtil.h>
|
#include <GeometryUtil.h>
|
||||||
#include <OctalCode.h>
|
#include <OctalCode.h>
|
||||||
|
#include <LogHandler.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <Shape.h>
|
#include <Shape.h>
|
||||||
|
@ -71,6 +72,10 @@ void Octree::recurseTreeWithPostOperation(RecurseOctreeOperation operation, void
|
||||||
void Octree::recurseElementWithOperation(OctreeElement* element, RecurseOctreeOperation operation, void* extraData,
|
void Octree::recurseElementWithOperation(OctreeElement* element, RecurseOctreeOperation operation, void* extraData,
|
||||||
int recursionCount) {
|
int recursionCount) {
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
|
static QString repeatedMessage
|
||||||
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
|
"Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +94,11 @@ void Octree::recurseElementWithOperation(OctreeElement* element, RecurseOctreeOp
|
||||||
void Octree::recurseElementWithPostOperation(OctreeElement* element, RecurseOctreeOperation operation, void* extraData,
|
void Octree::recurseElementWithPostOperation(OctreeElement* element, RecurseOctreeOperation operation, void* extraData,
|
||||||
int recursionCount) {
|
int recursionCount) {
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!\n";
|
static QString repeatedMessage
|
||||||
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
|
"Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
|
qDebug() << "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +124,10 @@ void Octree::recurseElementWithOperationDistanceSorted(OctreeElement* element, R
|
||||||
const glm::vec3& point, void* extraData, int recursionCount) {
|
const glm::vec3& point, void* extraData, int recursionCount) {
|
||||||
|
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
|
static QString repeatedMessage
|
||||||
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
|
"Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
qDebug() << "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
qDebug() << "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +165,11 @@ void Octree::recurseTreeWithOperator(RecurseOctreeOperator* operatorObject) {
|
||||||
|
|
||||||
bool Octree::recurseElementWithOperator(OctreeElement* element, RecurseOctreeOperator* operatorObject, int recursionCount) {
|
bool Octree::recurseElementWithOperator(OctreeElement* element, RecurseOctreeOperator* operatorObject, int recursionCount) {
|
||||||
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
if (recursionCount > DANGEROUSLY_DEEP_RECURSION) {
|
||||||
qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
static QString repeatedMessage
|
||||||
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
|
"Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!");
|
||||||
|
|
||||||
|
qDebug() << "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include <LogHandler.h>
|
||||||
#include <PacketHeaders.h>
|
#include <PacketHeaders.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
@ -854,8 +855,12 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet,
|
||||||
const int MAX_RESONABLE_FLIGHT_TIME = 200 * USECS_PER_SECOND; // 200 seconds is more than enough time for a packet to arrive
|
const int MAX_RESONABLE_FLIGHT_TIME = 200 * USECS_PER_SECOND; // 200 seconds is more than enough time for a packet to arrive
|
||||||
const int MIN_RESONABLE_FLIGHT_TIME = 0;
|
const int MIN_RESONABLE_FLIGHT_TIME = 0;
|
||||||
if (flightTime > MAX_RESONABLE_FLIGHT_TIME || flightTime < MIN_RESONABLE_FLIGHT_TIME) {
|
if (flightTime > MAX_RESONABLE_FLIGHT_TIME || flightTime < MIN_RESONABLE_FLIGHT_TIME) {
|
||||||
|
static QString repeatedMessage
|
||||||
|
= LogHandler::getInstance().addRepeatedMessageRegex(
|
||||||
|
"ignoring unreasonable packet... flightTime: -?\\d+ nodeClockSkewUsec: -?\\d+ usecs");
|
||||||
|
|
||||||
qDebug() << "ignoring unreasonable packet... flightTime:" << flightTime
|
qDebug() << "ignoring unreasonable packet... flightTime:" << flightTime
|
||||||
<< " nodeClockSkewUsec:" << nodeClockSkewUsec << " usecs";;
|
<< "nodeClockSkewUsec:" << nodeClockSkewUsec << "usecs";;
|
||||||
return; // ignore any packets that are unreasonable
|
return; // ignore any packets that are unreasonable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,15 @@ struct xColor {
|
||||||
unsigned char blue;
|
unsigned char blue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline QDebug& operator<<(QDebug& dbg, const xColor& c) {
|
||||||
|
dbg.nospace() << "{type='xColor'"
|
||||||
|
", red=" << c.red <<
|
||||||
|
", green=" << c.green <<
|
||||||
|
", blue=" << c.blue <<
|
||||||
|
"}";
|
||||||
|
return dbg;
|
||||||
|
}
|
||||||
|
|
||||||
static const float ZERO = 0.0f;
|
static const float ZERO = 0.0f;
|
||||||
static const float ONE = 1.0f;
|
static const float ONE = 1.0f;
|
||||||
static const float ONE_HALF = 0.5f;
|
static const float ONE_HALF = 0.5f;
|
||||||
|
|
Loading…
Reference in a new issue