add more properties to animated models

This commit is contained in:
ZappoMan 2014-05-12 13:44:44 -07:00
parent e4d2f07586
commit 5309c5ad8b
4 changed files with 159 additions and 7 deletions

View file

@ -231,6 +231,7 @@ function checkControllerSide(whichSide) {
if (animationURLs[currentModelURL] !== "") {
properties.animationURL = animationURLs[currentModelURL];
properties.isAnimationPlaying = true;
}
debugPrint("modelRadius=" +modelRadius);

View file

@ -88,7 +88,9 @@ ModelItem::ModelItem(const ModelItemID& modelItemID, const ModelItemProperties&
// animation related
_animationURL = MODEL_DEFAULT_ANIMATION_URL;
_isAnimationPlaying = false;
_frameIndex = 0.0f;
_jointMappingCompleted = false;
_lastAnimated = now;
@ -119,6 +121,7 @@ void ModelItem::init(glm::vec3 position, float radius, rgbColor color, uint32_t
// animation related
_animationURL = MODEL_DEFAULT_ANIMATION_URL;
_isAnimationPlaying = false;
_frameIndex = 0.0f;
_jointMappingCompleted = false;
_lastAnimated = now;
@ -172,6 +175,16 @@ bool ModelItem::appendModelData(OctreePacketData* packetData) const {
}
}
// isAnimationPlaying
if (success) {
success = packetData->appendValue(getIsAnimationPlaying());
}
// frameIndex
if (success) {
success = packetData->appendValue(getFrameIndex());
}
return success;
}
@ -259,6 +272,17 @@ int ModelItem::readModelDataFromBuffer(const unsigned char* data, int bytesLeftT
bytesRead += animationURLLength;
qDebug() << "readModelDataFromBuffer()... animationURL=" << qPrintable(animationURLString);
// isAnimationPlaying
memcpy(&_isAnimationPlaying, dataAt, sizeof(_isAnimationPlaying));
dataAt += sizeof(_isAnimationPlaying);
bytesRead += sizeof(_isAnimationPlaying);
// frameIndex
memcpy(&_frameIndex, dataAt, sizeof(_frameIndex));
dataAt += sizeof(_frameIndex);
bytesRead += sizeof(_frameIndex);
} else {
qDebug() << "readModelDataFromBuffer()... this model didn't have animation details";
}
@ -395,9 +419,25 @@ ModelItem ModelItem::fromEditPacket(const unsigned char* data, int length, int&
newModelItem._animationURL = tempString;
dataAt += animationURLLength;
processedBytes += animationURLLength;
qDebug() << "fromEditPacket()... animationURL=" << qPrintable(tempString);
}
// isAnimationPlaying
if (isNewModelItem || ((packetContainsBits &
MODEL_PACKET_CONTAINS_ANIMATION_PLAYING) == MODEL_PACKET_CONTAINS_ANIMATION_PLAYING)) {
memcpy(&newModelItem._isAnimationPlaying, dataAt, sizeof(newModelItem._isAnimationPlaying));
dataAt += sizeof(newModelItem._isAnimationPlaying);
processedBytes += sizeof(newModelItem._isAnimationPlaying);
}
// frameIndex
if (isNewModelItem || ((packetContainsBits &
MODEL_PACKET_CONTAINS_ANIMATION_FRAME) == MODEL_PACKET_CONTAINS_ANIMATION_FRAME)) {
memcpy(&newModelItem._frameIndex, dataAt, sizeof(newModelItem._frameIndex));
dataAt += sizeof(newModelItem._frameIndex);
processedBytes += sizeof(newModelItem._frameIndex);
}
const bool wantDebugging = false;
@ -545,6 +585,30 @@ qDebug() << "encodeModelItemEditMessageDetails()... animationURL=" << qPrintable
}
// isAnimationPlaying
if (isNewModelItem || ((packetContainsBits &
MODEL_PACKET_CONTAINS_ANIMATION_PLAYING) == MODEL_PACKET_CONTAINS_ANIMATION_PLAYING)) {
bool isAnimationPlaying = properties.getIsAnimationPlaying();
memcpy(copyAt, &isAnimationPlaying, sizeof(isAnimationPlaying));
copyAt += sizeof(isAnimationPlaying);
sizeOut += sizeof(isAnimationPlaying);
qDebug() << "encodeModelItemEditMessageDetails()... isAnimationPlaying=" << isAnimationPlaying;
}
// frameIndex
if (isNewModelItem || ((packetContainsBits &
MODEL_PACKET_CONTAINS_ANIMATION_FRAME) == MODEL_PACKET_CONTAINS_ANIMATION_FRAME)) {
float frameIndex = properties.getFrameIndex();
memcpy(copyAt, &frameIndex, sizeof(frameIndex));
copyAt += sizeof(frameIndex);
sizeOut += sizeof(frameIndex);
qDebug() << "encodeModelItemEditMessageDetails()... frameIndex=" << frameIndex;
}
bool wantDebugging = false;
if (wantDebugging) {
@ -631,11 +695,16 @@ void ModelItem::mapJoints(const QStringList& modelJointNames) {
QVector<glm::quat> ModelItem::getAnimationFrame() {
QVector<glm::quat> frameData;
if (hasAnimation() && _jointMappingCompleted) {
quint64 now = usecTimestampNow();
float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND;
_lastAnimated = now;
const float FRAME_RATE = 10.0f;
_frameIndex += deltaTime * FRAME_RATE;
// only advance the frame index if we're playing
if (getIsAnimationPlaying()) {
quint64 now = usecTimestampNow();
float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND;
_lastAnimated = now;
const float FRAME_RATE = 10.0f;
_frameIndex += deltaTime * FRAME_RATE;
}
Animation* myAnimation = getAnimation(_animationURL);
QVector<FBXAnimationFrame> frames = myAnimation->getFrames();
int frameIndex = (int)std::floor(_frameIndex) % frames.size();
@ -678,6 +747,8 @@ ModelItemProperties::ModelItemProperties() :
_modelURL(""),
_modelRotation(MODEL_DEFAULT_MODEL_ROTATION),
_animationURL(""),
_isAnimationPlaying(false),
_frameIndex(0.0),
_id(UNKNOWN_MODEL_ID),
_idSet(false),
@ -690,6 +761,8 @@ ModelItemProperties::ModelItemProperties() :
_modelURLChanged(false),
_modelRotationChanged(false),
_animationURLChanged(false),
_isAnimationPlayingChanged(false),
_frameIndexChanged(false),
_defaultSettings(true)
{
}
@ -725,6 +798,13 @@ uint16_t ModelItemProperties::getChangedBits() const {
changedBits += MODEL_PACKET_CONTAINS_ANIMATION_URL;
}
if (_isAnimationPlayingChanged) {
changedBits += MODEL_PACKET_CONTAINS_ANIMATION_PLAYING;
}
if (_frameIndexChanged) {
changedBits += MODEL_PACKET_CONTAINS_ANIMATION_FRAME;
}
return changedBits;
}
@ -749,6 +829,8 @@ QScriptValue ModelItemProperties::copyToScriptValue(QScriptEngine* engine) const
properties.setProperty("modelRotation", modelRotation);
properties.setProperty("animationURL", _animationURL);
properties.setProperty("isAnimationPlaying", _isAnimationPlaying);
properties.setProperty("frameIndex", _frameIndex);
if (_idSet) {
properties.setProperty("id", _id);
@ -855,6 +937,26 @@ void ModelItemProperties::copyFromScriptValue(const QScriptValue &object) {
}
}
QScriptValue isAnimationPlaying = object.property("isAnimationPlaying");
if (isAnimationPlaying.isValid()) {
bool newIsAnimationPlaying;
newIsAnimationPlaying = isAnimationPlaying.toVariant().toBool();
if (_defaultSettings || newIsAnimationPlaying != _isAnimationPlaying) {
_isAnimationPlaying = newIsAnimationPlaying;
_isAnimationPlayingChanged = true;
}
}
QScriptValue frameIndex = object.property("frameIndex");
if (frameIndex.isValid()) {
float newFrameIndex;
newFrameIndex = frameIndex.toVariant().toFloat();
if (_defaultSettings || newFrameIndex != _frameIndex) {
_frameIndex = newFrameIndex;
_frameIndexChanged = true;
}
}
_lastEdited = usecTimestampNow();
}
@ -897,6 +999,20 @@ void ModelItemProperties::copyToModelItem(ModelItem& modelItem) const {
qDebug() << "ModelItemProperties::copyToModelItem()... modelItem.setAnimationURL(_animationURL)=" << _animationURL;
}
if (_isAnimationPlayingChanged) {
modelItem.setIsAnimationPlaying(_isAnimationPlaying);
somethingChanged = true;
qDebug() << "ModelItemProperties::copyToModelItem()... _isAnimationPlaying=" << _isAnimationPlaying;
}
if (_frameIndexChanged) {
modelItem.setFrameIndex(_frameIndex);
somethingChanged = true;
qDebug() << "ModelItemProperties::copyToModelItem()... _frameIndex=" << _frameIndex;
}
if (somethingChanged) {
bool wantDebug = false;
if (wantDebug) {
@ -917,6 +1033,8 @@ void ModelItemProperties::copyFromModelItem(const ModelItem& modelItem) {
_modelURL = modelItem.getModelURL();
_modelRotation = modelItem.getModelRotation();
_animationURL = modelItem.getAnimationURL();
_isAnimationPlaying = modelItem.getIsAnimationPlaying();
_frameIndex = modelItem.getFrameIndex();
_id = modelItem.getID();
_idSet = true;
@ -929,6 +1047,8 @@ void ModelItemProperties::copyFromModelItem(const ModelItem& modelItem) {
_modelURLChanged = false;
_modelRotationChanged = false;
_animationURLChanged = false;
_isAnimationPlayingChanged = false;
_frameIndexChanged = false;
_defaultSettings = false;
}

View file

@ -44,6 +44,8 @@ const uint16_t MODEL_PACKET_CONTAINS_SHOULDDIE = 8;
const uint16_t MODEL_PACKET_CONTAINS_MODEL_URL = 16;
const uint16_t MODEL_PACKET_CONTAINS_MODEL_ROTATION = 32;
const uint16_t MODEL_PACKET_CONTAINS_ANIMATION_URL = 64;
const uint16_t MODEL_PACKET_CONTAINS_ANIMATION_PLAYING = 128;
const uint16_t MODEL_PACKET_CONTAINS_ANIMATION_FRAME = 256;
const float MODEL_DEFAULT_RADIUS = 0.1f / TREE_SCALE;
const float MINIMUM_MODEL_ELEMENT_SIZE = (1.0f / 100000.0f) / TREE_SCALE; // smallest size container
@ -75,6 +77,8 @@ public:
const QString& getModelURL() const { return _modelURL; }
const glm::quat& getModelRotation() const { return _modelRotation; }
const QString& getAnimationURL() const { return _animationURL; }
float getFrameIndex() const { return _frameIndex; }
bool getIsAnimationPlaying() const { return _isAnimationPlaying; }
quint64 getLastEdited() const { return _lastEdited; }
uint16_t getChangedBits() const;
@ -89,6 +93,8 @@ public:
void setModelURL(const QString& url) { _modelURL = url; _modelURLChanged = true; }
void setModelRotation(const glm::quat& rotation) { _modelRotation = rotation; _modelRotationChanged = true; }
void setAnimationURL(const QString& url) { _animationURL = url; _animationURLChanged = true; }
void setFrameIndex(float value) { _frameIndex = value; _frameIndexChanged = true; }
void setIsAnimationPlaying(bool value) { _isAnimationPlaying = value; _isAnimationPlayingChanged = true; }
/// used by ModelScriptingInterface to return ModelItemProperties for unknown models
void setIsUnknownID() { _id = UNKNOWN_MODEL_ID; _idSet = true; }
@ -105,6 +111,8 @@ private:
QString _modelURL;
glm::quat _modelRotation;
QString _animationURL;
bool _isAnimationPlaying;
float _frameIndex;
uint32_t _id;
bool _idSet;
@ -118,6 +126,8 @@ private:
bool _modelURLChanged;
bool _modelRotationChanged;
bool _animationURLChanged;
bool _isAnimationPlayingChanged;
bool _frameIndexChanged;
bool _defaultSettings;
};
Q_DECLARE_METATYPE(ModelItemProperties);
@ -228,6 +238,8 @@ public:
void setModelURL(const QString& url) { _modelURL = url; }
void setModelRotation(const glm::quat& rotation) { _modelRotation = rotation; }
void setAnimationURL(const QString& url) { _animationURL = url; }
void setFrameIndex(float value) { _frameIndex = value; }
void setIsAnimationPlaying(bool value) { _isAnimationPlaying = value; }
void setProperties(const ModelItemProperties& properties);
@ -254,7 +266,10 @@ public:
void mapJoints(const QStringList& modelJointNames);
QVector<glm::quat> getAnimationFrame();
bool jointsMapped() const { return _jointMappingCompleted; };
bool jointsMapped() const { return _jointMappingCompleted; }
bool getIsAnimationPlaying() const { return _isAnimationPlaying; }
float getFrameIndex() const { return _frameIndex; }
protected:
glm::vec3 _position;
@ -277,6 +292,8 @@ protected:
QString _animationURL;
float _frameIndex; // we keep this as a float and round to int only when we need the exact index
bool _isAnimationPlaying;
bool _jointMappingCompleted;
QVector<int> _jointMapping;

View file

@ -59,6 +59,20 @@ public slots:
/// this function will not find any models in script engine contexts which don't have access to models
QVector<ModelItemID> findModels(const glm::vec3& center, float radius) const;
/*
/// pauses the model animation.
ModelItemID pauseModelAnimation(ModelItemID modelID);
/// plays the model animation.
ModelItemID playModelAnimation(ModelItemID modelID);
/// gets the current frame of the model animation.
float getModelAnimationFrame(ModelItemID modelID);
/// gets the current frame of the model animation.
void setModelAnimationFrame(ModelItemID modelID, float frame);
*/
signals:
void modelCollisionWithVoxel(const ModelItemID& modelID, const VoxelDetail& voxel, const CollisionInfo& collision);
void modelCollisionWithModel(const ModelItemID& idA, const ModelItemID& idB, const CollisionInfo& collision);