More work on animation loading.

This commit is contained in:
Andrzej Kapolka 2014-04-16 20:39:55 -07:00
parent 8cbad1bf54
commit 0f69bbe23f
8 changed files with 61 additions and 20 deletions

View file

@ -11,8 +11,10 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop>
#include <QtCore/QStandardPaths>
#include <QtCore/QTimer>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkDiskCache>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
@ -20,6 +22,7 @@
#include <AvatarData.h>
#include <NodeList.h>
#include <PacketHeaders.h>
#include <ResourceCache.h>
#include <UUID.h>
#include <VoxelConstants.h>
#include <ParticlesScriptingInterface.h>
@ -152,8 +155,13 @@ void Agent::run() {
scriptURLString = scriptURLString.arg(NodeList::getInstance()->getDomainHandler().getIP().toString(),
uuidStringWithoutCurlyBraces(_uuid));
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
QNetworkReply *reply = networkManager->get(QNetworkRequest(QUrl(scriptURLString)));
QNetworkDiskCache* cache = new QNetworkDiskCache(networkManager);
cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "agentCache");
networkManager->setCache(cache);
qDebug() << "Downloading script at" << scriptURLString;
@ -162,8 +170,9 @@ void Agent::run() {
loop.exec();
// let the AvatarData class use our QNetworkAcessManager
// let the AvatarData and ResourceCache classes use our QNetworkAccessManager
AvatarData::setNetworkAccessManager(networkManager);
ResourceCache::setNetworkAccessManager(networkManager);
QString scriptContents(reply->readAll());

View file

@ -22,8 +22,6 @@ for (var i = 0; i < jointList.length; i++) {
}
print("# Joint list end");
var foo = AnimationCache.getAnimation("http://www.fungibleinsight.com/faces/hip_hop_dancing_2.fbx");
Script.update.connect(function(deltaTime) {
cumulativeTime += deltaTime;
MyAvatar.setJointData("joint_R_hip", Quat.fromPitchYawRollDegrees(0.0, 0.0, AMPLITUDE * Math.sin(cumulativeTime * FREQUENCY)));
@ -32,18 +30,6 @@ Script.update.connect(function(deltaTime) {
AMPLITUDE * (1.0 + Math.sin(cumulativeTime * FREQUENCY))));
MyAvatar.setJointData("joint_L_knee", Quat.fromPitchYawRollDegrees(0.0, 0.0,
AMPLITUDE * (1.0 - Math.sin(cumulativeTime * FREQUENCY))));
if (foo.jointNames.length > 0) {
print(foo.jointNames);
print(foo.frames.length);
if (foo.frames.length > 0) {
print(foo.frames[0].rotations.length);
if (foo.frames[0].rotations.length > 0) {
var rot = foo.frames[0].rotations[0];
print(rot.x + " " + rot.y + " " + rot.z + " " + rot.w);
}
}
}
});
Script.scriptEnding.connect(function() {

35
examples/dancing_bot.js Normal file
View file

@ -0,0 +1,35 @@
//
// dancing_bot.js
// examples
//
// Created by Andrzej Kapolka on 4/16/14.
// Copyright 2014 High Fidelity, Inc.
//
// This is an example script that demonstrates an NPC avatar running an FBX animation loop.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var animation = AnimationCache.getAnimation("http://www.fungibleinsight.com/faces/hip_hop_dancing_2.fbx");
Avatar.skeletonModelURL = "http://www.fungibleinsight.com/faces/vincent.fst";
Agent.isAvatar = true;
var jointMapping;
Script.update.connect(function(deltaTime) {
if (!jointMapping) {
var avatarJointNames = Avatar.jointNames;
var animationJointNames = animation.jointNames;
if (avatarJointNames === 0 || animationJointNames.length === 0) {
return;
}
print(avatarJointNames);
print(animationJointNames);
jointMapping = { };
}
});

View file

@ -99,6 +99,8 @@ class AvatarData : public QObject {
Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript)
Q_PROPERTY(QString billboardURL READ getBillboardURL WRITE setBillboardFromURL)
Q_PROPERTY(QStringList jointNames READ getJointNames)
Q_PROPERTY(QUuid sessionUUID READ getSessionUUID);
public:
AvatarData();

View file

@ -508,8 +508,7 @@ glm::vec3 parseVec3(const QString& string) {
QString processID(const QString& id) {
// Blender (at least) prepends a type to the ID, so strip it out
int index = id.indexOf("::");
return (index == -1) ? id : id.mid(index + 2);
return id.mid(id.lastIndexOf(':') + 1);
}
QString getID(const QVariantList& properties, int index = 0) {
@ -1014,7 +1013,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
QString name;
if (object.properties.size() == 3) {
name = object.properties.at(1).toString();
name = name.left(name.indexOf(QChar('\0')));
name = processID(name.left(name.indexOf(QChar('\0'))));
} else {
name = getID(object.properties);

View file

@ -17,8 +17,14 @@
static int animationPointerMetaTypeId = qRegisterMetaType<AnimationPointer>();
AnimationCache::AnimationCache(QObject* parent) :
ResourceCache(parent) {
}
AnimationPointer AnimationCache::getAnimation(const QUrl& url) {
if (QThread::currentThread() != thread()) {
qDebug() << "blocking call!";
AnimationPointer result;
QMetaObject::invokeMethod(this, "getAnimation", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(AnimationPointer, result), Q_ARG(const QUrl&, url));

View file

@ -30,6 +30,8 @@ class AnimationCache : public ResourceCache {
public:
AnimationCache(QObject* parent = NULL);
Q_INVOKABLE AnimationPointer getAnimation(const QString& url) { return getAnimation(QUrl(url)); }
Q_INVOKABLE AnimationPointer getAnimation(const QUrl& url);

View file

@ -64,7 +64,8 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
_fileNameString(fileNameString),
_quatLibrary(),
_vec3Library(),
_uuidLibrary()
_uuidLibrary(),
_animationCache(this)
{
}
@ -88,7 +89,8 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL,
_fileNameString(),
_quatLibrary(),
_vec3Library(),
_uuidLibrary()
_uuidLibrary(),
_animationCache(this)
{
QString scriptURLString = scriptURL.toString();
_fileNameString = scriptURLString;