//// ScriptValueUtils.cpp// libraries/shared/src//// Created by Anthony Thibault on 4/15/16.// Copyright 2016 High Fidelity, Inc.//// 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 "ScriptEngine.h"#include "ScriptEngineCast.h"#include "ScriptValueIterator.h" bool isListOfStrings(const ScriptValuePointer& 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(engine, vec2ToScriptValue, vec2FromScriptValue); scriptRegisterMetaType(engine, vec3ToScriptValue, vec3FromScriptValue); scriptRegisterMetaType(engine, u8vec3ToScriptValue, u8vec3FromScriptValue); scriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue); scriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue); scriptRegisterMetaType(engine, mat4toScriptValue, mat4FromScriptValue); scriptRegisterMetaType(engine, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue); scriptRegisterMetaType(engine, qVectorQuatToScriptValue, qVectorQuatFromScriptValue); scriptRegisterMetaType(engine, qVectorBoolToScriptValue, qVectorBoolFromScriptValue); scriptRegisterMetaType(engine, qVectorFloatToScriptValue, qVectorFloatFromScriptValue); scriptRegisterMetaType(engine, qVectorIntToScriptValue, qVectorIntFromScriptValue); scriptRegisterMetaType(engine, qVectorQUuidToScriptValue, qVectorQUuidFromScriptValue); scriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue); scriptRegisterMetaType(engine, qRectToScriptValue, qRectFromScriptValue); scriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue); scriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue); scriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue); scriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue); scriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue); scriptRegisterMetaType(engine, aaCubeToScriptValue, aaCubeFromScriptValue); scriptRegisterMetaType(engine, stencilMaskModeToScriptValue, stencilMaskModeFromScriptValue); scriptRegisterMetaType(engine, promiseToScriptValue, promiseFromScriptValue); scriptRegisterSequenceMetaType<QVector<unsigned int>>(engine);} ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("x", vec2.x); value->setProperty("y", vec2.y); value->setPrototype(prototype); return value;} void vec2FromScriptValue(const ScriptValuePointer& 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 { ScriptValuePointer x = object->property("x"); if (!x->isValid()) { x = object->property("u"); } ScriptValuePointer y = object->property("y"); if (!y->isValid()) { y = object->property("v"); } vec2.x = x->toVariant().toFloat(); vec2.y = y->toVariant().toFloat(); }} ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("x", vec3.x); value->setProperty("y", vec3.y); value->setProperty("z", vec3.z); value->setPrototype(prototype); return value;} ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("red", vec3.x); value->setProperty("green", vec3.y); value->setProperty("blue", vec3.z); value->setPrototype(prototype); return value;} void vec3FromScriptValue(const ScriptValuePointer& 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 { ScriptValuePointer x = object->property("x"); if (!x->isValid()) { x = object->property("r"); } if (!x->isValid()) { x = object->property("red"); } ScriptValuePointer y = object->property("y"); if (!y->isValid()) { y = object->property("g"); } if (!y->isValid()) { y = object->property("green"); } ScriptValuePointer 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(); }} ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("x", vec3.x); value->setProperty("y", vec3.y); value->setProperty("z", vec3.z); value->setPrototype(prototype); return value;} ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("red", vec3.x); value->setProperty("green", vec3.y); value->setProperty("blue", vec3.z); value->setPrototype(prototype); return value;} void u8vec3FromScriptValue(const ScriptValuePointer& 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 { ScriptValuePointer x = object->property("x"); if (!x->isValid()) { x = object->property("r"); } if (!x->isValid()) { x = object->property("red"); } ScriptValuePointer y = object->property("y"); if (!y->isValid()) { y = object->property("g"); } if (!y->isValid()) { y = object->property("green"); } ScriptValuePointer 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(); }} ScriptValuePointer vec4toScriptValue(ScriptEngine* engine, const glm::vec4& vec4) { ScriptValuePointer 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;} void vec4FromScriptValue(const ScriptValuePointer& 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();} ScriptValuePointer mat4toScriptValue(ScriptEngine* engine, const glm::mat4& mat4) { ScriptValuePointer 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;} void mat4FromScriptValue(const ScriptValuePointer& 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();} ScriptValuePointer qVectorVec3ColorToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) { ScriptValuePointer array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array->setProperty(i, vec3ColorToScriptValue(engine, vector.at(i))); } return array;} ScriptValuePointer qVectorVec3ToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) { ScriptValuePointer 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 ScriptValuePointer& 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;} void qVectorVec3FromScriptValue(const ScriptValuePointer& 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; }} ScriptValuePointer quatToScriptValue(ScriptEngine* engine, const glm::quat& quat) { ScriptValuePointer 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;} void quatFromScriptValue(const ScriptValuePointer& 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(); }} ScriptValuePointer qVectorQuatToScriptValue(ScriptEngine* engine, const QVector<glm::quat>& vector) { ScriptValuePointer array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array->setProperty(i, quatToScriptValue(engine, vector.at(i))); } return array;} ScriptValuePointer qVectorBoolToScriptValue(ScriptEngine* engine, const QVector<bool>& vector) { ScriptValuePointer array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array->setProperty(i, vector.at(i)); } return array;} QVector<float> qVectorFloatFromScriptValue(const ScriptValuePointer& 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;} ScriptValuePointer qVectorQUuidToScriptValue(ScriptEngine* engine, const QVector<QUuid>& vector) { ScriptValuePointer array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array->setProperty(i, quuidToScriptValue(engine, vector.at(i))); } return array;} void qVectorQUuidFromScriptValue(const ScriptValuePointer& array, QVector<QUuid>& vector) { int length = array->property("length")->toInteger(); for (int i = 0; i < length; i++) { vector << array->property(i)->toVariant().toUuid(); }} QVector<QUuid> qVectorQUuidFromScriptValue(const ScriptValuePointer& array) { if (!array->isArray()) { return QVector<QUuid>(); } QVector<QUuid> newVector; int length = array->property("length")->toInteger(); newVector.reserve(length); for (int i = 0; i < length; i++) { QString uuidAsString = array->property(i)->toString();Lines 1–500 of 887. Load more
// // ScriptValueUtils.cpp // libraries/shared/src // // Created by Anthony Thibault on 4/15/16. // Copyright 2016 High Fidelity, Inc. // // 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 "ScriptEngine.h" #include "ScriptEngineCast.h" #include "ScriptValueIterator.h" bool isListOfStrings(const ScriptValuePointer& 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(engine, vec2ToScriptValue, vec2FromScriptValue); scriptRegisterMetaType(engine, vec3ToScriptValue, vec3FromScriptValue); scriptRegisterMetaType(engine, u8vec3ToScriptValue, u8vec3FromScriptValue); scriptRegisterMetaType(engine, vec4toScriptValue, vec4FromScriptValue); scriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue); scriptRegisterMetaType(engine, mat4toScriptValue, mat4FromScriptValue); scriptRegisterMetaType(engine, qVectorVec3ToScriptValue, qVectorVec3FromScriptValue); scriptRegisterMetaType(engine, qVectorQuatToScriptValue, qVectorQuatFromScriptValue); scriptRegisterMetaType(engine, qVectorBoolToScriptValue, qVectorBoolFromScriptValue); scriptRegisterMetaType(engine, qVectorFloatToScriptValue, qVectorFloatFromScriptValue); scriptRegisterMetaType(engine, qVectorIntToScriptValue, qVectorIntFromScriptValue); scriptRegisterMetaType(engine, qVectorQUuidToScriptValue, qVectorQUuidFromScriptValue); scriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue); scriptRegisterMetaType(engine, qRectToScriptValue, qRectFromScriptValue); scriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue); scriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue); scriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue); scriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue); scriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue); scriptRegisterMetaType(engine, aaCubeToScriptValue, aaCubeFromScriptValue); scriptRegisterMetaType(engine, stencilMaskModeToScriptValue, stencilMaskModeFromScriptValue); scriptRegisterMetaType(engine, promiseToScriptValue, promiseFromScriptValue); scriptRegisterSequenceMetaType<QVector<unsigned int>>(engine); } ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("x", vec2.x); value->setProperty("y", vec2.y); value->setPrototype(prototype); return value; } void vec2FromScriptValue(const ScriptValuePointer& 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 { ScriptValuePointer x = object->property("x"); if (!x->isValid()) { x = object->property("u"); } ScriptValuePointer y = object->property("y"); if (!y->isValid()) { y = object->property("v"); } vec2.x = x->toVariant().toFloat(); vec2.y = y->toVariant().toFloat(); } } ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("x", vec3.x); value->setProperty("y", vec3.y); value->setProperty("z", vec3.z); value->setPrototype(prototype); return value; } ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("red", vec3.x); value->setProperty("green", vec3.y); value->setProperty("blue", vec3.z); value->setPrototype(prototype); return value; } void vec3FromScriptValue(const ScriptValuePointer& 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 { ScriptValuePointer x = object->property("x"); if (!x->isValid()) { x = object->property("r"); } if (!x->isValid()) { x = object->property("red"); } ScriptValuePointer y = object->property("y"); if (!y->isValid()) { y = object->property("g"); } if (!y->isValid()) { y = object->property("green"); } ScriptValuePointer 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(); } } ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("x", vec3.x); value->setProperty("y", vec3.y); value->setProperty("z", vec3.z); value->setPrototype(prototype); return value; } ScriptValuePointer 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; } }" "})"); } ScriptValuePointer value = engine->newObject(); value->setProperty("red", vec3.x); value->setProperty("green", vec3.y); value->setProperty("blue", vec3.z); value->setPrototype(prototype); return value; } void u8vec3FromScriptValue(const ScriptValuePointer& 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 { ScriptValuePointer x = object->property("x"); if (!x->isValid()) { x = object->property("r"); } if (!x->isValid()) { x = object->property("red"); } ScriptValuePointer y = object->property("y"); if (!y->isValid()) { y = object->property("g"); } if (!y->isValid()) { y = object->property("green"); } ScriptValuePointer 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(); } } ScriptValuePointer vec4toScriptValue(ScriptEngine* engine, const glm::vec4& vec4) { ScriptValuePointer 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; } void vec4FromScriptValue(const ScriptValuePointer& 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(); } ScriptValuePointer mat4toScriptValue(ScriptEngine* engine, const glm::mat4& mat4) { ScriptValuePointer 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; } void mat4FromScriptValue(const ScriptValuePointer& 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(); } ScriptValuePointer qVectorVec3ColorToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) { ScriptValuePointer array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array->setProperty(i, vec3ColorToScriptValue(engine, vector.at(i))); } return array; } ScriptValuePointer qVectorVec3ToScriptValue(ScriptEngine* engine, const QVector<glm::vec3>& vector) { ScriptValuePointer 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 ScriptValuePointer& 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; } void qVectorVec3FromScriptValue(const ScriptValuePointer& 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; } } ScriptValuePointer quatToScriptValue(ScriptEngine* engine, const glm::quat& quat) { ScriptValuePointer 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; } void quatFromScriptValue(const ScriptValuePointer& 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(); } } ScriptValuePointer qVectorQuatToScriptValue(ScriptEngine* engine, const QVector<glm::quat>& vector) { ScriptValuePointer array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array->setProperty(i, quatToScriptValue(engine, vector.at(i))); } return array; } ScriptValuePointer qVectorBoolToScriptValue(ScriptEngine* engine, const QVector<bool>& vector) { ScriptValuePointer array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array->setProperty(i, vector.at(i)); } return array; } QVector<float> qVectorFloatFromScriptValue(const ScriptValuePointer& 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; } ScriptValuePointer qVectorQUuidToScriptValue(ScriptEngine* engine, const QVector<QUuid>& vector) { ScriptValuePointer array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { array->setProperty(i, quuidToScriptValue(engine, vector.at(i))); } return array; } void qVectorQUuidFromScriptValue(const ScriptValuePointer& array, QVector<QUuid>& vector) { int length = array->property("length")->toInteger(); for (int i = 0; i < length; i++) { vector << array->property(i)->toVariant().toUuid(); } } QVector<QUuid> qVectorQUuidFromScriptValue(const ScriptValuePointer& array) { if (!array->isArray()) { return QVector<QUuid>(); } QVector<QUuid> newVector; int length = array->property("length")->toInteger(); newVector.reserve(length); for (int i = 0; i < length; i++) { QString uuidAsString = array->property(i)->toString();