//// ScriptValueUtils.cpp// libraries/shared/src//// Created by Anthony Thibault on 4/15/16.// Copyright 2016 High Fidelity, Inc.// Copyright 2022 Overte e.V.//// Utilities for working with QtScriptValues//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html// #include "ScriptValueUtils.h" #include <QtCore/QVariant>#include <QtGui/QColor>#include <QtCore/QRect>#include <QtCore/QUrl>#include <QtCore/QUuid> #include <AACube.h>#include <shared/MiniPromises.h>#include <RegisteredMetaTypes.h>#include <EntityItemID.h> #include "ScriptEngine.h"#include "ScriptEngineCast.h"#include "ScriptValueIterator.h" bool isListOfStrings(const ScriptValue& arg) { if (!arg.isArray()) { return false; } auto lengthProperty = arg.property("length"); if (!lengthProperty.isNumber()) { return false; } int length = lengthProperty.toInt32(); for (int i = 0; i < length; i++) { if (!arg.property(i).isString()) { return false; } } return true;} void registerMetaTypes(ScriptEngine* engine) { scriptRegisterMetaType<glm::vec2, vec2ToScriptValue, vec2FromScriptValue>(engine); scriptRegisterMetaType<glm::vec3, vec3ToScriptValue, vec3FromScriptValue>(engine); scriptRegisterMetaType<glm::u8vec3, u8vec3ToScriptValue, u8vec3FromScriptValue>(engine); scriptRegisterMetaType<glm::vec4, vec4toScriptValue, vec4FromScriptValue>(engine); scriptRegisterMetaType<glm::quat, quatToScriptValue, quatFromScriptValue>(engine); scriptRegisterMetaType<glm::mat4, mat4toScriptValue, mat4FromScriptValue>(engine); scriptRegisterMetaType<QVector< glm::vec3 >, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue>(engine); scriptRegisterMetaType<QVector< glm::quat >, qVectorQuatToScriptValue, qVectorQuatFromScriptValue>(engine); scriptRegisterMetaType<QVector< bool >, qVectorBoolToScriptValue, qVectorBoolFromScriptValue>(engine); scriptRegisterMetaType<QVector< float >, qVectorFloatToScriptValue, qVectorFloatFromScriptValue>(engine); scriptRegisterMetaType<QVector< uint32_t >, qVectorIntToScriptValue, qVectorIntFromScriptValue>(engine); scriptRegisterMetaType<QVector< QUuid >, qVectorQUuidToScriptValue, qVectorQUuidFromScriptValue>(engine); scriptRegisterMetaType<QSizeF, qSizeFToScriptValue, qSizeFFromScriptValue>(engine); scriptRegisterMetaType<QRect, qRectToScriptValue, qRectFromScriptValue>(engine); scriptRegisterMetaType<QUrl, qURLToScriptValue, qURLFromScriptValue>(engine); scriptRegisterMetaType<QColor, qColorToScriptValue, qColorFromScriptValue>(engine); scriptRegisterMetaType<PickRay, pickRayToScriptValue, pickRayFromScriptValue>(engine); scriptRegisterMetaType<Collision, collisionToScriptValue, collisionFromScriptValue>(engine); scriptRegisterMetaType<QUuid, quuidToScriptValue, quuidFromScriptValue>(engine); scriptRegisterMetaType<AACube, aaCubeToScriptValue, aaCubeFromScriptValue>(engine); scriptRegisterMetaType<StencilMaskMode, stencilMaskModeToScriptValue, stencilMaskModeFromScriptValue>(engine); scriptRegisterMetaType<std::shared_ptr< MiniPromise >, promiseToScriptValue, promiseFromScriptValue>(engine); scriptRegisterSequenceMetaType<QVector<unsigned int> >(engine);} ScriptValue vec2ToScriptValue(ScriptEngine* engine, const glm::vec2& vec2) { auto prototype = engine->globalObject().property("__hifi_vec2__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_vec2__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "u: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "v: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("x", vec2.x); value.setProperty("y", vec2.y); value.setPrototype(prototype); return value;} bool vec2FromScriptValue(const ScriptValue& object, glm::vec2& vec2) { if (object.isNumber()) { vec2 = glm::vec2(object.toVariant().toFloat()); } else if (object.isArray()) { QVariantList list = object.toVariant().toList(); if (list.length() == 2) { vec2.x = list[0].toFloat(); vec2.y = list[1].toFloat(); } } else { ScriptValue x = object.property("x"); if (!x.isValid()) { x = object.property("u"); } ScriptValue y = object.property("y"); if (!y.isValid()) { y = object.property("v"); } vec2.x = x.toVariant().toFloat(); vec2.y = y.toVariant().toFloat(); } return true;} ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_vec3__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_vec3__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "2: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," "r: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "g: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "b: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," "red: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("x", vec3.x); value.setProperty("y", vec3.y); value.setProperty("z", vec3.z); value.setPrototype(prototype); return value;} ScriptValue vec3ColorToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_vec3_color__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_vec3_color__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "1: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "2: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," "r: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "g: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "b: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," "x: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "y: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "z: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("red", vec3.x); value.setProperty("green", vec3.y); value.setProperty("blue", vec3.z); value.setPrototype(prototype); return value;} bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) { if (object.isNumber()) { vec3 = glm::vec3(object.toVariant().toFloat()); } else if (object.isString()) { QColor qColor(object.toString()); if (qColor.isValid()) { vec3.x = qColor.red(); vec3.y = qColor.green(); vec3.z = qColor.blue(); } } else if (object.isArray()) { QVariantList list = object.toVariant().toList(); if (list.length() == 3) { vec3.x = list[0].toFloat(); vec3.y = list[1].toFloat(); vec3.z = list[2].toFloat(); } } else { ScriptValue x = object.property("x"); if (!x.isValid()) { x = object.property("r"); } if (!x.isValid()) { x = object.property("red"); } ScriptValue y = object.property("y"); if (!y.isValid()) { y = object.property("g"); } if (!y.isValid()) { y = object.property("green"); } ScriptValue z = object.property("z"); if (!z.isValid()) { z = object.property("b"); } if (!z.isValid()) { z = object.property("blue"); } vec3.x = x.toVariant().toFloat(); vec3.y = y.toVariant().toFloat(); vec3.z = z.toVariant().toFloat(); } return true;} ScriptValue u8vec3ToScriptValue(ScriptEngine* engine, const glm::u8vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_u8vec3__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_u8vec3__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "2: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," "r: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "g: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "b: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," "red: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("x", vec3.x); value.setProperty("y", vec3.y); value.setProperty("z", vec3.z); value.setPrototype(prototype); return value;} ScriptValue u8vec3ColorToScriptValue(ScriptEngine* engine, const glm::u8vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_u8vec3_color__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_u8vec3_color__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "1: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "2: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," "r: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "g: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "b: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," "x: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "y: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "z: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("red", vec3.x); value.setProperty("green", vec3.y); value.setProperty("blue", vec3.z); value.setPrototype(prototype); return value;} bool u8vec3FromScriptValue(const ScriptValue& object, glm::u8vec3& vec3) { if (object.isNumber()) { vec3 = glm::vec3(object.toVariant().toUInt()); } else if (object.isString()) { QColor qColor(object.toString()); if (qColor.isValid()) { vec3.x = (uint8_t)qColor.red(); vec3.y = (uint8_t)qColor.green(); vec3.z = (uint8_t)qColor.blue(); } } else if (object.isArray()) { QVariantList list = object.toVariant().toList(); if (list.length() == 3) { vec3.x = list[0].toUInt(); vec3.y = list[1].toUInt(); vec3.z = list[2].toUInt(); } } else { ScriptValue x = object.property("x"); if (!x.isValid()) { x = object.property("r"); } if (!x.isValid()) { x = object.property("red"); } ScriptValue y = object.property("y"); if (!y.isValid()) { y = object.property("g"); } if (!y.isValid()) { y = object.property("green"); } ScriptValue z = object.property("z"); if (!z.isValid()) { z = object.property("b"); } if (!z.isValid()) { z = object.property("blue"); } vec3.x = x.toVariant().toUInt(); vec3.y = y.toVariant().toUInt(); vec3.z = z.toVariant().toUInt(); } return true;} ScriptValue vec4toScriptValue(ScriptEngine* engine, const glm::vec4& vec4) { ScriptValue obj = engine->newObject(); obj.setProperty("x", vec4.x); obj.setProperty("y", vec4.y); obj.setProperty("z", vec4.z); obj.setProperty("w", vec4.w); return obj;} bool vec4FromScriptValue(const ScriptValue& object, glm::vec4& vec4) { vec4.x = object.property("x").toVariant().toFloat(); vec4.y = object.property("y").toVariant().toFloat(); vec4.z = object.property("z").toVariant().toFloat(); vec4.w = object.property("w").toVariant().toFloat(); return true;} ScriptValue mat4toScriptValue(ScriptEngine* engine, const glm::mat4& mat4) { ScriptValue obj = engine->newObject(); obj.setProperty("r0c0", mat4[0][0]); obj.setProperty("r1c0", mat4[0][1]); obj.setProperty("r2c0", mat4[0][2]); obj.setProperty("r3c0", mat4[0][3]); obj.setProperty("r0c1", mat4[1][0]); obj.setProperty("r1c1", mat4[1][1]); obj.setProperty("r2c1", mat4[1][2]); obj.setProperty("r3c1", mat4[1][3]); obj.setProperty("r0c2", mat4[2][0]); obj.setProperty("r1c2", mat4[2][1]); obj.setProperty("r2c2", mat4[2][2]); obj.setProperty("r3c2", mat4[2][3]); obj.setProperty("r0c3", mat4[3][0]); obj.setProperty("r1c3", mat4[3][1]); obj.setProperty("r2c3", mat4[3][2]); obj.setProperty("r3c3", mat4[3][3]); return obj;} bool mat4FromScriptValue(const ScriptValue& object, glm::mat4& mat4) { mat4[0][0] = object.property("r0c0").toVariant().toFloat(); mat4[0][1] = object.property("r1c0").toVariant().toFloat(); mat4[0][2] = object.property("r2c0").toVariant().toFloat(); mat4[0][3] = object.property("r3c0").toVariant().toFloat(); mat4[1][0] = object.property("r0c1").toVariant().toFloat(); mat4[1][1] = object.property("r1c1").toVariant().toFloat(); mat4[1][2] = object.property("r2c1").toVariant().toFloat(); mat4[1][3] = object.property("r3c1").toVariant().toFloat(); mat4[2][0] = object.property("r0c2").toVariant().toFloat(); mat4[2][1] = object.property("r1c2").toVariant().toFloat(); mat4[2][2] = object.property("r2c2").toVariant().toFloat(); mat4[2][3] = object.property("r3c2").toVariant().toFloat(); mat4[3][0] = object.property("r0c3").toVariant().toFloat(); mat4[3][1] = object.property("r1c3").toVariant().toFloat(); mat4[3][2] = object.property("r2c3").toVariant().toFloat(); mat4[3][3] = object.property("r3c3").toVariant().toFloat(); return true;} ScriptValue qVectorVec3ColorToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, vec3ColorToScriptValue(engine, vector.at(i))); } return array;} ScriptValue qVectorVec3ToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, vec3ToScriptValue(engine, vector.at(i))); } return array;} QVector<glm::vec3> qVectorVec3FromScriptValue(const ScriptValue& array) { QVector<glm::vec3> newVector; int length = array.property("length").toInteger(); for (int i = 0; i < length; i++) { glm::vec3 newVec3 = glm::vec3(); vec3FromScriptValue(array.property(i), newVec3); newVector << newVec3; } return newVector;} bool qVectorVec3FromScriptValue(const ScriptValue& array, QVector<glm::vec3>& vector) { int length = array.property("length").toInteger(); for (int i = 0; i < length; i++) { glm::vec3 newVec3 = glm::vec3(); vec3FromScriptValue(array.property(i), newVec3); vector << newVec3; } return true;} ScriptValue quatToScriptValue(ScriptEngine* engine, const glm::quat& quat) { ScriptValue obj = engine->newObject(); if (quat.x != quat.x || quat.y != quat.y || quat.z != quat.z || quat.w != quat.w) { // if quat contains a NaN don't try to convert it return obj; } obj.setProperty("x", quat.x); obj.setProperty("y", quat.y); obj.setProperty("z", quat.z); obj.setProperty("w", quat.w); return obj;} bool quatFromScriptValue(const ScriptValue& object, glm::quat& quat) { quat.x = object.property("x").toVariant().toFloat(); quat.y = object.property("y").toVariant().toFloat(); quat.z = object.property("z").toVariant().toFloat(); quat.w = object.property("w").toVariant().toFloat(); // enforce normalized quaternion float length = glm::length(quat); if (length > FLT_EPSILON) { quat /= length; } else { quat = glm::quat(); } return true;} ScriptValue qVectorQuatToScriptValue(ScriptEngine* engine, const QVector<glm::quat>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, quatToScriptValue(engine, vector.at(i))); } return array;} ScriptValue qVectorBoolToScriptValue(ScriptEngine* engine, const QVector<bool>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, vector.at(i)); } return array;} QVector<float> qVectorFloatFromScriptValue(const ScriptValue& array) { if (!array.isArray()) { return QVector<float>(); } QVector<float> newVector; int length = array.property("length").toInteger(); newVector.reserve(length); for (int i = 0; i < length; i++) { if (array.property(i).isNumber()) { newVector << array.property(i).toNumber(); } } return newVector;} ScriptValue qVectorQUuidToScriptValue(ScriptEngine* engine, const QVector<QUuid>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, quuidToScriptValue(engine, vector.at(i))); } return array;} bool qVectorQUuidFromScriptValue(const ScriptValue& array, QVector<QUuid>& vector) { int length = array.property("length").toInteger(); for (int i = 0; i < length; i++) { vector << array.property(i).toVariant().toUuid(); } return true;}Lines 1–500 of 939. Load more
// // ScriptValueUtils.cpp // libraries/shared/src // // Created by Anthony Thibault on 4/15/16. // Copyright 2016 High Fidelity, Inc. // Copyright 2022 Overte e.V. // // Utilities for working with QtScriptValues // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "ScriptValueUtils.h" #include <QtCore/QVariant> #include <QtGui/QColor> #include <QtCore/QRect> #include <QtCore/QUrl> #include <QtCore/QUuid> #include <AACube.h> #include <shared/MiniPromises.h> #include <RegisteredMetaTypes.h> #include <EntityItemID.h> #include "ScriptEngine.h" #include "ScriptEngineCast.h" #include "ScriptValueIterator.h" bool isListOfStrings(const ScriptValue& arg) { if (!arg.isArray()) { return false; } auto lengthProperty = arg.property("length"); if (!lengthProperty.isNumber()) { return false; } int length = lengthProperty.toInt32(); for (int i = 0; i < length; i++) { if (!arg.property(i).isString()) { return false; } } return true; } void registerMetaTypes(ScriptEngine* engine) { scriptRegisterMetaType<glm::vec2, vec2ToScriptValue, vec2FromScriptValue>(engine); scriptRegisterMetaType<glm::vec3, vec3ToScriptValue, vec3FromScriptValue>(engine); scriptRegisterMetaType<glm::u8vec3, u8vec3ToScriptValue, u8vec3FromScriptValue>(engine); scriptRegisterMetaType<glm::vec4, vec4toScriptValue, vec4FromScriptValue>(engine); scriptRegisterMetaType<glm::quat, quatToScriptValue, quatFromScriptValue>(engine); scriptRegisterMetaType<glm::mat4, mat4toScriptValue, mat4FromScriptValue>(engine); scriptRegisterMetaType<QVector< glm::vec3 >, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue>(engine); scriptRegisterMetaType<QVector< glm::quat >, qVectorQuatToScriptValue, qVectorQuatFromScriptValue>(engine); scriptRegisterMetaType<QVector< bool >, qVectorBoolToScriptValue, qVectorBoolFromScriptValue>(engine); scriptRegisterMetaType<QVector< float >, qVectorFloatToScriptValue, qVectorFloatFromScriptValue>(engine); scriptRegisterMetaType<QVector< uint32_t >, qVectorIntToScriptValue, qVectorIntFromScriptValue>(engine); scriptRegisterMetaType<QVector< QUuid >, qVectorQUuidToScriptValue, qVectorQUuidFromScriptValue>(engine); scriptRegisterMetaType<QSizeF, qSizeFToScriptValue, qSizeFFromScriptValue>(engine); scriptRegisterMetaType<QRect, qRectToScriptValue, qRectFromScriptValue>(engine); scriptRegisterMetaType<QUrl, qURLToScriptValue, qURLFromScriptValue>(engine); scriptRegisterMetaType<QColor, qColorToScriptValue, qColorFromScriptValue>(engine); scriptRegisterMetaType<PickRay, pickRayToScriptValue, pickRayFromScriptValue>(engine); scriptRegisterMetaType<Collision, collisionToScriptValue, collisionFromScriptValue>(engine); scriptRegisterMetaType<QUuid, quuidToScriptValue, quuidFromScriptValue>(engine); scriptRegisterMetaType<AACube, aaCubeToScriptValue, aaCubeFromScriptValue>(engine); scriptRegisterMetaType<StencilMaskMode, stencilMaskModeToScriptValue, stencilMaskModeFromScriptValue>(engine); scriptRegisterMetaType<std::shared_ptr< MiniPromise >, promiseToScriptValue, promiseFromScriptValue>(engine); scriptRegisterSequenceMetaType<QVector<unsigned int> >(engine); } ScriptValue vec2ToScriptValue(ScriptEngine* engine, const glm::vec2& vec2) { auto prototype = engine->globalObject().property("__hifi_vec2__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_vec2__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "u: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "v: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("x", vec2.x); value.setProperty("y", vec2.y); value.setPrototype(prototype); return value; } bool vec2FromScriptValue(const ScriptValue& object, glm::vec2& vec2) { if (object.isNumber()) { vec2 = glm::vec2(object.toVariant().toFloat()); } else if (object.isArray()) { QVariantList list = object.toVariant().toList(); if (list.length() == 2) { vec2.x = list[0].toFloat(); vec2.y = list[1].toFloat(); } } else { ScriptValue x = object.property("x"); if (!x.isValid()) { x = object.property("u"); } ScriptValue y = object.property("y"); if (!y.isValid()) { y = object.property("v"); } vec2.x = x.toVariant().toFloat(); vec2.y = y.toVariant().toFloat(); } return true; } ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_vec3__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_vec3__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "2: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," "r: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "g: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "b: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," "red: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("x", vec3.x); value.setProperty("y", vec3.y); value.setProperty("z", vec3.z); value.setPrototype(prototype); return value; } ScriptValue vec3ColorToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_vec3_color__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_vec3_color__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "1: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "2: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," "r: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "g: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "b: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," "x: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "y: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "z: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("red", vec3.x); value.setProperty("green", vec3.y); value.setProperty("blue", vec3.z); value.setPrototype(prototype); return value; } bool vec3FromScriptValue(const ScriptValue& object, glm::vec3& vec3) { if (object.isNumber()) { vec3 = glm::vec3(object.toVariant().toFloat()); } else if (object.isString()) { QColor qColor(object.toString()); if (qColor.isValid()) { vec3.x = qColor.red(); vec3.y = qColor.green(); vec3.z = qColor.blue(); } } else if (object.isArray()) { QVariantList list = object.toVariant().toList(); if (list.length() == 3) { vec3.x = list[0].toFloat(); vec3.y = list[1].toFloat(); vec3.z = list[2].toFloat(); } } else { ScriptValue x = object.property("x"); if (!x.isValid()) { x = object.property("r"); } if (!x.isValid()) { x = object.property("red"); } ScriptValue y = object.property("y"); if (!y.isValid()) { y = object.property("g"); } if (!y.isValid()) { y = object.property("green"); } ScriptValue z = object.property("z"); if (!z.isValid()) { z = object.property("b"); } if (!z.isValid()) { z = object.property("blue"); } vec3.x = x.toVariant().toFloat(); vec3.y = y.toVariant().toFloat(); vec3.z = z.toVariant().toFloat(); } return true; } ScriptValue u8vec3ToScriptValue(ScriptEngine* engine, const glm::u8vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_u8vec3__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_u8vec3__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "2: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," "r: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "g: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "b: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }," "red: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "green: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," "blue: { set: function(nv) { return this.z = nv; }, get: function() { return this.z; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("x", vec3.x); value.setProperty("y", vec3.y); value.setProperty("z", vec3.z); value.setPrototype(prototype); return value; } ScriptValue u8vec3ColorToScriptValue(ScriptEngine* engine, const glm::u8vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_u8vec3_color__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( "__hifi_u8vec3_color__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "1: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "2: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," "r: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "g: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "b: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }," "x: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "y: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," "z: { set: function(nv) { return this.blue = nv; }, get: function() { return this.blue; } }" "})"); } ScriptValue value = engine->newObject(); value.setProperty("red", vec3.x); value.setProperty("green", vec3.y); value.setProperty("blue", vec3.z); value.setPrototype(prototype); return value; } bool u8vec3FromScriptValue(const ScriptValue& object, glm::u8vec3& vec3) { if (object.isNumber()) { vec3 = glm::vec3(object.toVariant().toUInt()); } else if (object.isString()) { QColor qColor(object.toString()); if (qColor.isValid()) { vec3.x = (uint8_t)qColor.red(); vec3.y = (uint8_t)qColor.green(); vec3.z = (uint8_t)qColor.blue(); } } else if (object.isArray()) { QVariantList list = object.toVariant().toList(); if (list.length() == 3) { vec3.x = list[0].toUInt(); vec3.y = list[1].toUInt(); vec3.z = list[2].toUInt(); } } else { ScriptValue x = object.property("x"); if (!x.isValid()) { x = object.property("r"); } if (!x.isValid()) { x = object.property("red"); } ScriptValue y = object.property("y"); if (!y.isValid()) { y = object.property("g"); } if (!y.isValid()) { y = object.property("green"); } ScriptValue z = object.property("z"); if (!z.isValid()) { z = object.property("b"); } if (!z.isValid()) { z = object.property("blue"); } vec3.x = x.toVariant().toUInt(); vec3.y = y.toVariant().toUInt(); vec3.z = z.toVariant().toUInt(); } return true; } ScriptValue vec4toScriptValue(ScriptEngine* engine, const glm::vec4& vec4) { ScriptValue obj = engine->newObject(); obj.setProperty("x", vec4.x); obj.setProperty("y", vec4.y); obj.setProperty("z", vec4.z); obj.setProperty("w", vec4.w); return obj; } bool vec4FromScriptValue(const ScriptValue& object, glm::vec4& vec4) { vec4.x = object.property("x").toVariant().toFloat(); vec4.y = object.property("y").toVariant().toFloat(); vec4.z = object.property("z").toVariant().toFloat(); vec4.w = object.property("w").toVariant().toFloat(); return true; } ScriptValue mat4toScriptValue(ScriptEngine* engine, const glm::mat4& mat4) { ScriptValue obj = engine->newObject(); obj.setProperty("r0c0", mat4[0][0]); obj.setProperty("r1c0", mat4[0][1]); obj.setProperty("r2c0", mat4[0][2]); obj.setProperty("r3c0", mat4[0][3]); obj.setProperty("r0c1", mat4[1][0]); obj.setProperty("r1c1", mat4[1][1]); obj.setProperty("r2c1", mat4[1][2]); obj.setProperty("r3c1", mat4[1][3]); obj.setProperty("r0c2", mat4[2][0]); obj.setProperty("r1c2", mat4[2][1]); obj.setProperty("r2c2", mat4[2][2]); obj.setProperty("r3c2", mat4[2][3]); obj.setProperty("r0c3", mat4[3][0]); obj.setProperty("r1c3", mat4[3][1]); obj.setProperty("r2c3", mat4[3][2]); obj.setProperty("r3c3", mat4[3][3]); return obj; } bool mat4FromScriptValue(const ScriptValue& object, glm::mat4& mat4) { mat4[0][0] = object.property("r0c0").toVariant().toFloat(); mat4[0][1] = object.property("r1c0").toVariant().toFloat(); mat4[0][2] = object.property("r2c0").toVariant().toFloat(); mat4[0][3] = object.property("r3c0").toVariant().toFloat(); mat4[1][0] = object.property("r0c1").toVariant().toFloat(); mat4[1][1] = object.property("r1c1").toVariant().toFloat(); mat4[1][2] = object.property("r2c1").toVariant().toFloat(); mat4[1][3] = object.property("r3c1").toVariant().toFloat(); mat4[2][0] = object.property("r0c2").toVariant().toFloat(); mat4[2][1] = object.property("r1c2").toVariant().toFloat(); mat4[2][2] = object.property("r2c2").toVariant().toFloat(); mat4[2][3] = object.property("r3c2").toVariant().toFloat(); mat4[3][0] = object.property("r0c3").toVariant().toFloat(); mat4[3][1] = object.property("r1c3").toVariant().toFloat(); mat4[3][2] = object.property("r2c3").toVariant().toFloat(); mat4[3][3] = object.property("r3c3").toVariant().toFloat(); return true; } ScriptValue qVectorVec3ColorToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, vec3ColorToScriptValue(engine, vector.at(i))); } return array; } ScriptValue qVectorVec3ToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, vec3ToScriptValue(engine, vector.at(i))); } return array; } QVector<glm::vec3> qVectorVec3FromScriptValue(const ScriptValue& array) { QVector<glm::vec3> newVector; int length = array.property("length").toInteger(); for (int i = 0; i < length; i++) { glm::vec3 newVec3 = glm::vec3(); vec3FromScriptValue(array.property(i), newVec3); newVector << newVec3; } return newVector; } bool qVectorVec3FromScriptValue(const ScriptValue& array, QVector<glm::vec3>& vector) { int length = array.property("length").toInteger(); for (int i = 0; i < length; i++) { glm::vec3 newVec3 = glm::vec3(); vec3FromScriptValue(array.property(i), newVec3); vector << newVec3; } return true; } ScriptValue quatToScriptValue(ScriptEngine* engine, const glm::quat& quat) { ScriptValue obj = engine->newObject(); if (quat.x != quat.x || quat.y != quat.y || quat.z != quat.z || quat.w != quat.w) { // if quat contains a NaN don't try to convert it return obj; } obj.setProperty("x", quat.x); obj.setProperty("y", quat.y); obj.setProperty("z", quat.z); obj.setProperty("w", quat.w); return obj; } bool quatFromScriptValue(const ScriptValue& object, glm::quat& quat) { quat.x = object.property("x").toVariant().toFloat(); quat.y = object.property("y").toVariant().toFloat(); quat.z = object.property("z").toVariant().toFloat(); quat.w = object.property("w").toVariant().toFloat(); // enforce normalized quaternion float length = glm::length(quat); if (length > FLT_EPSILON) { quat /= length; } else { quat = glm::quat(); } return true; } ScriptValue qVectorQuatToScriptValue(ScriptEngine* engine, const QVector<glm::quat>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, quatToScriptValue(engine, vector.at(i))); } return array; } ScriptValue qVectorBoolToScriptValue(ScriptEngine* engine, const QVector<bool>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, vector.at(i)); } return array; } QVector<float> qVectorFloatFromScriptValue(const ScriptValue& array) { if (!array.isArray()) { return QVector<float>(); } QVector<float> newVector; int length = array.property("length").toInteger(); newVector.reserve(length); for (int i = 0; i < length; i++) { if (array.property(i).isNumber()) { newVector << array.property(i).toNumber(); } } return newVector; } ScriptValue qVectorQUuidToScriptValue(ScriptEngine* engine, const QVector<QUuid>& vector) { ScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array.setProperty(i, quuidToScriptValue(engine, vector.at(i))); } return array; } bool qVectorQUuidFromScriptValue(const ScriptValue& array, QVector<QUuid>& vector) { int length = array.property("length").toInteger(); for (int i = 0; i < length; i++) { vector << array.property(i).toVariant().toUuid(); } return true; }