mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
whitespace corrections + warnings updated cmake plugin rework with focus on JS API integration example cleanup edit_filter scope separate-out edit_filter wantsScope stuff -plugin metadata split scriptengines out separately cleanup __url/__filename sets additional cleanup fix typo; consolidate ScriptInitializerMixin inits add more example API protoypes cleanup pass; fix entity_server / agent init fix whitespace remove technically unnessary plugin filtering +EDIT_FILTER_SCRIPT; cleanup reorder public/slot/private use std::count_if formatting better debug output; cleanup fix msvc compiler warning cleanup eradicate QtScript references from API Example updated header comments Updated KasenAPIExample
139 lines
4.6 KiB
C++
139 lines
4.6 KiB
C++
//
|
|
// KasenAPIExample.cpp
|
|
// plugins/KasenAPIExample/src
|
|
//
|
|
// Created by Kasen IO on 2019.07.14 | realities.dev | kasenvr@gmail.com
|
|
// Copyright 2019 Kasen IO
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
// Example of prototyping new JS APIs by leveraging the existing plugin system.
|
|
|
|
#include "DeprecatedScriptPlugin.h"
|
|
|
|
#include <QCoreApplication>
|
|
#include <QtCore/QJsonObject>
|
|
#include <QtCore/QLoggingCategory>
|
|
#include <QtCore/QThread>
|
|
#include <QtCore/QTimer>
|
|
|
|
#include <SharedUtil.h>
|
|
#include <AvatarHashMap.h>
|
|
|
|
namespace custom_api_example {
|
|
|
|
QLoggingCategory logger{ "custom_api_example" };
|
|
|
|
class KasenAPIExample : public deprecated::ScriptPlugin {
|
|
Q_OBJECT
|
|
Q_PLUGIN_METADATA(IID "KasenAPIExample" FILE "plugin.json")
|
|
public:
|
|
KasenAPIExample() : deprecated::ScriptPlugin("KasenAPIExample", "0.0.0") {
|
|
qCInfo(logger) << "plugin loaded" << qApp << toString() << QThread::currentThread();
|
|
}
|
|
|
|
public slots:
|
|
/**jsdoc
|
|
* Returns current microseconds (usecs) since Epoch. note: 1000usecs == 1ms
|
|
* @example <caption>Measure current setTimeout accuracy.</caption>
|
|
* var expected = 1000;
|
|
* var start = KasenAPIExample.now();
|
|
* Script.setTimeout(function () {
|
|
* var elapsed = (KasenAPIExample.now() - start)/1000;
|
|
* print("expected (ms):", expected, "actual (ms):", elapsed);
|
|
* }, expected);
|
|
*/
|
|
QVariant now() const {
|
|
return usecTimestampNow();
|
|
}
|
|
|
|
/**jsdoc
|
|
* Returns the available blendshape names for an avatar.
|
|
* @example <caption>Get blendshape names</caption>
|
|
* print(JSON.stringify(KasenAPIExample.getBlendshapeNames(MyAvatar.sessionUUID)));
|
|
*/
|
|
QStringList getBlendshapeNames(const QUuid& avatarID) const {
|
|
QVector<QString> out;
|
|
if (auto head = getAvatarHead(avatarID)) {
|
|
for (const auto& kv : head->getBlendshapeMap().toStdMap()) {
|
|
if (kv.second >= out.size()) out.resize(kv.second+1);
|
|
out[kv.second] = kv.first;
|
|
}
|
|
}
|
|
return out.toList();
|
|
}
|
|
|
|
/**jsdoc
|
|
* Returns a key-value object with active (non-zero) blendshapes.
|
|
* eg: { JawOpen: 1.0, ... }
|
|
* @example <caption>Get active blendshape map</caption>
|
|
* print(JSON.stringify(KasenAPIExample.getActiveBlendshapes(MyAvatar.sessionUUID)));
|
|
*/
|
|
QVariant getActiveBlendshapes(const QUuid& avatarID) const {
|
|
if (auto head = getAvatarHead(avatarID)) {
|
|
return head->toJson()["blendShapes"].toVariant();
|
|
}
|
|
return {};
|
|
}
|
|
|
|
QVariant getBlendshapeMapping(const QUuid& avatarID) const {
|
|
QVariantMap out;
|
|
if (auto head = getAvatarHead(avatarID)) {
|
|
for (const auto& kv : head->getBlendshapeMap().toStdMap()) {
|
|
out[kv.first] = kv.second;
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
QVariant getBlendshapes(const QUuid& avatarID) const {
|
|
QVariantMap result;
|
|
if (auto head = getAvatarHead(avatarID)) {
|
|
QStringList names = getBlendshapeNames(avatarID);
|
|
auto states = head->getBlendshapeStates();
|
|
result = {
|
|
{ "base", zipNonZeroValues(names, states.base) },
|
|
{ "summed", zipNonZeroValues(names, states.summed) },
|
|
{ "transient", zipNonZeroValues(names, states.transient) },
|
|
};
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private:
|
|
static QVariantMap zipNonZeroValues(const QStringList& keys, const QVector<float>& values) {
|
|
QVariantMap out;
|
|
for (int i=1; i < values.size(); i++) {
|
|
if (fabs(values[i]) > 1.0e-6f) {
|
|
out[keys.value(i)] = values[i];
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
struct _HeadHelper : public HeadData {
|
|
QMap<QString,int> getBlendshapeMap() const {
|
|
return _blendshapeLookupMap;
|
|
}
|
|
struct States { QVector<float> base, summed, transient; };
|
|
States getBlendshapeStates() const {
|
|
return {
|
|
_blendshapeCoefficients,
|
|
_summedBlendshapeCoefficients,
|
|
_transientBlendshapeCoefficients
|
|
};
|
|
}
|
|
};
|
|
static const _HeadHelper* getAvatarHead(const QUuid& avatarID) {
|
|
auto avatars = DependencyManager::get<AvatarHashMap>();
|
|
auto avatar = avatars ? avatars->getAvatarBySessionID(avatarID) : nullptr;
|
|
auto head = avatar ? avatar->getHeadData() : nullptr;
|
|
return reinterpret_cast<const _HeadHelper*>(head);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
const QLoggingCategory& deprecated::logger{ custom_api_example::logger };
|
|
|
|
#include "KasenAPIExample.moc"
|