History

rename plugin folder

humbletim committed 6 years ago

Commit fa3a8861 parent 1aac9704 files · +0 −58Browse files

Showing the changes to plugins/JSAPIExample/src/JSAPIExample.cpp (1 of 4 files). Show all

Unified · Split

plugins/JSAPIExample/src/JSAPIExample.cpp+141−0
@@ -0,0 +1,141 @@
1+//
2+// KasenAPIExample.cpp
3+// plugins/KasenAPIExample/src
4+//
5+// Created by Kasen IO on 2019.07.14 | realities.dev | kasenvr@gmail.com
6+// Copyright 2019 Kasen IO
7+//
8+// Authored by: Humbletim (humbletim@gmail.com)
9+//
10+// Distributed under the Apache License, Version 2.0.
11+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
12+//
13+// Example of prototyping new JS APIs by leveraging the existing plugin system.
14+
15+#include "ExampleScriptPlugin.h"
16+
17+#include <QCoreApplication>
18+#include <QtCore/QJsonObject>
19+#include <QtCore/QLoggingCategory>
20+#include <QtCore/QThread>
21+#include <QtCore/QTimer>
22+
23+#include <SharedUtil.h>
24+#include <AvatarHashMap.h>
25+
26+namespace custom_api_example {
27+
28+QLoggingCategory logger{ "custom_api_example" };
29+
30+class KasenAPIExample : public example::ScriptPlugin {
31+ Q_OBJECT
32+ Q_PLUGIN_METADATA(IID "KasenAPIExample" FILE "plugin.json")
33+public:
34+ KasenAPIExample() : example::ScriptPlugin("KasenAPIExample", "0.0.1") {
35+ qCInfo(logger) << "plugin loaded" << qApp << toString() << QThread::currentThread();
36+ }
37+
38+public slots:
39+ /**jsdoc
40+ * Returns current microseconds (usecs) since Epoch. note: 1000usecs == 1ms
41+ * @example <caption>Measure current setTimeout accuracy.</caption>
42+ * var expected = 1000;
43+ * var start = KasenAPIExample.now();
44+ * Script.setTimeout(function () {
45+ * var elapsed = (KasenAPIExample.now() - start)/1000;
46+ * print("expected (ms):", expected, "actual (ms):", elapsed);
47+ * }, expected);
48+ */
49+ QVariant now() const {
50+ return usecTimestampNow();
51+ }
52+
53+ /**jsdoc
54+ * Returns the available blendshape names for an avatar.
55+ * @example <caption>Get blendshape names</caption>
56+ * print(JSON.stringify(KasenAPIExample.getBlendshapeNames(MyAvatar.sessionUUID)));
57+ */
58+ QStringList getBlendshapeNames(const QUuid& avatarID) const {
59+ QVector<QString> out;
60+ if (auto head = getAvatarHead(avatarID)) {
61+ for (const auto& kv : head->getBlendshapeMap().toStdMap()) {
62+ if (kv.second >= out.size()) out.resize(kv.second+1);
63+ out[kv.second] = kv.first;
64+ }
65+ }
66+ return out.toList();
67+ }
68+
69+ /**jsdoc
70+ * Returns a key-value object with active (non-zero) blendshapes.
71+ * eg: { JawOpen: 1.0, ... }
72+ * @example <caption>Get active blendshape map</caption>
73+ * print(JSON.stringify(KasenAPIExample.getActiveBlendshapes(MyAvatar.sessionUUID)));
74+ */
75+ QVariant getActiveBlendshapes(const QUuid& avatarID) const {
76+ if (auto head = getAvatarHead(avatarID)) {
77+ return head->toJson()["blendShapes"].toVariant();
78+ }
79+ return {};
80+ }
81+
82+ QVariant getBlendshapeMapping(const QUuid& avatarID) const {
83+ QVariantMap out;
84+ if (auto head = getAvatarHead(avatarID)) {
85+ for (const auto& kv : head->getBlendshapeMap().toStdMap()) {
86+ out[kv.first] = kv.second;
87+ }
88+ }
89+ return out;
90+ }
91+
92+ QVariant getBlendshapes(const QUuid& avatarID) const {
93+ QVariantMap result;
94+ if (auto head = getAvatarHead(avatarID)) {
95+ QStringList names = getBlendshapeNames(avatarID);
96+ auto states = head->getBlendshapeStates();
97+ result = {
98+ { "base", zipNonZeroValues(names, states.base) },
99+ { "summed", zipNonZeroValues(names, states.summed) },
100+ { "transient", zipNonZeroValues(names, states.transient) },
101+ };
102+ }
103+ return result;
104+ }
105+
106+private:
107+ static QVariantMap zipNonZeroValues(const QStringList& keys, const QVector<float>& values) {
108+ QVariantMap out;
109+ for (int i=1; i < values.size(); i++) {
110+ if (fabs(values[i]) > 1.0e-6f) {
111+ out[keys.value(i)] = values[i];
112+ }
113+ }
114+ return out;
115+ }
116+ struct _HeadHelper : public HeadData {
117+ QMap<QString,int> getBlendshapeMap() const {
118+ return BLENDSHAPE_LOOKUP_MAP;
119+ }
120+ struct States { QVector<float> base, summed, transient; };
121+ States getBlendshapeStates() const {
122+ return {
123+ _blendshapeCoefficients,
124+ _summedBlendshapeCoefficients,
125+ _transientBlendshapeCoefficients
126+ };
127+ }
128+ };
129+ static const _HeadHelper* getAvatarHead(const QUuid& avatarID) {
130+ auto avatars = DependencyManager::get<AvatarHashMap>();
131+ auto avatar = avatars ? avatars->getAvatarBySessionID(avatarID) : nullptr;
132+ auto head = avatar ? avatar->getHeadData() : nullptr;
133+ return reinterpret_cast<const _HeadHelper*>(head);
134+ }
135+};
136+
137+}
138+
139+const QLoggingCategory& example::logger{ custom_api_example::logger };
140+
141+#include "KasenAPIExample.moc"