diff --git a/interface/resources/scripts/sphere.js b/interface/resources/scripts/sphere.js index 403374e812..b696021fe8 100644 --- a/interface/resources/scripts/sphere.js +++ b/interface/resources/scripts/sphere.js @@ -35,11 +35,11 @@ function setNormal(vector) { if (normalIndex != -1) { var length = Math.sqrt(lengthSquared(vector[0], vector[1], vector[2])); if (length == 0.0) { - info.attributeValues[normalIndex] = 0x007F00; + info.inputValues[normalIndex] = 0x007F00; } else { var scale = 127.0 / length; - info.attributeValues[normalIndex] = + info.inputValues[normalIndex] = (Math.floor(vector[0] * scale) & 0xFF) << 16 | (Math.floor(vector[1] * scale) & 0xFF) << 8 | Math.floor(vector[2] * scale) & 0xFF; @@ -61,7 +61,7 @@ function guide(minimum, size, depth) { maximum[2] <= sphereCenter[2] - sphereRadius) { info.isLeaf = true; if (colorIndex != -1) { - info.attributeValues[colorIndex] = 0x0; + info.inputValues[colorIndex] = 0x0; } visitor.visit(info); return; @@ -110,7 +110,7 @@ function guide(minimum, size, depth) { if (inside == 8) { info.isLeaf = true; if (colorIndex != -1) { - info.attributeValues[colorIndex] = sphereColor; + info.inputValues[colorIndex] = sphereColor; } setNormal(vector); visitor.visit(info); @@ -122,13 +122,13 @@ function guide(minimum, size, depth) { info.isLeaf = true; if (inside >= 3) { if (colorIndex != -1) { - info.attributeValues[colorIndex] = sphereColor; + info.inputValues[colorIndex] = sphereColor; } setNormal(vector); } else { if (colorIndex != -1) { - info.attributeValues[colorIndex] = 0x0; + info.inputValues[colorIndex] = 0x0; } } visitor.visit(info); @@ -152,11 +152,11 @@ function guide(minimum, size, depth) { } (function(visitation) { - var attributes = visitation.visitor.getAttributes(); - colorIndex = strictIndexOf(attributes, AttributeRegistry.colorAttribute); - normalIndex = strictIndexOf(attributes, AttributeRegistry.normalAttribute); + var inputs = visitation.visitor.getInputs(); + colorIndex = strictIndexOf(inputs, AttributeRegistry.colorAttribute); + normalIndex = strictIndexOf(inputs, AttributeRegistry.normalAttribute); visitor = visitation.visitor; - info = { attributeValues: new Array(attributes.length) }; + info = { inputValues: new Array(inputs.length) }; // have the sphere orbit the center and pulse in size var time = new Date().getTime(); diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 355b027e93..298367b253 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -157,7 +157,8 @@ void MetavoxelSystem::receivedData(const QByteArray& data, const HifiSockAddr& s MetavoxelSystem::PointVisitor::PointVisitor(QVector& points) : MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getColorAttribute() << - AttributeRegistry::getInstance()->getNormalAttribute()), + AttributeRegistry::getInstance()->getNormalAttribute(), + QVector()), _points(points) { } @@ -165,8 +166,8 @@ bool MetavoxelSystem::PointVisitor::visit(const MetavoxelInfo& info) { if (!info.isLeaf) { return true; } - QRgb color = info.attributeValues.at(0).getInlineValue(); - QRgb normal = info.attributeValues.at(1).getInlineValue(); + QRgb color = info.inputValues.at(0).getInlineValue(); + QRgb normal = info.inputValues.at(1).getInlineValue(); int alpha = qAlpha(color); if (alpha > 0) { Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size), diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 8f2bd7429c..f89b64727b 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -32,19 +32,20 @@ MetavoxelData& MetavoxelData::operator=(const MetavoxelData& other) { void MetavoxelData::guide(MetavoxelVisitor& visitor) { // start with the root values/defaults (plus the guide attribute) const float TOP_LEVEL_SIZE = 1.0f; - const QVector& attributes = visitor.getAttributes(); - MetavoxelVisitation firstVisitation = { visitor, QVector(attributes.size() + 1), - { glm::vec3(), TOP_LEVEL_SIZE, QVector(attributes.size() + 1) } }; - for (int i = 0; i < attributes.size(); i++) { - MetavoxelNode* node = _roots.value(attributes[i]); + const QVector& inputs = visitor.getInputs(); + const QVector& outputs = visitor.getOutputs(); + MetavoxelVisitation firstVisitation = { visitor, QVector(inputs.size() + 1), + { glm::vec3(), TOP_LEVEL_SIZE, QVector(inputs.size() + 1), QVector(outputs.size()) } }; + for (int i = 0; i < inputs.size(); i++) { + MetavoxelNode* node = _roots.value(inputs[i]); firstVisitation.nodes[i] = node; - firstVisitation.info.attributeValues[i] = node ? node->getAttributeValue(attributes[i]) : attributes[i]; + firstVisitation.info.inputValues[i] = node ? node->getAttributeValue(inputs[i]) : inputs[i]; } AttributePointer guideAttribute = AttributeRegistry::getInstance()->getGuideAttribute(); MetavoxelNode* node = _roots.value(guideAttribute); firstVisitation.nodes.last() = node; - firstVisitation.info.attributeValues.last() = node ? node->getAttributeValue(guideAttribute) : guideAttribute; - static_cast(firstVisitation.info.attributeValues.last().getInlineValue< + firstVisitation.info.inputValues.last() = node ? node->getAttributeValue(guideAttribute) : guideAttribute; + static_cast(firstVisitation.info.inputValues.last().getInlineValue< PolymorphicDataPointer>().data())->guide(firstVisitation); } @@ -369,6 +370,11 @@ MetavoxelPath& MetavoxelPath::operator+=(int element) { return *this; } +MetavoxelVisitor::MetavoxelVisitor(const QVector& inputs, const QVector& outputs) : + _inputs(inputs), + _outputs(outputs) { +} + PolymorphicData* DefaultMetavoxelGuide::clone() const { return new DefaultMetavoxelGuide(); } @@ -379,7 +385,7 @@ const int Z_MAXIMUM_FLAG = 4; void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) { visitation.info.isLeaf = visitation.allNodesLeaves(); - if (!visitation.visitor.visit(visitation.info) || visitation.info.isLeaf) { + if (!visitation.visitor.visit(visitation.info)) { return; } MetavoxelVisitation nextVisitation = { visitation.visitor, QVector(visitation.nodes.size()), @@ -388,32 +394,40 @@ void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) { for (int j = 0; j < visitation.nodes.size(); j++) { MetavoxelNode* node = visitation.nodes.at(j); MetavoxelNode* child = node ? node->getChild(i) : NULL; - nextVisitation.info.attributeValues[j] = ((nextVisitation.nodes[j] = child)) ? - child->getAttributeValue(visitation.info.attributeValues[j].getAttribute()) : - visitation.info.attributeValues[j]; + nextVisitation.info.inputValues[j] = ((nextVisitation.nodes[j] = child)) ? + child->getAttributeValue(visitation.info.inputValues[j].getAttribute()) : + visitation.info.inputValues[j]; } nextVisitation.info.minimum = visitation.info.minimum + glm::vec3( (i & X_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f, (i & Y_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f, (i & Z_MAXIMUM_FLAG) ? nextVisitation.info.size : 0.0f); - static_cast(nextVisitation.info.attributeValues.last().getInlineValue< + static_cast(nextVisitation.info.inputValues.last().getInlineValue< PolymorphicDataPointer>().data())->guide(nextVisitation); } } -QScriptValue ScriptedMetavoxelGuide::getAttributes(QScriptContext* context, QScriptEngine* engine) { - ScriptedMetavoxelGuide* guide = static_cast(context->callee().data().toVariant().value()); +static QScriptValue getAttributes(QScriptEngine* engine, ScriptedMetavoxelGuide* guide, + const QVector& attributes) { - const QVector& attributes = guide->_visitation->visitor.getAttributes(); QScriptValue attributesValue = engine->newArray(attributes.size()); for (int i = 0; i < attributes.size(); i++) { attributesValue.setProperty(i, engine->newQObject(attributes.at(i).data(), QScriptEngine::QtOwnership, QScriptEngine::PreferExistingWrapperObject)); } - return attributesValue; } +QScriptValue ScriptedMetavoxelGuide::getInputs(QScriptContext* context, QScriptEngine* engine) { + ScriptedMetavoxelGuide* guide = static_cast(context->callee().data().toVariant().value()); + return getAttributes(engine, guide, guide->_visitation->visitor.getInputs()); +} + +QScriptValue ScriptedMetavoxelGuide::getOutputs(QScriptContext* context, QScriptEngine* engine) { + ScriptedMetavoxelGuide* guide = static_cast(context->callee().data().toVariant().value()); + return getAttributes(engine, guide, guide->_visitation->visitor.getOutputs()); +} + QScriptValue ScriptedMetavoxelGuide::visit(QScriptContext* context, QScriptEngine* engine) { ScriptedMetavoxelGuide* guide = static_cast(context->callee().data().toVariant().value()); @@ -422,26 +436,26 @@ QScriptValue ScriptedMetavoxelGuide::visit(QScriptContext* context, QScriptEngin QScriptValue minimum = infoValue.property(guide->_minimumHandle); MetavoxelInfo info = { glm::vec3(minimum.property(0).toNumber(), minimum.property(1).toNumber(), minimum.property(2).toNumber()), - infoValue.property(guide->_sizeHandle).toNumber(), guide->_visitation->info.attributeValues, - infoValue.property(guide->_isLeafHandle).toBool() }; + infoValue.property(guide->_sizeHandle).toNumber(), guide->_visitation->info.inputValues, + guide->_visitation->info.outputValues, infoValue.property(guide->_isLeafHandle).toBool() }; // extract and convert the values provided by the script - QScriptValue attributeValues = infoValue.property(guide->_attributeValuesHandle); - const QVector& attributes = guide->_visitation->visitor.getAttributes(); - for (int i = 0; i < attributes.size(); i++) { - QScriptValue attributeValue = attributeValues.property(i); + QScriptValue inputValues = infoValue.property(guide->_inputValuesHandle); + const QVector& inputs = guide->_visitation->visitor.getInputs(); + for (int i = 0; i < inputs.size(); i++) { + QScriptValue attributeValue = inputValues.property(i); if (attributeValue.isValid()) { - info.attributeValues[i] = AttributeValue(attributes.at(i), - attributes.at(i)->createFromScript(attributeValue, engine)); + info.inputValues[i] = AttributeValue(inputs.at(i), + inputs.at(i)->createFromScript(attributeValue, engine)); } } QScriptValue result = guide->_visitation->visitor.visit(info); // destroy any created values - for (int i = 0; i < attributes.size(); i++) { - if (attributeValues.property(i).isValid()) { - info.attributeValues[i].getAttribute()->destroy(info.attributeValues[i].getValue()); + for (int i = 0; i < inputs.size(); i++) { + if (inputValues.property(i).isValid()) { + info.inputValues[i].getAttribute()->destroy(info.inputValues[i].getValue()); } } @@ -452,16 +466,19 @@ ScriptedMetavoxelGuide::ScriptedMetavoxelGuide(const QScriptValue& guideFunction _guideFunction(guideFunction), _minimumHandle(guideFunction.engine()->toStringHandle("minimum")), _sizeHandle(guideFunction.engine()->toStringHandle("size")), - _attributeValuesHandle(guideFunction.engine()->toStringHandle("attributeValues")), + _inputValuesHandle(guideFunction.engine()->toStringHandle("inputValues")), + _outputValuesHandle(guideFunction.engine()->toStringHandle("outputValues")), _isLeafHandle(guideFunction.engine()->toStringHandle("isLeaf")), - _getAttributesFunction(guideFunction.engine()->newFunction(getAttributes, 0)), + _getInputsFunction(guideFunction.engine()->newFunction(getInputs, 0)), + _getOutputsFunction(guideFunction.engine()->newFunction(getOutputs, 0)), _visitFunction(guideFunction.engine()->newFunction(visit, 1)), _info(guideFunction.engine()->newObject()), _minimum(guideFunction.engine()->newArray(3)) { _arguments.append(guideFunction.engine()->newObject()); QScriptValue visitor = guideFunction.engine()->newObject(); - visitor.setProperty("getAttributes", _getAttributesFunction); + visitor.setProperty("getInputs", _getInputsFunction); + visitor.setProperty("getOutputs", _getOutputsFunction); visitor.setProperty("visit", _visitFunction); _arguments[0].setProperty("visitor", visitor); _arguments[0].setProperty("info", _info); @@ -474,7 +491,7 @@ PolymorphicData* ScriptedMetavoxelGuide::clone() const { void ScriptedMetavoxelGuide::guide(MetavoxelVisitation& visitation) { QScriptValue data = _guideFunction.engine()->newVariant(QVariant::fromValue(this)); - _getAttributesFunction.setData(data); + _getInputsFunction.setData(data); _visitFunction.setData(data); _minimum.setProperty(0, visitation.info.minimum.x); _minimum.setProperty(1, visitation.info.minimum.y); diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index d588c8a687..a129930e93 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -139,7 +139,8 @@ public: glm::vec3 minimum; ///< the minimum extent of the area covered by the voxel float size; ///< the size of the voxel in all dimensions - QVector attributeValues; + QVector inputValues; + QVector outputValues; bool isLeaf; }; @@ -147,19 +148,23 @@ public: class MetavoxelVisitor { public: - MetavoxelVisitor(const QVector& attributes) : _attributes(attributes) { } - - /// Returns a reference to the list of attributes desired. - const QVector& getAttributes() const { return _attributes; } + MetavoxelVisitor(const QVector& inputs, const QVector& outputs); + + /// Returns a reference to the list of input attributes desired. + const QVector& getInputs() const { return _inputs; } + + /// Returns a reference to the list of output attributes provided. + const QVector& getOutputs() const { return _outputs; } /// Visits a metavoxel. - /// \param info the metavoxel ata - /// \param if true, continue descending; if false, stop + /// \param info the metavoxel data + /// \return if true, continue descending; if false, stop virtual bool visit(const MetavoxelInfo& info) = 0; protected: - QVector _attributes; + QVector _inputs; + QVector _outputs; }; /// Interface for objects that guide metavoxel visitors. @@ -191,16 +196,19 @@ public: private: - static QScriptValue getAttributes(QScriptContext* context, QScriptEngine* engine); + static QScriptValue getInputs(QScriptContext* context, QScriptEngine* engine); + static QScriptValue getOutputs(QScriptContext* context, QScriptEngine* engine); static QScriptValue visit(QScriptContext* context, QScriptEngine* engine); QScriptValue _guideFunction; QScriptString _minimumHandle; QScriptString _sizeHandle; - QScriptString _attributeValuesHandle; + QScriptString _inputValuesHandle; + QScriptString _outputValuesHandle; QScriptString _isLeafHandle; QScriptValueList _arguments; - QScriptValue _getAttributesFunction; + QScriptValue _getInputsFunction; + QScriptValue _getOutputsFunction; QScriptValue _visitFunction; QScriptValue _info; QScriptValue _minimum;