mirror of
https://github.com/overte-org/overte.git
synced 2025-06-20 14:21:20 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into bug16645
This commit is contained in:
commit
6cecfd4d24
9 changed files with 479 additions and 414 deletions
|
@ -23,6 +23,7 @@
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
#include <QtCore/QJsonDocument>
|
#include <QtCore/QJsonDocument>
|
||||||
|
#include <QtCore/QSaveFile>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtGui/QImageReader>
|
#include <QtGui/QImageReader>
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
|
@ -1042,7 +1043,7 @@ bool AssetServer::loadMappingsFromFile() {
|
||||||
bool AssetServer::writeMappingsToFile() {
|
bool AssetServer::writeMappingsToFile() {
|
||||||
auto mapFilePath = _resourcesDirectory.absoluteFilePath(MAP_FILE_NAME);
|
auto mapFilePath = _resourcesDirectory.absoluteFilePath(MAP_FILE_NAME);
|
||||||
|
|
||||||
QFile mapFile { mapFilePath };
|
QSaveFile mapFile { mapFilePath };
|
||||||
if (mapFile.open(QIODevice::WriteOnly)) {
|
if (mapFile.open(QIODevice::WriteOnly)) {
|
||||||
QJsonObject root;
|
QJsonObject root;
|
||||||
|
|
||||||
|
@ -1053,8 +1054,12 @@ bool AssetServer::writeMappingsToFile() {
|
||||||
QJsonDocument jsonDocument { root };
|
QJsonDocument jsonDocument { root };
|
||||||
|
|
||||||
if (mapFile.write(jsonDocument.toJson()) != -1) {
|
if (mapFile.write(jsonDocument.toJson()) != -1) {
|
||||||
qCDebug(asset_server) << "Wrote JSON mappings to file at" << mapFilePath;
|
if (mapFile.commit()) {
|
||||||
return true;
|
qCDebug(asset_server) << "Wrote JSON mappings to file at" << mapFilePath;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
qCWarning(asset_server) << "Failed to commit JSON mappings to file at" << mapFilePath;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(asset_server) << "Failed to write JSON mappings to file at" << mapFilePath;
|
qCWarning(asset_server) << "Failed to write JSON mappings to file at" << mapFilePath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,6 +262,26 @@ void MyAvatar::setDominantHand(const QString& hand) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyAvatar::requestDisableHandTouch() {
|
||||||
|
std::lock_guard<std::mutex> guard(_disableHandTouchMutex);
|
||||||
|
_disableHandTouchCount++;
|
||||||
|
emit shouldDisableHandTouchChanged(_disableHandTouchCount > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyAvatar::requestEnableHandTouch() {
|
||||||
|
std::lock_guard<std::mutex> guard(_disableHandTouchMutex);
|
||||||
|
_disableHandTouchCount = std::max(_disableHandTouchCount - 1, 0);
|
||||||
|
emit shouldDisableHandTouchChanged(_disableHandTouchCount > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyAvatar::disableHandTouchForID(const QUuid& entityID) {
|
||||||
|
emit disableHandTouchForIDChanged(entityID, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyAvatar::enableHandTouchForID(const QUuid& entityID) {
|
||||||
|
emit disableHandTouchForIDChanged(entityID, false);
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::registerMetaTypes(ScriptEnginePointer engine) {
|
void MyAvatar::registerMetaTypes(ScriptEnginePointer engine) {
|
||||||
QScriptValue value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects);
|
QScriptValue value = engine->newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects);
|
||||||
engine->globalObject().setProperty("MyAvatar", value);
|
engine->globalObject().setProperty("MyAvatar", value);
|
||||||
|
|
|
@ -505,6 +505,28 @@ public:
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; }
|
Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; }
|
||||||
|
/**jsdoc
|
||||||
|
* Request to enable hand touch effect globally
|
||||||
|
* @function MyAvatar.requestEnableHandTouch
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void requestEnableHandTouch();
|
||||||
|
/**jsdoc
|
||||||
|
* Request to disable hand touch effect globally
|
||||||
|
* @function MyAvatar.requestDisableHandTouch
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void requestDisableHandTouch();
|
||||||
|
/**jsdoc
|
||||||
|
* Disables hand touch effect on a specific entity
|
||||||
|
* @function MyAvatar.disableHandTouchForID
|
||||||
|
* @param {Uuid} entityID - ID of the entity that will disable hand touch effect
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void disableHandTouchForID(const QUuid& entityID);
|
||||||
|
/**jsdoc
|
||||||
|
* Enables hand touch effect on a specific entity
|
||||||
|
* @function MyAvatar.enableHandTouchForID
|
||||||
|
* @param {Uuid} entityID - ID of the entity that will enable hand touch effect
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void enableHandTouchForID(const QUuid& entityID);
|
||||||
|
|
||||||
bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); }
|
bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); }
|
||||||
void setUseAdvancedMovementControls(bool useAdvancedMovementControls)
|
void setUseAdvancedMovementControls(bool useAdvancedMovementControls)
|
||||||
|
@ -1392,6 +1414,23 @@ signals:
|
||||||
*/
|
*/
|
||||||
void scaleChanged();
|
void scaleChanged();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when hand touch is globally enabled or disabled
|
||||||
|
* @function MyAvatar.shouldDisableHandTouchChanged
|
||||||
|
* @param {boolean} shouldDisable
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void shouldDisableHandTouchChanged(bool shouldDisable);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when hand touch is enabled or disabled for an specific entity
|
||||||
|
* @function MyAvatar.disableHandTouchForIDChanged
|
||||||
|
* @param {Uuid} entityID - ID of the entity that will enable hand touch effect
|
||||||
|
* @param {boolean} disable
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void disableHandTouchForIDChanged(const QUuid& entityID, bool disable);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void leaveDomain();
|
void leaveDomain();
|
||||||
|
|
||||||
|
@ -1628,6 +1667,7 @@ private:
|
||||||
// all poses are in sensor-frame
|
// all poses are in sensor-frame
|
||||||
std::map<controller::Action, controller::Pose> _controllerPoseMap;
|
std::map<controller::Action, controller::Pose> _controllerPoseMap;
|
||||||
mutable std::mutex _controllerPoseMapMutex;
|
mutable std::mutex _controllerPoseMapMutex;
|
||||||
|
mutable std::mutex _disableHandTouchMutex;
|
||||||
|
|
||||||
bool _centerOfGravityModelEnabled { true };
|
bool _centerOfGravityModelEnabled { true };
|
||||||
bool _hmdLeanRecenterEnabled { true };
|
bool _hmdLeanRecenterEnabled { true };
|
||||||
|
@ -1668,6 +1708,7 @@ private:
|
||||||
bool _shouldLoadScripts { false };
|
bool _shouldLoadScripts { false };
|
||||||
|
|
||||||
bool _haveReceivedHeightLimitsFromDomain { false };
|
bool _haveReceivedHeightLimitsFromDomain { false };
|
||||||
|
int _disableHandTouchCount { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);
|
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);
|
||||||
|
|
|
@ -21,14 +21,17 @@
|
||||||
#include <QtCore/qpair.h>
|
#include <QtCore/qpair.h>
|
||||||
#include <QtCore/qlist.h>
|
#include <QtCore/qlist.h>
|
||||||
|
|
||||||
|
|
||||||
#include <QtNetwork/QNetworkAccessManager>
|
#include <QtNetwork/QNetworkAccessManager>
|
||||||
#include <QtNetwork/QNetworkRequest>
|
#include <QtNetwork/QNetworkRequest>
|
||||||
|
|
||||||
#include <qfile.h>
|
#include <qfile.h>
|
||||||
|
#include <qfileinfo.h>
|
||||||
|
|
||||||
#include <shared/NsightHelpers.h>
|
#include <shared/NsightHelpers.h>
|
||||||
#include <NetworkAccessManager.h>
|
#include <NetworkAccessManager.h>
|
||||||
#include <ResourceManager.h>
|
#include <ResourceManager.h>
|
||||||
|
#include <PathUtils.h>
|
||||||
|
|
||||||
#include "FBXReader.h"
|
#include "FBXReader.h"
|
||||||
|
|
||||||
|
@ -786,13 +789,18 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
|
||||||
QVector<glm::vec3> raw_vertices;
|
QVector<glm::vec3> raw_vertices;
|
||||||
QVector<glm::vec3> raw_normals;
|
QVector<glm::vec3> raw_normals;
|
||||||
|
|
||||||
addArrayOfType(indicesBuffer.blob,
|
bool success = addArrayOfType(indicesBuffer.blob,
|
||||||
indicesBufferview.byteOffset + indicesAccBoffset,
|
indicesBufferview.byteOffset + indicesAccBoffset,
|
||||||
indicesBufferview.byteLength,
|
indicesAccessor.count,
|
||||||
part.triangleIndices,
|
part.triangleIndices,
|
||||||
indicesAccessor.type,
|
indicesAccessor.type,
|
||||||
indicesAccessor.componentType);
|
indicesAccessor.componentType);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
qWarning(modelformat) << "There was a problem reading glTF INDICES data for model " << _url;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
QList<QString> keys = primitive.attributes.values.keys();
|
QList<QString> keys = primitive.attributes.values.keys();
|
||||||
|
|
||||||
foreach(auto &key, keys) {
|
foreach(auto &key, keys) {
|
||||||
|
@ -805,44 +813,60 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
|
||||||
int accBoffset = accessor.defined["byteOffset"] ? accessor.byteOffset : 0;
|
int accBoffset = accessor.defined["byteOffset"] ? accessor.byteOffset : 0;
|
||||||
if (key == "POSITION") {
|
if (key == "POSITION") {
|
||||||
QVector<float> vertices;
|
QVector<float> vertices;
|
||||||
addArrayOfType(buffer.blob,
|
success = addArrayOfType(buffer.blob,
|
||||||
bufferview.byteOffset + accBoffset,
|
bufferview.byteOffset + accBoffset,
|
||||||
bufferview.byteLength, vertices,
|
accessor.count, vertices,
|
||||||
accessor.type,
|
accessor.type,
|
||||||
accessor.componentType);
|
accessor.componentType);
|
||||||
|
if (!success) {
|
||||||
|
qWarning(modelformat) << "There was a problem reading glTF POSITION data for model " << _url;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int n = 0; n < vertices.size(); n = n + 3) {
|
for (int n = 0; n < vertices.size(); n = n + 3) {
|
||||||
mesh.vertices.push_back(glm::vec3(vertices[n], vertices[n + 1], vertices[n + 2]));
|
mesh.vertices.push_back(glm::vec3(vertices[n], vertices[n + 1], vertices[n + 2]));
|
||||||
}
|
}
|
||||||
} else if (key == "NORMAL") {
|
} else if (key == "NORMAL") {
|
||||||
QVector<float> normals;
|
QVector<float> normals;
|
||||||
addArrayOfType(buffer.blob,
|
success = addArrayOfType(buffer.blob,
|
||||||
bufferview.byteOffset + accBoffset,
|
bufferview.byteOffset + accBoffset,
|
||||||
bufferview.byteLength,
|
accessor.count,
|
||||||
normals,
|
normals,
|
||||||
accessor.type,
|
accessor.type,
|
||||||
accessor.componentType);
|
accessor.componentType);
|
||||||
|
if (!success) {
|
||||||
|
qWarning(modelformat) << "There was a problem reading glTF NORMAL data for model " << _url;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int n = 0; n < normals.size(); n = n + 3) {
|
for (int n = 0; n < normals.size(); n = n + 3) {
|
||||||
mesh.normals.push_back(glm::vec3(normals[n], normals[n + 1], normals[n + 2]));
|
mesh.normals.push_back(glm::vec3(normals[n], normals[n + 1], normals[n + 2]));
|
||||||
}
|
}
|
||||||
} else if (key == "TEXCOORD_0") {
|
} else if (key == "TEXCOORD_0") {
|
||||||
QVector<float> texcoords;
|
QVector<float> texcoords;
|
||||||
addArrayOfType(buffer.blob,
|
success = addArrayOfType(buffer.blob,
|
||||||
bufferview.byteOffset + accBoffset,
|
bufferview.byteOffset + accBoffset,
|
||||||
bufferview.byteLength,
|
accessor.count,
|
||||||
texcoords,
|
texcoords,
|
||||||
accessor.type,
|
accessor.type,
|
||||||
accessor.componentType);
|
accessor.componentType);
|
||||||
|
if (!success) {
|
||||||
|
qWarning(modelformat) << "There was a problem reading glTF TEXCOORD_0 data for model " << _url;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int n = 0; n < texcoords.size(); n = n + 2) {
|
for (int n = 0; n < texcoords.size(); n = n + 2) {
|
||||||
mesh.texCoords.push_back(glm::vec2(texcoords[n], texcoords[n + 1]));
|
mesh.texCoords.push_back(glm::vec2(texcoords[n], texcoords[n + 1]));
|
||||||
}
|
}
|
||||||
} else if (key == "TEXCOORD_1") {
|
} else if (key == "TEXCOORD_1") {
|
||||||
QVector<float> texcoords;
|
QVector<float> texcoords;
|
||||||
addArrayOfType(buffer.blob,
|
success = addArrayOfType(buffer.blob,
|
||||||
bufferview.byteOffset + accBoffset,
|
bufferview.byteOffset + accBoffset,
|
||||||
bufferview.byteLength,
|
accessor.count,
|
||||||
texcoords,
|
texcoords,
|
||||||
accessor.type,
|
accessor.type,
|
||||||
accessor.componentType);
|
accessor.componentType);
|
||||||
|
if (!success) {
|
||||||
|
qWarning(modelformat) << "There was a problem reading glTF TEXCOORD_1 data for model " << _url;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int n = 0; n < texcoords.size(); n = n + 2) {
|
for (int n = 0; n < texcoords.size(); n = n + 2) {
|
||||||
mesh.texCoords1.push_back(glm::vec2(texcoords[n], texcoords[n + 1]));
|
mesh.texCoords1.push_back(glm::vec2(texcoords[n], texcoords[n + 1]));
|
||||||
}
|
}
|
||||||
|
@ -888,8 +912,16 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
|
||||||
|
|
||||||
FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping,
|
FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping,
|
||||||
const QUrl& url, bool loadLightmaps, float lightmapLevel) {
|
const QUrl& url, bool loadLightmaps, float lightmapLevel) {
|
||||||
|
|
||||||
_url = url;
|
_url = url;
|
||||||
|
|
||||||
|
// Normalize url for local files
|
||||||
|
QUrl normalizeUrl = DependencyManager::get<ResourceManager>()->normalizeURL(url);
|
||||||
|
if (normalizeUrl.scheme().isEmpty() || (normalizeUrl.scheme() == "file")) {
|
||||||
|
QString localFileName = PathUtils::expandToLocalDataAbsolutePath(normalizeUrl).toLocalFile();
|
||||||
|
_url = QUrl(QFileInfo(localFileName).absoluteFilePath());
|
||||||
|
}
|
||||||
|
|
||||||
parseGLTF(model);
|
parseGLTF(model);
|
||||||
//_file.dump();
|
//_file.dump();
|
||||||
FBXGeometry* geometryPtr = new FBXGeometry();
|
FBXGeometry* geometryPtr = new FBXGeometry();
|
||||||
|
@ -904,6 +936,7 @@ FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping
|
||||||
|
|
||||||
bool GLTFReader::readBinary(const QString& url, QByteArray& outdata) {
|
bool GLTFReader::readBinary(const QString& url, QByteArray& outdata) {
|
||||||
QUrl binaryUrl = _url.resolved(QUrl(url).fileName());
|
QUrl binaryUrl = _url.resolved(QUrl(url).fileName());
|
||||||
|
|
||||||
qCDebug(modelformat) << "binaryUrl: " << binaryUrl << " OriginalUrl: " << _url;
|
qCDebug(modelformat) << "binaryUrl: " << binaryUrl << " OriginalUrl: " << _url;
|
||||||
bool success;
|
bool success;
|
||||||
std::tie<bool, QByteArray>(success, outdata) = requestData(binaryUrl);
|
std::tie<bool, QByteArray>(success, outdata) = requestData(binaryUrl);
|
||||||
|
@ -1018,13 +1051,12 @@ void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& materia
|
||||||
fbxmat.opacityTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
fbxmat.opacityTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
||||||
fbxmat.albedoTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
fbxmat.albedoTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
||||||
fbxmat.useAlbedoMap = true;
|
fbxmat.useAlbedoMap = true;
|
||||||
fbxmat.metallicTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
|
||||||
fbxmat.useMetallicMap = true;
|
|
||||||
}
|
}
|
||||||
if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) {
|
if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) {
|
||||||
fbxmat.roughnessTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
fbxmat.roughnessTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
||||||
fbxmat.useRoughnessMap = true;
|
fbxmat.useRoughnessMap = true;
|
||||||
|
fbxmat.metallicTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
||||||
|
fbxmat.useMetallicMap = true;
|
||||||
}
|
}
|
||||||
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
|
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
|
||||||
fbxmat._material->setRoughness(material.pbrMetallicRoughness.roughnessFactor);
|
fbxmat._material->setRoughness(material.pbrMetallicRoughness.roughnessFactor);
|
||||||
|
@ -1043,7 +1075,7 @@ void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& materia
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename L>
|
template<typename T, typename L>
|
||||||
bool GLTFReader::readArray(const QByteArray& bin, int byteOffset, int byteLength,
|
bool GLTFReader::readArray(const QByteArray& bin, int byteOffset, int count,
|
||||||
QVector<L>& outarray, int accessorType) {
|
QVector<L>& outarray, int accessorType) {
|
||||||
|
|
||||||
QDataStream blobstream(bin);
|
QDataStream blobstream(bin);
|
||||||
|
@ -1051,142 +1083,77 @@ bool GLTFReader::readArray(const QByteArray& bin, int byteOffset, int byteLength
|
||||||
blobstream.setVersion(QDataStream::Qt_5_9);
|
blobstream.setVersion(QDataStream::Qt_5_9);
|
||||||
blobstream.setFloatingPointPrecision(QDataStream::FloatingPointPrecision::SinglePrecision);
|
blobstream.setFloatingPointPrecision(QDataStream::FloatingPointPrecision::SinglePrecision);
|
||||||
|
|
||||||
int vsize = byteLength / sizeof(T);
|
qCDebug(modelformat) << "size1: " << count;
|
||||||
|
|
||||||
qCDebug(modelformat) << "size1: " << vsize;
|
|
||||||
int dataskipped = blobstream.skipRawData(byteOffset);
|
int dataskipped = blobstream.skipRawData(byteOffset);
|
||||||
qCDebug(modelformat) << "dataskipped: " << dataskipped;
|
qCDebug(modelformat) << "dataskipped: " << dataskipped;
|
||||||
|
|
||||||
|
int bufferCount = 0;
|
||||||
while (outarray.size() < vsize) {
|
switch (accessorType) {
|
||||||
|
case GLTFAccessorType::SCALAR:
|
||||||
T value1, value2, value3, value4,
|
bufferCount = 1;
|
||||||
value5, value6, value7, value8,
|
break;
|
||||||
value9, value10, value11, value12,
|
case GLTFAccessorType::VEC2:
|
||||||
value13, value14, value15, value16;
|
bufferCount = 2;
|
||||||
|
break;
|
||||||
if (accessorType == GLTFAccessorType::SCALAR) {
|
case GLTFAccessorType::VEC3:
|
||||||
|
bufferCount = 3;
|
||||||
blobstream >> value1;
|
break;
|
||||||
|
case GLTFAccessorType::VEC4:
|
||||||
outarray.push_back(value1);
|
bufferCount = 4;
|
||||||
} else if (accessorType == GLTFAccessorType::VEC2) {
|
break;
|
||||||
|
case GLTFAccessorType::MAT2:
|
||||||
blobstream >> value1;
|
bufferCount = 4;
|
||||||
blobstream >> value2;
|
break;
|
||||||
|
case GLTFAccessorType::MAT3:
|
||||||
outarray.push_back(value1);
|
bufferCount = 9;
|
||||||
outarray.push_back(value2);
|
break;
|
||||||
} else if (accessorType == GLTFAccessorType::VEC3) {
|
case GLTFAccessorType::MAT4:
|
||||||
|
bufferCount = 16;
|
||||||
blobstream >> value1;
|
break;
|
||||||
blobstream >> value2;
|
default:
|
||||||
blobstream >> value3;
|
qWarning(modelformat) << "Unknown accessorType: " << accessorType;
|
||||||
|
blobstream.unsetDevice();
|
||||||
outarray.push_back(value1);
|
return false;
|
||||||
outarray.push_back(value2);
|
}
|
||||||
outarray.push_back(value3);
|
for (int i = 0; i < count; i++) {
|
||||||
} else if (accessorType == GLTFAccessorType::VEC4 || accessorType == GLTFAccessorType::MAT2) {
|
for (int j = 0; j < bufferCount; j++) {
|
||||||
|
if (!blobstream.atEnd()) {
|
||||||
blobstream >> value1;
|
T value;
|
||||||
blobstream >> value2;
|
blobstream >> value;
|
||||||
blobstream >> value3;
|
outarray.push_back(value);
|
||||||
blobstream >> value4;
|
} else {
|
||||||
|
blobstream.unsetDevice();
|
||||||
outarray.push_back(value1);
|
return false;
|
||||||
outarray.push_back(value2);
|
}
|
||||||
outarray.push_back(value3);
|
|
||||||
outarray.push_back(value4);
|
|
||||||
} else if (accessorType == GLTFAccessorType::MAT3) {
|
|
||||||
|
|
||||||
blobstream >> value1;
|
|
||||||
blobstream >> value2;
|
|
||||||
blobstream >> value3;
|
|
||||||
blobstream >> value4;
|
|
||||||
blobstream >> value5;
|
|
||||||
blobstream >> value6;
|
|
||||||
blobstream >> value7;
|
|
||||||
blobstream >> value8;
|
|
||||||
blobstream >> value9;
|
|
||||||
|
|
||||||
outarray.push_back(value1);
|
|
||||||
outarray.push_back(value2);
|
|
||||||
outarray.push_back(value3);
|
|
||||||
outarray.push_back(value4);
|
|
||||||
outarray.push_back(value5);
|
|
||||||
outarray.push_back(value6);
|
|
||||||
outarray.push_back(value7);
|
|
||||||
outarray.push_back(value8);
|
|
||||||
outarray.push_back(value9);
|
|
||||||
} else if (accessorType == GLTFAccessorType::MAT4) {
|
|
||||||
|
|
||||||
blobstream >> value1;
|
|
||||||
blobstream >> value2;
|
|
||||||
blobstream >> value3;
|
|
||||||
blobstream >> value4;
|
|
||||||
blobstream >> value5;
|
|
||||||
blobstream >> value6;
|
|
||||||
blobstream >> value7;
|
|
||||||
blobstream >> value8;
|
|
||||||
blobstream >> value9;
|
|
||||||
blobstream >> value10;
|
|
||||||
blobstream >> value11;
|
|
||||||
blobstream >> value12;
|
|
||||||
blobstream >> value13;
|
|
||||||
blobstream >> value14;
|
|
||||||
blobstream >> value15;
|
|
||||||
blobstream >> value16;
|
|
||||||
|
|
||||||
outarray.push_back(value1);
|
|
||||||
outarray.push_back(value2);
|
|
||||||
outarray.push_back(value3);
|
|
||||||
outarray.push_back(value4);
|
|
||||||
outarray.push_back(value5);
|
|
||||||
outarray.push_back(value6);
|
|
||||||
outarray.push_back(value7);
|
|
||||||
outarray.push_back(value8);
|
|
||||||
outarray.push_back(value9);
|
|
||||||
outarray.push_back(value10);
|
|
||||||
outarray.push_back(value11);
|
|
||||||
outarray.push_back(value12);
|
|
||||||
outarray.push_back(value13);
|
|
||||||
outarray.push_back(value14);
|
|
||||||
outarray.push_back(value15);
|
|
||||||
outarray.push_back(value16);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blobstream.unsetDevice();
|
blobstream.unsetDevice();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool GLTFReader::addArrayOfType(const QByteArray& bin, int byteOffset, int byteLength,
|
bool GLTFReader::addArrayOfType(const QByteArray& bin, int byteOffset, int count,
|
||||||
QVector<T>& outarray, int accessorType, int componentType) {
|
QVector<T>& outarray, int accessorType, int componentType) {
|
||||||
|
|
||||||
switch (componentType) {
|
switch (componentType) {
|
||||||
case GLTFAccessorComponentType::BYTE: {}
|
case GLTFAccessorComponentType::BYTE: {}
|
||||||
case GLTFAccessorComponentType::UNSIGNED_BYTE: {
|
case GLTFAccessorComponentType::UNSIGNED_BYTE: {
|
||||||
readArray<uchar>(bin, byteOffset, byteLength, outarray, accessorType);
|
return readArray<uchar>(bin, byteOffset, count, outarray, accessorType);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case GLTFAccessorComponentType::SHORT: {
|
case GLTFAccessorComponentType::SHORT: {
|
||||||
readArray<short>(bin, byteOffset, byteLength, outarray, accessorType);
|
return readArray<short>(bin, byteOffset, count, outarray, accessorType);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case GLTFAccessorComponentType::UNSIGNED_INT: {
|
case GLTFAccessorComponentType::UNSIGNED_INT: {
|
||||||
readArray<quint32>(bin, byteOffset, byteLength, outarray, accessorType);
|
return readArray<uint>(bin, byteOffset, count, outarray, accessorType);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case GLTFAccessorComponentType::UNSIGNED_SHORT: {
|
case GLTFAccessorComponentType::UNSIGNED_SHORT: {
|
||||||
readArray<ushort>(bin, byteOffset, byteLength, outarray, accessorType);
|
return readArray<ushort>(bin, byteOffset, count, outarray, accessorType);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case GLTFAccessorComponentType::FLOAT: {
|
case GLTFAccessorComponentType::FLOAT: {
|
||||||
readArray<float>(bin, byteOffset, byteLength, outarray, accessorType);
|
return readArray<float>(bin, byteOffset, count, outarray, accessorType);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLTFReader::retriangulate(const QVector<int>& inIndices, const QVector<glm::vec3>& in_vertices,
|
void GLTFReader::retriangulate(const QVector<int>& inIndices, const QVector<glm::vec3>& in_vertices,
|
||||||
|
|
|
@ -762,11 +762,11 @@ private:
|
||||||
bool readBinary(const QString& url, QByteArray& outdata);
|
bool readBinary(const QString& url, QByteArray& outdata);
|
||||||
|
|
||||||
template<typename T, typename L>
|
template<typename T, typename L>
|
||||||
bool readArray(const QByteArray& bin, int byteOffset, int byteLength,
|
bool readArray(const QByteArray& bin, int byteOffset, int count,
|
||||||
QVector<L>& outarray, int accessorType);
|
QVector<L>& outarray, int accessorType);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool addArrayOfType(const QByteArray& bin, int byteOffset, int byteLength,
|
bool addArrayOfType(const QByteArray& bin, int byteOffset, int count,
|
||||||
QVector<T>& outarray, int accessorType, int componentType);
|
QVector<T>& outarray, int accessorType, int componentType);
|
||||||
|
|
||||||
void retriangulate(const QVector<int>& in_indices, const QVector<glm::vec3>& in_vertices,
|
void retriangulate(const QVector<int>& in_indices, const QVector<glm::vec3>& in_vertices,
|
||||||
|
|
|
@ -14,64 +14,64 @@
|
||||||
/* global Script, Overlays, Controller, Vec3, MyAvatar, Entities
|
/* global Script, Overlays, Controller, Vec3, MyAvatar, Entities
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function() {
|
(function () {
|
||||||
|
|
||||||
var MSECONDS_AFTER_LOAD = 2000;
|
|
||||||
|
|
||||||
|
var handTouchEnabled = true;
|
||||||
|
var MSECONDS_AFTER_LOAD = 2000;
|
||||||
var updateFingerWithIndex = 0;
|
var updateFingerWithIndex = 0;
|
||||||
|
var untouchableEntities = [];
|
||||||
|
|
||||||
|
// Keys to access finger data
|
||||||
// Keys to access finger data
|
|
||||||
var fingerKeys = ["pinky", "ring", "middle", "index", "thumb"];
|
var fingerKeys = ["pinky", "ring", "middle", "index", "thumb"];
|
||||||
|
|
||||||
// Additionally close the hands to achieve a grabbing effect
|
// Additionally close the hands to achieve a grabbing effect
|
||||||
var grabPercent = { left: 0, right: 0 };
|
var grabPercent = { left: 0, right: 0 };
|
||||||
|
|
||||||
var Palm = function() {
|
var Palm = function() {
|
||||||
this.position = {x: 0, y: 0, z: 0};
|
this.position = {x: 0, y: 0, z: 0};
|
||||||
this.perpendicular = {x: 0, y: 0, z: 0};
|
this.perpendicular = {x: 0, y: 0, z: 0};
|
||||||
this.distance = 0;
|
this.distance = 0;
|
||||||
this.fingers = {
|
this.fingers = {
|
||||||
pinky: {x: 0, y: 0, z: 0},
|
pinky: {x: 0, y: 0, z: 0},
|
||||||
middle: {x: 0, y: 0, z: 0},
|
middle: {x: 0, y: 0, z: 0},
|
||||||
ring: {x: 0, y: 0, z: 0},
|
ring: {x: 0, y: 0, z: 0},
|
||||||
thumb: {x: 0, y: 0, z: 0},
|
thumb: {x: 0, y: 0, z: 0},
|
||||||
index: {x: 0, y: 0, z: 0}
|
index: {x: 0, y: 0, z: 0}
|
||||||
};
|
};
|
||||||
this.set = false;
|
this.set = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
var palmData = {
|
var palmData = {
|
||||||
left: new Palm(),
|
left: new Palm(),
|
||||||
right: new Palm()
|
right: new Palm()
|
||||||
};
|
};
|
||||||
|
|
||||||
var handJointNames = {left: "LeftHand", right: "RightHand"};
|
var handJointNames = {left: "LeftHand", right: "RightHand"};
|
||||||
|
|
||||||
// Store which fingers are touching - if all false restate the default poses
|
// Store which fingers are touching - if all false restate the default poses
|
||||||
var isTouching = {
|
var isTouching = {
|
||||||
left: {
|
left: {
|
||||||
pinky: false,
|
pinky: false,
|
||||||
middle: false,
|
middle: false,
|
||||||
ring: false,
|
ring: false,
|
||||||
thumb: false,
|
thumb: false,
|
||||||
index: false
|
index: false
|
||||||
}, right: {
|
}, right: {
|
||||||
pinky: false,
|
pinky: false,
|
||||||
middle: false,
|
middle: false,
|
||||||
ring: false,
|
ring: false,
|
||||||
thumb: false,
|
thumb: false,
|
||||||
index: false
|
index: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// frame count for transition to default pose
|
// frame count for transition to default pose
|
||||||
|
|
||||||
var countToDefault = {
|
var countToDefault = {
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0
|
right: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// joint data for open pose
|
// joint data for open pose
|
||||||
var dataOpen = {
|
var dataOpen = {
|
||||||
left: {
|
left: {
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// joint data for close pose
|
// joint data for close pose
|
||||||
var dataClose = {
|
var dataClose = {
|
||||||
left: {
|
left: {
|
||||||
|
@ -185,78 +185,78 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// snapshot for the default pose
|
// snapshot for the default pose
|
||||||
var dataDefault = {
|
var dataDefault = {
|
||||||
left: {
|
left: {
|
||||||
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
set: false
|
set: false
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
set: false
|
set: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// joint data for the current frame
|
// joint data for the current frame
|
||||||
var dataCurrent = {
|
var dataCurrent = {
|
||||||
left: {
|
left: {
|
||||||
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}]
|
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}]
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}]
|
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// interpolated values on joint data to smooth movement
|
// interpolated values on joint data to smooth movement
|
||||||
var dataDelta = {
|
var dataDelta = {
|
||||||
left: {
|
left: {
|
||||||
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}]
|
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}]
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
pinky: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
middle: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
ring: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
thumb: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}],
|
||||||
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}]
|
index: [{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0},{x: 0, y: 0, z: 0, w: 0}]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Acquire an updated value per hand every 5 frames when finger is touching (faster in)
|
// Acquire an updated value per hand every 5 frames when finger is touching (faster in)
|
||||||
var touchAnimationSteps = 5;
|
var touchAnimationSteps = 5;
|
||||||
|
|
||||||
// Acquire an updated value per hand every 20 frames when finger is returning to default position (slower out)
|
// Acquire an updated value per hand every 20 frames when finger is returning to default position (slower out)
|
||||||
var defaultAnimationSteps = 10;
|
var defaultAnimationSteps = 10;
|
||||||
|
|
||||||
// Debugging info
|
// Debugging info
|
||||||
var showSphere = false;
|
var showSphere = false;
|
||||||
var showLines = false;
|
var showLines = false;
|
||||||
|
|
||||||
// This get setup on creation
|
// This get setup on creation
|
||||||
var linesCreated = false;
|
var linesCreated = false;
|
||||||
var sphereCreated = false;
|
var sphereCreated = false;
|
||||||
|
|
||||||
// Register object with API Debugger
|
// Register object with API Debugger
|
||||||
var varsToDebug = {
|
var varsToDebug = {
|
||||||
scriptLoaded: false,
|
scriptLoaded: false,
|
||||||
toggleDebugSphere: function() {
|
toggleDebugSphere: function() {
|
||||||
|
@ -275,17 +275,17 @@
|
||||||
},
|
},
|
||||||
fingerPercent: {
|
fingerPercent: {
|
||||||
left: {
|
left: {
|
||||||
pinky: 0.38,
|
pinky: 0.38,
|
||||||
middle: 0.38,
|
middle: 0.38,
|
||||||
ring: 0.38,
|
ring: 0.38,
|
||||||
thumb: 0.38,
|
thumb: 0.38,
|
||||||
index: 0.38
|
index: 0.38
|
||||||
} ,
|
} ,
|
||||||
right: {
|
right: {
|
||||||
pinky: 0.38,
|
pinky: 0.38,
|
||||||
middle: 0.38,
|
middle: 0.38,
|
||||||
ring: 0.38,
|
ring: 0.38,
|
||||||
thumb: 0.38,
|
thumb: 0.38,
|
||||||
index: 0.38
|
index: 0.38
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -300,12 +300,11 @@
|
||||||
palmData: {
|
palmData: {
|
||||||
left: new Palm(),
|
left: new Palm(),
|
||||||
right: new Palm()
|
right: new Palm()
|
||||||
},
|
},
|
||||||
offset: {x: 0, y: 0, z: 0},
|
offset: {x: 0, y: 0, z: 0},
|
||||||
avatarLoaded: false
|
avatarLoaded: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Add/Subtract the joint data - per finger joint
|
// Add/Subtract the joint data - per finger joint
|
||||||
function addVals(val1, val2, sign) {
|
function addVals(val1, val2, sign) {
|
||||||
var val = [];
|
var val = [];
|
||||||
|
@ -321,7 +320,7 @@
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply/Divide the joint data - per finger joint
|
// Multiply/Divide the joint data - per finger joint
|
||||||
function multiplyValsBy(val1, num) {
|
function multiplyValsBy(val1, num) {
|
||||||
var val = [];
|
var val = [];
|
||||||
|
@ -334,7 +333,7 @@
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the finger lengths by adding its joint lengths
|
// Calculate the finger lengths by adding its joint lengths
|
||||||
function getJointDistances(jointNamesArray) {
|
function getJointDistances(jointNamesArray) {
|
||||||
var result = {distances: [], totalDistance: 0};
|
var result = {distances: [], totalDistance: 0};
|
||||||
|
@ -349,13 +348,12 @@
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dataRelativeToWorld(side, dataIn, dataOut) {
|
|
||||||
|
|
||||||
|
function dataRelativeToWorld(side, dataIn, dataOut) {
|
||||||
var handJoint = handJointNames[side];
|
var handJoint = handJointNames[side];
|
||||||
var jointIndex = MyAvatar.getJointIndex(handJoint);
|
var jointIndex = MyAvatar.getJointIndex(handJoint);
|
||||||
var worldPosHand = MyAvatar.jointToWorldPoint({x: 0, y: 0, z: 0}, jointIndex);
|
var worldPosHand = MyAvatar.jointToWorldPoint({x: 0, y: 0, z: 0}, jointIndex);
|
||||||
|
|
||||||
dataOut.position = MyAvatar.jointToWorldPoint(dataIn.position, jointIndex);
|
dataOut.position = MyAvatar.jointToWorldPoint(dataIn.position, jointIndex);
|
||||||
var localPerpendicular = side === "right" ? {x: 0.2, y: 0, z: 1} : {x: -0.2, y: 0, z: 1};
|
var localPerpendicular = side === "right" ? {x: 0.2, y: 0, z: 1} : {x: -0.2, y: 0, z: 1};
|
||||||
dataOut.perpendicular = Vec3.normalize(
|
dataOut.perpendicular = Vec3.normalize(
|
||||||
|
@ -365,15 +363,14 @@
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
var finger = fingerKeys[i];
|
var finger = fingerKeys[i];
|
||||||
dataOut.fingers[finger] = MyAvatar.jointToWorldPoint(dataIn.fingers[finger], jointIndex);
|
dataOut.fingers[finger] = MyAvatar.jointToWorldPoint(dataIn.fingers[finger], jointIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dataRelativeToHandJoint(side, dataIn, dataOut) {
|
|
||||||
|
|
||||||
|
function dataRelativeToHandJoint(side, dataIn, dataOut) {
|
||||||
var handJoint = handJointNames[side];
|
var handJoint = handJointNames[side];
|
||||||
var jointIndex = MyAvatar.getJointIndex(handJoint);
|
var jointIndex = MyAvatar.getJointIndex(handJoint);
|
||||||
var worldPosHand = MyAvatar.jointToWorldPoint({x: 0, y: 0, z: 0}, jointIndex);
|
var worldPosHand = MyAvatar.jointToWorldPoint({x: 0, y: 0, z: 0}, jointIndex);
|
||||||
|
|
||||||
dataOut.position = MyAvatar.worldToJointPoint(dataIn.position, jointIndex);
|
dataOut.position = MyAvatar.worldToJointPoint(dataIn.position, jointIndex);
|
||||||
dataOut.perpendicular = MyAvatar.worldToJointPoint(Vec3.sum(worldPosHand, dataIn.perpendicular), jointIndex);
|
dataOut.perpendicular = MyAvatar.worldToJointPoint(Vec3.sum(worldPosHand, dataIn.perpendicular), jointIndex);
|
||||||
dataOut.distance = dataIn.distance;
|
dataOut.distance = dataIn.distance;
|
||||||
|
@ -382,46 +379,44 @@
|
||||||
dataOut.fingers[finger] = MyAvatar.worldToJointPoint(dataIn.fingers[finger], jointIndex);
|
dataOut.fingers[finger] = MyAvatar.worldToJointPoint(dataIn.fingers[finger], jointIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate touch field; Sphere at the center of the palm,
|
// Calculate touch field; Sphere at the center of the palm,
|
||||||
// perpendicular vector from the palm plane and origin of the the finger rays
|
// perpendicular vector from the palm plane and origin of the the finger rays
|
||||||
|
|
||||||
function estimatePalmData(side) {
|
function estimatePalmData(side) {
|
||||||
// Return data object
|
// Return data object
|
||||||
var data = new Palm();
|
var data = new Palm();
|
||||||
|
|
||||||
var jointOffset = { x: 0, y: 0, z: 0 };
|
var jointOffset = { x: 0, y: 0, z: 0 };
|
||||||
|
|
||||||
var upperSide = side[0].toUpperCase() + side.substring(1);
|
var upperSide = side[0].toUpperCase() + side.substring(1);
|
||||||
var jointIndexHand = MyAvatar.getJointIndex(upperSide + "Hand");
|
var jointIndexHand = MyAvatar.getJointIndex(upperSide + "Hand");
|
||||||
|
|
||||||
// Store position of the hand joint
|
// Store position of the hand joint
|
||||||
var worldPosHand = MyAvatar.jointToWorldPoint(jointOffset, jointIndexHand);
|
var worldPosHand = MyAvatar.jointToWorldPoint(jointOffset, jointIndexHand);
|
||||||
var minusWorldPosHand = {x: -worldPosHand.x, y: -worldPosHand.y, z: -worldPosHand.z};
|
var minusWorldPosHand = {x: -worldPosHand.x, y: -worldPosHand.y, z: -worldPosHand.z};
|
||||||
|
|
||||||
// Data for finger rays
|
// Data for finger rays
|
||||||
var directions = {pinky: undefined, middle: undefined, ring: undefined, thumb: undefined, index: undefined};
|
var directions = {pinky: undefined, middle: undefined, ring: undefined, thumb: undefined, index: undefined};
|
||||||
var positions = {pinky: undefined, middle: undefined, ring: undefined, thumb: undefined, index: undefined};
|
var positions = {pinky: undefined, middle: undefined, ring: undefined, thumb: undefined, index: undefined};
|
||||||
|
|
||||||
var thumbLength = 0;
|
var thumbLength = 0;
|
||||||
var weightCount = 0;
|
var weightCount = 0;
|
||||||
|
|
||||||
// Calculate palm center
|
// Calculate palm center
|
||||||
|
|
||||||
var handJointWeight = 1;
|
var handJointWeight = 1;
|
||||||
var fingerJointWeight = 2;
|
var fingerJointWeight = 2;
|
||||||
|
|
||||||
var palmCenter = {x: 0, y: 0, z: 0};
|
var palmCenter = {x: 0, y: 0, z: 0};
|
||||||
palmCenter = Vec3.sum(worldPosHand, palmCenter);
|
palmCenter = Vec3.sum(worldPosHand, palmCenter);
|
||||||
|
|
||||||
weightCount += handJointWeight;
|
weightCount += handJointWeight;
|
||||||
|
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
var finger = fingerKeys[i];
|
var finger = fingerKeys[i];
|
||||||
var jointSuffixes = 4; // Get 4 joint names with suffix numbers (0, 1, 2, 3)
|
var jointSuffixes = 4; // Get 4 joint names with suffix numbers (0, 1, 2, 3)
|
||||||
var jointNames = getJointNames(side, finger, jointSuffixes);
|
var jointNames = getJointNames(side, finger, jointSuffixes);
|
||||||
var fingerLength = getJointDistances(jointNames).totalDistance;
|
var fingerLength = getJointDistances(jointNames).totalDistance;
|
||||||
|
|
||||||
var jointIndex = MyAvatar.getJointIndex(jointNames[0]);
|
var jointIndex = MyAvatar.getJointIndex(jointNames[0]);
|
||||||
positions[finger] = MyAvatar.jointToWorldPoint(jointOffset, jointIndex);
|
positions[finger] = MyAvatar.jointToWorldPoint(jointOffset, jointIndex);
|
||||||
directions[finger] = Vec3.normalize(Vec3.sum(positions[finger], minusWorldPosHand));
|
directions[finger] = Vec3.normalize(Vec3.sum(positions[finger], minusWorldPosHand));
|
||||||
|
@ -429,66 +424,63 @@
|
||||||
if (finger !== "thumb") {
|
if (finger !== "thumb") {
|
||||||
// finger joints have double the weight than the hand joint
|
// finger joints have double the weight than the hand joint
|
||||||
// This would better position the palm estimation
|
// This would better position the palm estimation
|
||||||
|
|
||||||
palmCenter = Vec3.sum(Vec3.multiply(fingerJointWeight, positions[finger]), palmCenter);
|
palmCenter = Vec3.sum(Vec3.multiply(fingerJointWeight, positions[finger]), palmCenter);
|
||||||
weightCount += fingerJointWeight;
|
weightCount += fingerJointWeight;
|
||||||
} else {
|
} else {
|
||||||
thumbLength = fingerLength;
|
thumbLength = fingerLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// perpendicular change direction depending on the side
|
// perpendicular change direction depending on the side
|
||||||
data.perpendicular = (side === "right") ?
|
data.perpendicular = (side === "right") ?
|
||||||
Vec3.normalize(Vec3.cross(directions.index, directions.pinky)):
|
Vec3.normalize(Vec3.cross(directions.index, directions.pinky)):
|
||||||
Vec3.normalize(Vec3.cross(directions.pinky, directions.index));
|
Vec3.normalize(Vec3.cross(directions.pinky, directions.index));
|
||||||
|
|
||||||
data.position = Vec3.multiply(1.0/weightCount, palmCenter);
|
data.position = Vec3.multiply(1.0/weightCount, palmCenter);
|
||||||
|
|
||||||
if (side === "right") {
|
if (side === "right") {
|
||||||
varsToDebug.offset = MyAvatar.worldToJointPoint(worldPosHand, jointIndexHand);
|
varsToDebug.offset = MyAvatar.worldToJointPoint(worldPosHand, jointIndexHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
var palmDistanceMultiplier = 1.55; // 1.55 based on test/error for the sphere radius that best fits the hand
|
var palmDistanceMultiplier = 1.55; // 1.55 based on test/error for the sphere radius that best fits the hand
|
||||||
data.distance = palmDistanceMultiplier*Vec3.distance(data.position, positions.index);
|
data.distance = palmDistanceMultiplier*Vec3.distance(data.position, positions.index);
|
||||||
|
|
||||||
// move back thumb ray origin
|
// move back thumb ray origin
|
||||||
var thumbBackMultiplier = 0.2;
|
var thumbBackMultiplier = 0.2;
|
||||||
data.fingers.thumb = Vec3.sum(
|
data.fingers.thumb = Vec3.sum(
|
||||||
data.fingers.thumb, Vec3.multiply( -thumbBackMultiplier * thumbLength, data.perpendicular));
|
data.fingers.thumb, Vec3.multiply( -thumbBackMultiplier * thumbLength, data.perpendicular));
|
||||||
|
|
||||||
// return getDataRelativeToHandJoint(side, data);
|
// return getDataRelativeToHandJoint(side, data);
|
||||||
dataRelativeToHandJoint(side, data, palmData[side]);
|
dataRelativeToHandJoint(side, data, palmData[side]);
|
||||||
palmData[side].set = true;
|
palmData[side].set = true;
|
||||||
// return palmData[side];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register GlobalDebugger for API Debugger
|
// Register GlobalDebugger for API Debugger
|
||||||
Script.registerValue("GlobalDebugger", varsToDebug);
|
Script.registerValue("GlobalDebugger", varsToDebug);
|
||||||
|
|
||||||
// store the rays for the fingers - only for debug purposes
|
// store the rays for the fingers - only for debug purposes
|
||||||
var fingerRays = {
|
var fingerRays = {
|
||||||
left: {
|
left: {
|
||||||
pinky: undefined,
|
pinky: undefined,
|
||||||
middle: undefined,
|
middle: undefined,
|
||||||
ring: undefined,
|
ring: undefined,
|
||||||
thumb: undefined,
|
thumb: undefined,
|
||||||
index: undefined
|
index: undefined
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
pinky: undefined,
|
pinky: undefined,
|
||||||
middle: undefined,
|
middle: undefined,
|
||||||
ring: undefined,
|
ring: undefined,
|
||||||
thumb: undefined,
|
thumb: undefined,
|
||||||
index: undefined
|
index: undefined
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create debug overlays - finger rays + palm rays + spheres
|
// Create debug overlays - finger rays + palm rays + spheres
|
||||||
|
|
||||||
var palmRay, sphereHand;
|
var palmRay, sphereHand;
|
||||||
|
|
||||||
function createDebugLines() {
|
function createDebugLines() {
|
||||||
|
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
fingerRays.left[fingerKeys[i]] = Overlays.addOverlay("line3d", {
|
fingerRays.left[fingerKeys[i]] = Overlays.addOverlay("line3d", {
|
||||||
color: { red: 0, green: 0, blue: 255 },
|
color: { red: 0, green: 0, blue: 255 },
|
||||||
|
@ -503,7 +495,7 @@
|
||||||
visible: showLines
|
visible: showLines
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
palmRay = {
|
palmRay = {
|
||||||
left: Overlays.addOverlay("line3d", {
|
left: Overlays.addOverlay("line3d", {
|
||||||
color: { red: 255, green: 0, blue: 0 },
|
color: { red: 255, green: 0, blue: 0 },
|
||||||
|
@ -520,9 +512,8 @@
|
||||||
};
|
};
|
||||||
linesCreated = true;
|
linesCreated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDebugSphere() {
|
function createDebugSphere() {
|
||||||
|
|
||||||
sphereHand = {
|
sphereHand = {
|
||||||
right: Overlays.addOverlay("sphere", {
|
right: Overlays.addOverlay("sphere", {
|
||||||
position: MyAvatar.position,
|
position: MyAvatar.position,
|
||||||
|
@ -536,10 +527,10 @@
|
||||||
scale: { x: 0.01, y: 0.01, z: 0.01 },
|
scale: { x: 0.01, y: 0.01, z: 0.01 },
|
||||||
visible: showSphere
|
visible: showSphere
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
sphereCreated = true;
|
sphereCreated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function acquireDefaultPose(side) {
|
function acquireDefaultPose(side) {
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
var finger = fingerKeys[i];
|
var finger = fingerKeys[i];
|
||||||
|
@ -553,86 +544,87 @@
|
||||||
}
|
}
|
||||||
dataDefault[side].set = true;
|
dataDefault[side].set = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rayPicks = {
|
var rayPicks = {
|
||||||
left: {
|
left: {
|
||||||
pinky: undefined,
|
pinky: undefined,
|
||||||
middle: undefined,
|
middle: undefined,
|
||||||
ring: undefined,
|
ring: undefined,
|
||||||
thumb: undefined,
|
thumb: undefined,
|
||||||
index: undefined
|
index: undefined
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
pinky: undefined,
|
pinky: undefined,
|
||||||
middle: undefined,
|
middle: undefined,
|
||||||
ring: undefined,
|
ring: undefined,
|
||||||
thumb: undefined,
|
thumb: undefined,
|
||||||
index: undefined
|
index: undefined
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var dataFailed = {
|
var dataFailed = {
|
||||||
left: {
|
left: {
|
||||||
pinky: 0,
|
pinky: 0,
|
||||||
middle: 0,
|
middle: 0,
|
||||||
ring: 0,
|
ring: 0,
|
||||||
thumb: 0,
|
thumb: 0,
|
||||||
index: 0
|
index: 0
|
||||||
},
|
},
|
||||||
right: {
|
right: {
|
||||||
pinky: 0,
|
pinky: 0,
|
||||||
middle: 0,
|
middle: 0,
|
||||||
ring: 0,
|
ring: 0,
|
||||||
thumb: 0,
|
thumb: 0,
|
||||||
index: 0
|
index: 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function clearRayPicks(side) {
|
function clearRayPicks(side) {
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
var finger = fingerKeys[i];
|
var finger = fingerKeys[i];
|
||||||
if (rayPicks[side][finger] !== undefined) {
|
if (rayPicks[side][finger] !== undefined) {
|
||||||
RayPick.removeRayPick(rayPicks[side][finger]);
|
RayPick.removeRayPick(rayPicks[side][finger]);
|
||||||
rayPicks[side][finger] = undefined;
|
rayPicks[side][finger] = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRayPicks(side) {
|
function createRayPicks(side) {
|
||||||
var data = palmData[side];
|
var data = palmData[side];
|
||||||
clearRayPicks(side);
|
clearRayPicks(side);
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
var finger = fingerKeys[i];
|
var finger = fingerKeys[i];
|
||||||
var LOOKUP_DISTANCE_MULTIPLIER = 1.5;
|
var LOOKUP_DISTANCE_MULTIPLIER = 1.5;
|
||||||
var dist = LOOKUP_DISTANCE_MULTIPLIER*data.distance;
|
var dist = LOOKUP_DISTANCE_MULTIPLIER*data.distance;
|
||||||
var checkOffset = {
|
var checkOffset = {
|
||||||
x: data.perpendicular.x * dist,
|
x: data.perpendicular.x * dist,
|
||||||
y: data.perpendicular.y * dist,
|
y: data.perpendicular.y * dist,
|
||||||
z: data.perpendicular.z * dist
|
z: data.perpendicular.z * dist
|
||||||
};
|
};
|
||||||
|
|
||||||
var checkPoint = Vec3.sum(data.position, Vec3.multiply(2, checkOffset));
|
var checkPoint = Vec3.sum(data.position, Vec3.multiply(2, checkOffset));
|
||||||
var sensorToWorldScale = MyAvatar.getSensorToWorldScale();
|
var sensorToWorldScale = MyAvatar.getSensorToWorldScale();
|
||||||
|
|
||||||
var origin = data.fingers[finger];
|
var origin = data.fingers[finger];
|
||||||
|
|
||||||
var direction = Vec3.normalize(Vec3.subtract(checkPoint, origin));
|
var direction = Vec3.normalize(Vec3.subtract(checkPoint, origin));
|
||||||
|
|
||||||
origin = Vec3.multiply(1/sensorToWorldScale, origin);
|
origin = Vec3.multiply(1/sensorToWorldScale, origin);
|
||||||
|
|
||||||
rayPicks[side][finger] = RayPick.createRayPick(
|
rayPicks[side][finger] = RayPick.createRayPick(
|
||||||
{
|
{
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"joint": handJointNames[side],
|
"joint": handJointNames[side],
|
||||||
"posOffset": origin,
|
"posOffset": origin,
|
||||||
"dirOffset": direction,
|
"dirOffset": direction,
|
||||||
"filter": RayPick.PICK_ENTITIES
|
"filter": RayPick.PICK_ENTITIES
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
RayPick.setPrecisionPicking(rayPicks[side][finger], true);
|
RayPick.setPrecisionPicking(rayPicks[side][finger], true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function activateNextRay(side, index) {
|
function activateNextRay(side, index) {
|
||||||
var nextIndex = (index < fingerKeys.length-1) ? index + 1 : 0;
|
var nextIndex = (index < fingerKeys.length-1) ? index + 1 : 0;
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
|
@ -641,46 +633,44 @@
|
||||||
RayPick.enableRayPick(rayPicks[side][finger]);
|
RayPick.enableRayPick(rayPicks[side][finger]);
|
||||||
} else {
|
} else {
|
||||||
RayPick.disableRayPick(rayPicks[side][finger]);
|
RayPick.disableRayPick(rayPicks[side][finger]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSphereHand(side) {
|
|
||||||
|
|
||||||
|
function updateSphereHand(side) {
|
||||||
var data = new Palm();
|
var data = new Palm();
|
||||||
dataRelativeToWorld(side, palmData[side], data);
|
dataRelativeToWorld(side, palmData[side], data);
|
||||||
varsToDebug.palmData[side] = palmData[side];
|
varsToDebug.palmData[side] = palmData[side];
|
||||||
|
|
||||||
var palmPoint = data.position;
|
var palmPoint = data.position;
|
||||||
var LOOKUP_DISTANCE_MULTIPLIER = 1.5;
|
var LOOKUP_DISTANCE_MULTIPLIER = 1.5;
|
||||||
var dist = LOOKUP_DISTANCE_MULTIPLIER*data.distance;
|
var dist = LOOKUP_DISTANCE_MULTIPLIER*data.distance;
|
||||||
|
|
||||||
// Situate the debugging overlays
|
// Situate the debugging overlays
|
||||||
|
var checkOffset = {
|
||||||
var checkOffset = {
|
x: data.perpendicular.x * dist,
|
||||||
x: data.perpendicular.x * dist,
|
y: data.perpendicular.y * dist,
|
||||||
y: data.perpendicular.y * dist,
|
z: data.perpendicular.z * dist
|
||||||
z: data.perpendicular.z * dist
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var spherePos = Vec3.sum(palmPoint, checkOffset);
|
var spherePos = Vec3.sum(palmPoint, checkOffset);
|
||||||
var checkPoint = Vec3.sum(palmPoint, Vec3.multiply(2, checkOffset));
|
var checkPoint = Vec3.sum(palmPoint, Vec3.multiply(2, checkOffset));
|
||||||
|
|
||||||
if (showLines) {
|
if (showLines) {
|
||||||
Overlays.editOverlay(palmRay[side], {
|
Overlays.editOverlay(palmRay[side], {
|
||||||
start: palmPoint,
|
start: palmPoint,
|
||||||
end: checkPoint,
|
end: checkPoint,
|
||||||
visible: showLines
|
visible: showLines
|
||||||
});
|
});
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
Overlays.editOverlay(fingerRays[side][fingerKeys[i]], {
|
Overlays.editOverlay(fingerRays[side][fingerKeys[i]], {
|
||||||
start: data.fingers[fingerKeys[i]],
|
start: data.fingers[fingerKeys[i]],
|
||||||
end: checkPoint,
|
end: checkPoint,
|
||||||
visible: showLines
|
visible: showLines
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showSphere) {
|
if (showSphere) {
|
||||||
Overlays.editOverlay(sphereHand[side], {
|
Overlays.editOverlay(sphereHand[side], {
|
||||||
position: spherePos,
|
position: spherePos,
|
||||||
|
@ -690,16 +680,16 @@
|
||||||
z: 2*dist
|
z: 2*dist
|
||||||
},
|
},
|
||||||
visible: showSphere
|
visible: showSphere
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the intersection of only one finger at a time
|
// Update the intersection of only one finger at a time
|
||||||
|
var finger = fingerKeys[updateFingerWithIndex];
|
||||||
var finger = fingerKeys[updateFingerWithIndex];
|
var nearbyEntities = Entities.findEntities(spherePos, dist);
|
||||||
|
// Filter the entities that are allowed to be touched
|
||||||
|
var touchableEntities = nearbyEntities.filter(function (id) {
|
||||||
var grabbables = Entities.findEntities(spherePos, dist);
|
return untouchableEntities.indexOf(id) == -1;
|
||||||
|
});
|
||||||
var intersection;
|
var intersection;
|
||||||
if (rayPicks[side][finger] !== undefined) {
|
if (rayPicks[side][finger] !== undefined) {
|
||||||
intersection = RayPick.getPrevRayPickResult(rayPicks[side][finger]);
|
intersection = RayPick.getPrevRayPickResult(rayPicks[side][finger]);
|
||||||
|
@ -708,11 +698,10 @@
|
||||||
var animationSteps = defaultAnimationSteps;
|
var animationSteps = defaultAnimationSteps;
|
||||||
var newFingerData = dataDefault[side][finger];
|
var newFingerData = dataDefault[side][finger];
|
||||||
var isAbleToGrab = false;
|
var isAbleToGrab = false;
|
||||||
if (grabbables.length > 0) {
|
if (touchableEntities.length > 0) {
|
||||||
|
RayPick.setIncludeItems(rayPicks[side][finger], touchableEntities);
|
||||||
RayPick.setIncludeItems(rayPicks[side][finger], grabbables);
|
|
||||||
|
|
||||||
if (intersection === undefined) {
|
if (intersection === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -725,28 +714,27 @@
|
||||||
// Store if this finger is touching something
|
// Store if this finger is touching something
|
||||||
isTouching[side][finger] = isAbleToGrab;
|
isTouching[side][finger] = isAbleToGrab;
|
||||||
if (isAbleToGrab) {
|
if (isAbleToGrab) {
|
||||||
// update the open/close percentage for this finger
|
// update the open/close percentage for this finger
|
||||||
|
|
||||||
var FINGER_REACT_MULTIPLIER = 2.8;
|
var FINGER_REACT_MULTIPLIER = 2.8;
|
||||||
|
|
||||||
percent = intersection.distance/(FINGER_REACT_MULTIPLIER*dist);
|
percent = intersection.distance/(FINGER_REACT_MULTIPLIER*dist);
|
||||||
|
|
||||||
var THUMB_FACTOR = 0.2;
|
var THUMB_FACTOR = 0.2;
|
||||||
var FINGER_FACTOR = 0.05;
|
var FINGER_FACTOR = 0.05;
|
||||||
|
|
||||||
// Amount of grab coefficient added to the fingers - thumb is higher
|
// Amount of grab coefficient added to the fingers - thumb is higher
|
||||||
var grabMultiplier = finger === "thumb" ? THUMB_FACTOR : FINGER_FACTOR;
|
var grabMultiplier = finger === "thumb" ? THUMB_FACTOR : FINGER_FACTOR;
|
||||||
percent += grabMultiplier * grabPercent[side];
|
percent += grabMultiplier * grabPercent[side];
|
||||||
|
|
||||||
// Calculate new interpolation data
|
// Calculate new interpolation data
|
||||||
var totalDistance = addVals(dataClose[side][finger], dataOpen[side][finger], -1);
|
var totalDistance = addVals(dataClose[side][finger], dataOpen[side][finger], -1);
|
||||||
// Assign close/open ratio to finger to simulate touch
|
// Assign close/open ratio to finger to simulate touch
|
||||||
newFingerData = addVals(dataOpen[side][finger], multiplyValsBy(totalDistance, percent), 1);
|
newFingerData = addVals(dataOpen[side][finger], multiplyValsBy(totalDistance, percent), 1);
|
||||||
animationSteps = touchAnimationSteps;
|
animationSteps = touchAnimationSteps;
|
||||||
}
|
}
|
||||||
varsToDebug.fingerPercent[side][finger] = percent;
|
varsToDebug.fingerPercent[side][finger] = percent;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!isAbleToGrab) {
|
if (!isAbleToGrab) {
|
||||||
dataFailed[side][finger] = dataFailed[side][finger] === 0 ? 1 : 2;
|
dataFailed[side][finger] = dataFailed[side][finger] === 0 ? 1 : 2;
|
||||||
} else {
|
} else {
|
||||||
|
@ -755,13 +743,12 @@
|
||||||
// If it only fails once it will not update increments
|
// If it only fails once it will not update increments
|
||||||
if (dataFailed[side][finger] !== 1) {
|
if (dataFailed[side][finger] !== 1) {
|
||||||
// Calculate animation increments
|
// Calculate animation increments
|
||||||
dataDelta[side][finger] =
|
dataDelta[side][finger] =
|
||||||
multiplyValsBy(addVals(newFingerData, dataCurrent[side][finger], -1), 1.0/animationSteps);
|
multiplyValsBy(addVals(newFingerData, dataCurrent[side][finger], -1), 1.0/animationSteps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recreate the finger joint names
|
// Recreate the finger joint names
|
||||||
|
|
||||||
function getJointNames(side, finger, count) {
|
function getJointNames(side, finger, count) {
|
||||||
var names = [];
|
var names = [];
|
||||||
for (var i = 1; i < count+1; i++) {
|
for (var i = 1; i < count+1; i++) {
|
||||||
|
@ -772,30 +759,34 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capture the controller values
|
// Capture the controller values
|
||||||
|
|
||||||
var leftTriggerPress = function (value) {
|
var leftTriggerPress = function (value) {
|
||||||
varsToDebug.triggerValues.leftTriggerValue = value;
|
varsToDebug.triggerValues.leftTriggerValue = value;
|
||||||
// the value for the trigger increments the hand-close percentage
|
// the value for the trigger increments the hand-close percentage
|
||||||
grabPercent.left = value;
|
grabPercent.left = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
var leftTriggerClick = function (value) {
|
var leftTriggerClick = function (value) {
|
||||||
varsToDebug.triggerValues.leftTriggerClicked = value;
|
varsToDebug.triggerValues.leftTriggerClicked = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
var rightTriggerPress = function (value) {
|
var rightTriggerPress = function (value) {
|
||||||
varsToDebug.triggerValues.rightTriggerValue = value;
|
varsToDebug.triggerValues.rightTriggerValue = value;
|
||||||
// the value for the trigger increments the hand-close percentage
|
// the value for the trigger increments the hand-close percentage
|
||||||
grabPercent.right = value;
|
grabPercent.right = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
var rightTriggerClick = function (value) {
|
var rightTriggerClick = function (value) {
|
||||||
varsToDebug.triggerValues.rightTriggerClicked = value;
|
varsToDebug.triggerValues.rightTriggerClicked = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
var leftSecondaryPress = function (value) {
|
var leftSecondaryPress = function (value) {
|
||||||
varsToDebug.triggerValues.leftSecondaryValue = value;
|
varsToDebug.triggerValues.leftSecondaryValue = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
var rightSecondaryPress = function (value) {
|
var rightSecondaryPress = function (value) {
|
||||||
varsToDebug.triggerValues.rightSecondaryValue = value;
|
varsToDebug.triggerValues.rightSecondaryValue = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
var MAPPING_NAME = "com.highfidelity.handTouch";
|
var MAPPING_NAME = "com.highfidelity.handTouch";
|
||||||
var mapping = Controller.newMapping(MAPPING_NAME);
|
var mapping = Controller.newMapping(MAPPING_NAME);
|
||||||
mapping.from([Controller.Standard.RT]).peek().to(rightTriggerPress);
|
mapping.from([Controller.Standard.RT]).peek().to(rightTriggerPress);
|
||||||
|
@ -809,16 +800,17 @@
|
||||||
mapping.from([Controller.Standard.RightGrip]).peek().to(rightSecondaryPress);
|
mapping.from([Controller.Standard.RightGrip]).peek().to(rightSecondaryPress);
|
||||||
|
|
||||||
Controller.enableMapping(MAPPING_NAME);
|
Controller.enableMapping(MAPPING_NAME);
|
||||||
|
|
||||||
if (showLines && !linesCreated) {
|
if (showLines && !linesCreated) {
|
||||||
createDebugLines();
|
createDebugLines();
|
||||||
linesCreated = true;
|
linesCreated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showSphere && !sphereCreated) {
|
if (showSphere && !sphereCreated) {
|
||||||
createDebugSphere();
|
createDebugSphere();
|
||||||
sphereCreated = true;
|
sphereCreated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTouching(side) {
|
function getTouching(side) {
|
||||||
var animating = false;
|
var animating = false;
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
|
@ -827,19 +819,70 @@
|
||||||
}
|
}
|
||||||
return animating; // return false only if none of the fingers are touching
|
return animating; // return false only if none of the fingers are touching
|
||||||
}
|
}
|
||||||
|
|
||||||
function reEstimatePalmData() {
|
function reEstimatePalmData() {
|
||||||
["right", "left"].forEach(function(side) {
|
["right", "left"].forEach(function(side) {
|
||||||
estimatePalmData(side);
|
estimatePalmData(side);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function recreateRayPicks() {
|
function recreateRayPicks() {
|
||||||
["right", "left"].forEach(function(side) {
|
["right", "left"].forEach(function(side) {
|
||||||
createRayPicks(side);
|
createRayPicks(side);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanUp() {
|
||||||
|
["right", "left"].forEach(function (side) {
|
||||||
|
if (linesCreated) {
|
||||||
|
Overlays.deleteOverlay(palmRay[side]);
|
||||||
|
}
|
||||||
|
if (sphereCreated) {
|
||||||
|
Overlays.deleteOverlay(sphereHand[side]);
|
||||||
|
}
|
||||||
|
clearRayPicks(side);
|
||||||
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
|
var finger = fingerKeys[i];
|
||||||
|
var jointSuffixes = 3; // We need to clear the joints 0, 1 and 2 joints
|
||||||
|
var names = getJointNames(side, finger, jointSuffixes);
|
||||||
|
for (var j = 0; j < names.length; j++) {
|
||||||
|
var index = MyAvatar.getJointIndex(names[j]);
|
||||||
|
MyAvatar.clearJointData(index);
|
||||||
|
}
|
||||||
|
if (linesCreated) {
|
||||||
|
Overlays.deleteOverlay(fingerRays[side][finger]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
MyAvatar.shouldDisableHandTouchChanged.connect(function (shouldDisable) {
|
||||||
|
if (shouldDisable) {
|
||||||
|
if (handTouchEnabled) {
|
||||||
|
cleanUp();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!handTouchEnabled) {
|
||||||
|
reEstimatePalmData();
|
||||||
|
recreateRayPicks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handTouchEnabled = !shouldDisable;
|
||||||
|
});
|
||||||
|
|
||||||
|
MyAvatar.disableHandTouchForIDChanged.connect(function (entityID, disable) {
|
||||||
|
var entityIndex = untouchableEntities.indexOf(entityID);
|
||||||
|
if (disable) {
|
||||||
|
if (entityIndex == -1) {
|
||||||
|
untouchableEntities.push(entityID);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (entityIndex != -1) {
|
||||||
|
untouchableEntities.splice(entityIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
MyAvatar.onLoadComplete.connect(function () {
|
MyAvatar.onLoadComplete.connect(function () {
|
||||||
// Sometimes the rig is not ready when this signal is trigger
|
// Sometimes the rig is not ready when this signal is trigger
|
||||||
console.log("avatar loaded");
|
console.log("avatar loaded");
|
||||||
|
@ -848,78 +891,55 @@
|
||||||
recreateRayPicks();
|
recreateRayPicks();
|
||||||
}, MSECONDS_AFTER_LOAD);
|
}, MSECONDS_AFTER_LOAD);
|
||||||
});
|
});
|
||||||
|
|
||||||
MyAvatar.sensorToWorldScaleChanged.connect(function() {
|
MyAvatar.sensorToWorldScaleChanged.connect(function() {
|
||||||
reEstimatePalmData();
|
reEstimatePalmData();
|
||||||
});
|
});
|
||||||
|
|
||||||
Script.scriptEnding.connect(function () {
|
|
||||||
["right", "left"].forEach(function(side) {
|
|
||||||
if (linesCreated) {
|
|
||||||
Overlays.deleteOverlay(palmRay[side]);
|
|
||||||
}
|
|
||||||
if (sphereCreated) {
|
|
||||||
Overlays.deleteOverlay(sphereHand[side]);
|
|
||||||
}
|
|
||||||
clearRayPicks(side);
|
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
|
||||||
|
|
||||||
var finger = fingerKeys[i];
|
Script.scriptEnding.connect(function () {
|
||||||
var jointSuffixes = 3; // We need to clear the joints 0, 1 and 2 joints
|
cleanUp();
|
||||||
var names = getJointNames(side, finger, jointSuffixes);
|
|
||||||
|
|
||||||
for (var j = 0; j < names.length; j++) {
|
|
||||||
var index = MyAvatar.getJointIndex(names[j]);
|
|
||||||
MyAvatar.clearJointData(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (linesCreated) {
|
|
||||||
Overlays.deleteOverlay(fingerRays[side][finger]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Script.update.connect(function() {
|
Script.update.connect(function () {
|
||||||
|
|
||||||
|
if (!handTouchEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// index of the finger that needs to be updated this frame
|
// index of the finger that needs to be updated this frame
|
||||||
|
|
||||||
updateFingerWithIndex = (updateFingerWithIndex < fingerKeys.length-1) ? updateFingerWithIndex + 1 : 0;
|
updateFingerWithIndex = (updateFingerWithIndex < fingerKeys.length-1) ? updateFingerWithIndex + 1 : 0;
|
||||||
|
|
||||||
["right", "left"].forEach(function(side) {
|
["right", "left"].forEach(function(side) {
|
||||||
|
|
||||||
if (!palmData[side].set) {
|
if (!palmData[side].set) {
|
||||||
reEstimatePalmData();
|
reEstimatePalmData();
|
||||||
recreateRayPicks();
|
recreateRayPicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
// recalculate the base data
|
// recalculate the base data
|
||||||
updateSphereHand(side);
|
updateSphereHand(side);
|
||||||
activateNextRay(side, updateFingerWithIndex);
|
activateNextRay(side, updateFingerWithIndex);
|
||||||
|
|
||||||
// this vars manage the transition to default pose
|
// this vars manage the transition to default pose
|
||||||
var isHandTouching = getTouching(side);
|
var isHandTouching = getTouching(side);
|
||||||
countToDefault[side] = isHandTouching ? 0 : countToDefault[side] + 1;
|
countToDefault[side] = isHandTouching ? 0 : countToDefault[side] + 1;
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0; i < fingerKeys.length; i++) {
|
for (var i = 0; i < fingerKeys.length; i++) {
|
||||||
var finger = fingerKeys[i];
|
var finger = fingerKeys[i];
|
||||||
var jointSuffixes = 3; // We need to update rotation of the 0, 1 and 2 joints
|
var jointSuffixes = 3; // We need to update rotation of the 0, 1 and 2 joints
|
||||||
var names = getJointNames(side, finger, jointSuffixes);
|
var names = getJointNames(side, finger, jointSuffixes);
|
||||||
|
|
||||||
// Add the animation increments
|
// Add the animation increments
|
||||||
|
dataCurrent[side][finger] = addVals(dataCurrent[side][finger], dataDelta[side][finger], 1);
|
||||||
dataCurrent[side][finger] = addVals(dataCurrent[side][finger], dataDelta[side][finger], 1);
|
|
||||||
|
|
||||||
// update every finger joint
|
// update every finger joint
|
||||||
|
|
||||||
for (var j = 0; j < names.length; j++) {
|
for (var j = 0; j < names.length; j++) {
|
||||||
var index = MyAvatar.getJointIndex(names[j]);
|
var index = MyAvatar.getJointIndex(names[j]);
|
||||||
// if no finger is touching restate the default poses
|
// if no finger is touching restate the default poses
|
||||||
if (isHandTouching || (dataDefault[side].set &&
|
if (isHandTouching || (dataDefault[side].set &&
|
||||||
countToDefault[side] < fingerKeys.length*touchAnimationSteps)) {
|
countToDefault[side] < fingerKeys.length*touchAnimationSteps)) {
|
||||||
var quatRot = dataCurrent[side][finger][j];
|
var quatRot = dataCurrent[side][finger][j];
|
||||||
MyAvatar.setJointRotation(index, quatRot);
|
MyAvatar.setJointRotation(index, quatRot);
|
||||||
} else {
|
} else {
|
||||||
MyAvatar.clearJointData(index);
|
MyAvatar.clearJointData(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,15 @@ var createToolsWindow = new CreateWindow(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Returns true in case we should use the tablet version of the CreateApp
|
||||||
|
* @returns boolean
|
||||||
|
*/
|
||||||
|
var shouldUseEditTabletApp = function() {
|
||||||
|
return HMD.active || (!HMD.active && !Settings.getValue("desktopTabletBecomesToolbar", true));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var selectionDisplay = SelectionDisplay;
|
var selectionDisplay = SelectionDisplay;
|
||||||
var selectionManager = SelectionManager;
|
var selectionManager = SelectionManager;
|
||||||
|
|
||||||
|
@ -88,11 +97,12 @@ var cameraManager = new CameraManager();
|
||||||
var grid = new Grid();
|
var grid = new Grid();
|
||||||
var gridTool = new GridTool({
|
var gridTool = new GridTool({
|
||||||
horizontalGrid: grid,
|
horizontalGrid: grid,
|
||||||
createToolsWindow: createToolsWindow
|
createToolsWindow: createToolsWindow,
|
||||||
|
shouldUseEditTabletApp: shouldUseEditTabletApp
|
||||||
});
|
});
|
||||||
gridTool.setVisible(false);
|
gridTool.setVisible(false);
|
||||||
|
|
||||||
var entityListTool = new EntityListTool();
|
var entityListTool = new EntityListTool(shouldUseEditTabletApp);
|
||||||
|
|
||||||
selectionManager.addEventListener(function () {
|
selectionManager.addEventListener(function () {
|
||||||
selectionDisplay.updateHandles();
|
selectionDisplay.updateHandles();
|
||||||
|
@ -578,7 +588,8 @@ var toolBar = (function () {
|
||||||
});
|
});
|
||||||
createButton = activeButton;
|
createButton = activeButton;
|
||||||
tablet.screenChanged.connect(function (type, url) {
|
tablet.screenChanged.connect(function (type, url) {
|
||||||
var isGoingToHomescreenOnDesktop = (!HMD.active && (url === 'hifi/tablet/TabletHome.qml' || url === ''));
|
var isGoingToHomescreenOnDesktop = (!shouldUseEditTabletApp() &&
|
||||||
|
(url === 'hifi/tablet/TabletHome.qml' || url === ''));
|
||||||
if (isActive && (type !== "QML" || url !== "hifi/tablet/Edit.qml") && !isGoingToHomescreenOnDesktop) {
|
if (isActive && (type !== "QML" || url !== "hifi/tablet/Edit.qml") && !isGoingToHomescreenOnDesktop) {
|
||||||
that.setActive(false);
|
that.setActive(false);
|
||||||
}
|
}
|
||||||
|
@ -605,7 +616,7 @@ var toolBar = (function () {
|
||||||
});
|
});
|
||||||
function createNewEntityDialogButtonCallback(entityType) {
|
function createNewEntityDialogButtonCallback(entityType) {
|
||||||
return function() {
|
return function() {
|
||||||
if (HMD.active) {
|
if (shouldUseEditTabletApp()) {
|
||||||
// tablet version of new-model dialog
|
// tablet version of new-model dialog
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
tablet.pushOntoStack("hifi/tablet/New" + entityType + "Dialog.qml");
|
tablet.pushOntoStack("hifi/tablet/New" + entityType + "Dialog.qml");
|
||||||
|
@ -837,7 +848,7 @@ var toolBar = (function () {
|
||||||
selectionDisplay.triggerMapping.disable();
|
selectionDisplay.triggerMapping.disable();
|
||||||
tablet.landscape = false;
|
tablet.landscape = false;
|
||||||
} else {
|
} else {
|
||||||
if (HMD.active) {
|
if (shouldUseEditTabletApp()) {
|
||||||
tablet.loadQMLSource("hifi/tablet/Edit.qml", true);
|
tablet.loadQMLSource("hifi/tablet/Edit.qml", true);
|
||||||
} else {
|
} else {
|
||||||
// make other apps inactive while in desktop mode
|
// make other apps inactive while in desktop mode
|
||||||
|
@ -1989,8 +2000,8 @@ var PropertiesTool = function (opts) {
|
||||||
|
|
||||||
that.setVisible = function (newVisible) {
|
that.setVisible = function (newVisible) {
|
||||||
visible = newVisible;
|
visible = newVisible;
|
||||||
webView.setVisible(HMD.active && visible);
|
webView.setVisible(shouldUseEditTabletApp() && visible);
|
||||||
createToolsWindow.setVisible(!HMD.active && visible);
|
createToolsWindow.setVisible(!shouldUseEditTabletApp() && visible);
|
||||||
};
|
};
|
||||||
|
|
||||||
that.setVisible(false);
|
that.setVisible(false);
|
||||||
|
@ -2416,7 +2427,7 @@ function selectParticleEntity(entityID) {
|
||||||
|
|
||||||
// Switch to particle explorer
|
// Switch to particle explorer
|
||||||
var selectTabMethod = { method: 'selectTab', params: { id: 'particle' } };
|
var selectTabMethod = { method: 'selectTab', params: { id: 'particle' } };
|
||||||
if (HMD.active) {
|
if (shouldUseEditTabletApp()) {
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
tablet.sendToQml(selectTabMethod);
|
tablet.sendToQml(selectTabMethod);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
/* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages,
|
/* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages,
|
||||||
cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible */
|
cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible */
|
||||||
|
|
||||||
EntityListTool = function() {
|
EntityListTool = function(shouldUseEditTabletApp) {
|
||||||
var that = {};
|
var that = {};
|
||||||
|
|
||||||
var CreateWindow = Script.require('../modules/createWindow.js');
|
var CreateWindow = Script.require('../modules/createWindow.js');
|
||||||
|
@ -55,8 +55,8 @@ EntityListTool = function() {
|
||||||
|
|
||||||
that.setVisible = function(newVisible) {
|
that.setVisible = function(newVisible) {
|
||||||
visible = newVisible;
|
visible = newVisible;
|
||||||
webView.setVisible(HMD.active && visible);
|
webView.setVisible(shouldUseEditTabletApp() && visible);
|
||||||
entityListWindow.setVisible(!HMD.active && visible);
|
entityListWindow.setVisible(!shouldUseEditTabletApp() && visible);
|
||||||
};
|
};
|
||||||
|
|
||||||
that.setVisible(false);
|
that.setVisible(false);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var GRID_CONTROLS_HTML_URL = Script.resolvePath('../html/gridControls.html');
|
var GRID_CONTROLS_HTML_URL = Script.resolvePath('../html/gridControls.html');
|
||||||
|
|
||||||
Grid = function(opts) {
|
Grid = function() {
|
||||||
var that = {};
|
var that = {};
|
||||||
var gridColor = { red: 0, green: 0, blue: 0 };
|
var gridColor = { red: 0, green: 0, blue: 0 };
|
||||||
var gridAlpha = 0.6;
|
var gridAlpha = 0.6;
|
||||||
|
@ -247,6 +247,7 @@ GridTool = function(opts) {
|
||||||
var horizontalGrid = opts.horizontalGrid;
|
var horizontalGrid = opts.horizontalGrid;
|
||||||
var verticalGrid = opts.verticalGrid;
|
var verticalGrid = opts.verticalGrid;
|
||||||
var createToolsWindow = opts.createToolsWindow;
|
var createToolsWindow = opts.createToolsWindow;
|
||||||
|
var shouldUseEditTabletApp = opts.shouldUseEditTabletApp;
|
||||||
var listeners = [];
|
var listeners = [];
|
||||||
|
|
||||||
var webView = null;
|
var webView = null;
|
||||||
|
@ -299,7 +300,7 @@ GridTool = function(opts) {
|
||||||
};
|
};
|
||||||
|
|
||||||
that.setVisible = function(visible) {
|
that.setVisible = function(visible) {
|
||||||
webView.setVisible(HMD.active && visible);
|
webView.setVisible(shouldUseEditTabletApp() && visible);
|
||||||
};
|
};
|
||||||
|
|
||||||
return that;
|
return that;
|
||||||
|
|
Loading…
Reference in a new issue