mirror of
https://github.com/lubosz/overte.git
synced 2025-08-13 11:48:12 +02:00
More progress on getting values in and out of scripts.
This commit is contained in:
parent
07ed688a8a
commit
d535d3b115
5 changed files with 102 additions and 17 deletions
|
@ -30,6 +30,8 @@ void MetavoxelSystem::init() {
|
||||||
_pointScaleLocation = _program.uniformLocation("pointScale");
|
_pointScaleLocation = _program.uniformLocation("pointScale");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttributeRegistry::getInstance()->configureScriptEngine(&_scriptEngine);
|
||||||
|
|
||||||
MetavoxelPath p1;
|
MetavoxelPath p1;
|
||||||
p1 += 7;
|
p1 += 7;
|
||||||
p1 += 7;
|
p1 += 7;
|
||||||
|
@ -41,6 +43,13 @@ void MetavoxelSystem::init() {
|
||||||
|
|
||||||
QScriptValue guideFunction = _scriptEngine.evaluate(
|
QScriptValue guideFunction = _scriptEngine.evaluate(
|
||||||
"(function(visitation) { "
|
"(function(visitation) { "
|
||||||
|
" var attributes = visitation.visitor.getAttributes();"
|
||||||
|
" var colorIndex = attributes.indexOf(AttributeRegistry.colorAttribute);"
|
||||||
|
" var normalIndex = attributes.indexOf(AttributeRegistry.normalAttribute);"
|
||||||
|
" for (var i = 0; i < attributes.length; i++) {"
|
||||||
|
" print(attributes[i].getName() + ' ');"
|
||||||
|
" }"
|
||||||
|
" print('\\n');"
|
||||||
" visitation.visitor.visit(visitation.info);"
|
" visitation.visitor.visit(visitation.info);"
|
||||||
"})");
|
"})");
|
||||||
_data.setAttributeValue(MetavoxelPath(), AttributeValue(AttributeRegistry::getInstance()->getGuideAttribute(),
|
_data.setAttributeValue(MetavoxelPath(), AttributeValue(AttributeRegistry::getInstance()->getGuideAttribute(),
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QScriptEngine>
|
||||||
|
|
||||||
#include "AttributeRegistry.h"
|
#include "AttributeRegistry.h"
|
||||||
#include "MetavoxelData.h"
|
#include "MetavoxelData.h"
|
||||||
|
|
||||||
|
@ -17,6 +19,14 @@ AttributeRegistry::AttributeRegistry() :
|
||||||
_normalAttribute(registerAttribute(new QRgbAttribute("normal", qRgb(0, 127, 0)))) {
|
_normalAttribute(registerAttribute(new QRgbAttribute("normal", qRgb(0, 127, 0)))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AttributeRegistry::configureScriptEngine(QScriptEngine* engine) {
|
||||||
|
QScriptValue registry = engine->newObject();
|
||||||
|
registry.setProperty("colorAttribute", engine->newQObject(_colorAttribute.data()));
|
||||||
|
registry.setProperty("normalAttribute", engine->newQObject(_normalAttribute.data()));
|
||||||
|
registry.setProperty("getAttribute", engine->newFunction(getAttribute, 1));
|
||||||
|
engine->globalObject().setProperty("AttributeRegistry", registry);
|
||||||
|
}
|
||||||
|
|
||||||
AttributePointer AttributeRegistry::registerAttribute(AttributePointer attribute) {
|
AttributePointer AttributeRegistry::registerAttribute(AttributePointer attribute) {
|
||||||
AttributePointer& pointer = _attributes[attribute->getName()];
|
AttributePointer& pointer = _attributes[attribute->getName()];
|
||||||
if (!pointer) {
|
if (!pointer) {
|
||||||
|
@ -25,6 +35,11 @@ AttributePointer AttributeRegistry::registerAttribute(AttributePointer attribute
|
||||||
return pointer;
|
return pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue AttributeRegistry::getAttribute(QScriptContext* context, QScriptEngine* engine) {
|
||||||
|
return engine->newQObject(_instance.getAttribute(context->argument(0).toString()).data(), QScriptEngine::QtOwnership,
|
||||||
|
QScriptEngine::PreferExistingWrapperObject);
|
||||||
|
}
|
||||||
|
|
||||||
AttributeValue::AttributeValue(const AttributePointer& attribute) :
|
AttributeValue::AttributeValue(const AttributePointer& attribute) :
|
||||||
_attribute(attribute), _value(attribute ? attribute->getDefaultValue() : NULL) {
|
_attribute(attribute), _value(attribute ? attribute->getDefaultValue() : NULL) {
|
||||||
}
|
}
|
||||||
|
@ -76,7 +91,8 @@ OwnedAttributeValue& OwnedAttributeValue::operator=(const AttributeValue& other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Attribute::Attribute(const QString& name) : _name(name) {
|
Attribute::Attribute(const QString& name) {
|
||||||
|
setObjectName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Attribute::~Attribute() {
|
Attribute::~Attribute() {
|
||||||
|
@ -106,6 +122,10 @@ bool QRgbAttribute::merge(void*& parent, void* children[]) const {
|
||||||
return allChildrenEqual;
|
return allChildrenEqual;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* QRgbAttribute::createFromScript(const QScriptValue& value, QScriptEngine* engine) const {
|
||||||
|
return encodeInline((QRgb)value.toUInt32());
|
||||||
|
}
|
||||||
|
|
||||||
PolymorphicData::~PolymorphicData() {
|
PolymorphicData::~PolymorphicData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,12 +12,17 @@
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QExplicitlySharedDataPointer>
|
#include <QExplicitlySharedDataPointer>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QObject>
|
||||||
#include <QSharedData>
|
#include <QSharedData>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "Bitstream.h"
|
#include "Bitstream.h"
|
||||||
|
|
||||||
|
class QScriptContext;
|
||||||
|
class QScriptEngine;
|
||||||
|
class QScriptValue;
|
||||||
|
|
||||||
class Attribute;
|
class Attribute;
|
||||||
|
|
||||||
typedef QSharedPointer<Attribute> AttributePointer;
|
typedef QSharedPointer<Attribute> AttributePointer;
|
||||||
|
@ -31,6 +36,9 @@ public:
|
||||||
|
|
||||||
AttributeRegistry();
|
AttributeRegistry();
|
||||||
|
|
||||||
|
/// Configures the supplied script engine with the global AttributeRegistry property.
|
||||||
|
void configureScriptEngine(QScriptEngine* engine);
|
||||||
|
|
||||||
/// Registers an attribute with the system. The registry assumes ownership of the object.
|
/// Registers an attribute with the system. The registry assumes ownership of the object.
|
||||||
/// \return either the pointer passed as an argument, if the attribute wasn't already registered, or the existing
|
/// \return either the pointer passed as an argument, if the attribute wasn't already registered, or the existing
|
||||||
/// attribute
|
/// attribute
|
||||||
|
@ -55,6 +63,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static QScriptValue getAttribute(QScriptContext* context, QScriptEngine* engine);
|
||||||
|
|
||||||
static AttributeRegistry _instance;
|
static AttributeRegistry _instance;
|
||||||
|
|
||||||
QHash<QString, AttributePointer> _attributes;
|
QHash<QString, AttributePointer> _attributes;
|
||||||
|
@ -114,15 +124,17 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a registered attribute.
|
/// Represents a registered attribute.
|
||||||
class Attribute {
|
class Attribute : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static const int MERGE_COUNT = 8;
|
static const int MERGE_COUNT = 8;
|
||||||
|
|
||||||
Attribute(const QString& name);
|
Attribute(const QString& name);
|
||||||
virtual ~Attribute();
|
virtual ~Attribute();
|
||||||
|
|
||||||
const QString& getName() const { return _name; }
|
Q_INVOKABLE QString getName() const { return objectName(); }
|
||||||
|
|
||||||
void* create() const { return create(getDefaultValue()); }
|
void* create() const { return create(getDefaultValue()); }
|
||||||
virtual void* create(void* copy) const = 0;
|
virtual void* create(void* copy) const = 0;
|
||||||
|
@ -139,9 +151,7 @@ public:
|
||||||
|
|
||||||
virtual void* getDefaultValue() const = 0;
|
virtual void* getDefaultValue() const = 0;
|
||||||
|
|
||||||
private:
|
virtual void* createFromScript(const QScriptValue& value, QScriptEngine* engine) const { return create(); }
|
||||||
|
|
||||||
QString _name;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A simple attribute class that stores its values inline.
|
/// A simple attribute class that stores its values inline.
|
||||||
|
@ -193,6 +203,8 @@ public:
|
||||||
QRgbAttribute(const QString& name, QRgb defaultValue = QRgb());
|
QRgbAttribute(const QString& name, QRgb defaultValue = QRgb());
|
||||||
|
|
||||||
virtual bool merge(void*& parent, void* children[]) const;
|
virtual bool merge(void*& parent, void* children[]) const;
|
||||||
|
|
||||||
|
virtual void* createFromScript(const QScriptValue& value, QScriptEngine* engine) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An attribute class that stores pointers to its values.
|
/// An attribute class that stores pointers to its values.
|
||||||
|
|
|
@ -185,31 +185,67 @@ void DefaultMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue ScriptedMetavoxelGuide::getAttributes(QScriptContext* context, QScriptEngine* engine) {
|
||||||
|
ScriptedMetavoxelGuide* guide = static_cast<ScriptedMetavoxelGuide*>(context->callee().data().toVariant().value<void*>());
|
||||||
|
|
||||||
|
const QVector<AttributePointer>& 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::visit(QScriptContext* context, QScriptEngine* engine) {
|
QScriptValue ScriptedMetavoxelGuide::visit(QScriptContext* context, QScriptEngine* engine) {
|
||||||
ScriptedMetavoxelGuide* guide = static_cast<ScriptedMetavoxelGuide*>(context->callee().data().toVariant().value<void*>());
|
ScriptedMetavoxelGuide* guide = static_cast<ScriptedMetavoxelGuide*>(context->callee().data().toVariant().value<void*>());
|
||||||
|
|
||||||
MetavoxelInfo info;
|
// start with the basics, including inherited attribute values
|
||||||
QScriptValue infoValue = context->argument(0);
|
QScriptValue infoValue = context->argument(0);
|
||||||
QScriptValue minimumValue = infoValue.property(guide->_minimumHandle);
|
QScriptValue minimum = infoValue.property(guide->_minimumHandle);
|
||||||
info.minimum = glm::vec3(minimumValue.property(0).toNumber(), minimumValue.property(1).toNumber(),
|
MetavoxelInfo info = {
|
||||||
minimumValue.property(2).toNumber());
|
glm::vec3(minimum.property(0).toNumber(), minimum.property(1).toNumber(), minimum.property(2).toNumber()),
|
||||||
info.size = infoValue.property(guide->_sizeHandle).toNumber();
|
infoValue.property(guide->_sizeHandle).toNumber(), guide->_visitation->info.attributeValues,
|
||||||
info.isLeaf = infoValue.property(guide->_isLeafHandle).toBool();
|
infoValue.property(guide->_isLeafHandle).toBool() };
|
||||||
|
|
||||||
return guide->_visitor->visit(info);
|
// extract and convert the values provided by the script
|
||||||
|
QScriptValue attributeValues = infoValue.property(guide->_attributeValuesHandle);
|
||||||
|
const QVector<AttributePointer>& attributes = guide->_visitation->visitor.getAttributes();
|
||||||
|
for (int i = 0; i < attributes.size(); i++) {
|
||||||
|
QScriptValue attributeValue = attributeValues.property(i);
|
||||||
|
if (attributeValue.isValid()) {
|
||||||
|
info.attributeValues[i] = AttributeValue(attributes.at(i),
|
||||||
|
attributes.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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptedMetavoxelGuide::ScriptedMetavoxelGuide(const QScriptValue& guideFunction) :
|
ScriptedMetavoxelGuide::ScriptedMetavoxelGuide(const QScriptValue& guideFunction) :
|
||||||
_guideFunction(guideFunction),
|
_guideFunction(guideFunction),
|
||||||
_minimumHandle(guideFunction.engine()->toStringHandle("minimum")),
|
_minimumHandle(guideFunction.engine()->toStringHandle("minimum")),
|
||||||
_sizeHandle(guideFunction.engine()->toStringHandle("size")),
|
_sizeHandle(guideFunction.engine()->toStringHandle("size")),
|
||||||
|
_attributeValuesHandle(guideFunction.engine()->toStringHandle("attributeValues")),
|
||||||
_isLeafHandle(guideFunction.engine()->toStringHandle("isLeaf")),
|
_isLeafHandle(guideFunction.engine()->toStringHandle("isLeaf")),
|
||||||
|
_getAttributesFunction(guideFunction.engine()->newFunction(getAttributes, 0)),
|
||||||
_visitFunction(guideFunction.engine()->newFunction(visit, 1)),
|
_visitFunction(guideFunction.engine()->newFunction(visit, 1)),
|
||||||
_info(guideFunction.engine()->newObject()),
|
_info(guideFunction.engine()->newObject()),
|
||||||
_minimum(guideFunction.engine()->newArray(3)) {
|
_minimum(guideFunction.engine()->newArray(3)) {
|
||||||
|
|
||||||
_arguments.append(guideFunction.engine()->newObject());
|
_arguments.append(guideFunction.engine()->newObject());
|
||||||
QScriptValue visitor = guideFunction.engine()->newObject();
|
QScriptValue visitor = guideFunction.engine()->newObject();
|
||||||
|
visitor.setProperty("getAttributes", _getAttributesFunction);
|
||||||
visitor.setProperty("visit", _visitFunction);
|
visitor.setProperty("visit", _visitFunction);
|
||||||
_arguments[0].setProperty("visitor", visitor);
|
_arguments[0].setProperty("visitor", visitor);
|
||||||
_arguments[0].setProperty("info", _info);
|
_arguments[0].setProperty("info", _info);
|
||||||
|
@ -221,14 +257,19 @@ PolymorphicData* ScriptedMetavoxelGuide::clone() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptedMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
void ScriptedMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
|
||||||
_visitFunction.setData(_guideFunction.engine()->newVariant(QVariant::fromValue<void*>(this)));
|
QScriptValue data = _guideFunction.engine()->newVariant(QVariant::fromValue<void*>(this));
|
||||||
|
_getAttributesFunction.setData(data);
|
||||||
|
_visitFunction.setData(data);
|
||||||
_minimum.setProperty(0, visitation.info.minimum.x);
|
_minimum.setProperty(0, visitation.info.minimum.x);
|
||||||
_minimum.setProperty(1, visitation.info.minimum.y);
|
_minimum.setProperty(1, visitation.info.minimum.y);
|
||||||
_minimum.setProperty(2, visitation.info.minimum.z);
|
_minimum.setProperty(2, visitation.info.minimum.z);
|
||||||
_info.setProperty(_sizeHandle, visitation.info.size);
|
_info.setProperty(_sizeHandle, visitation.info.size);
|
||||||
_info.setProperty(_isLeafHandle, visitation.info.isLeaf);
|
_info.setProperty(_isLeafHandle, visitation.info.isLeaf);
|
||||||
_visitor = &visitation.visitor;
|
_visitation = &visitation;
|
||||||
_guideFunction.call(QScriptValue(), _arguments);
|
_guideFunction.call(QScriptValue(), _arguments);
|
||||||
|
if (_guideFunction.engine()->hasUncaughtException()) {
|
||||||
|
qDebug() << "Script error: " << _guideFunction.engine()->uncaughtException().toString() << "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetavoxelVisitation::allNodesLeaves() const {
|
bool MetavoxelVisitation::allNodesLeaves() const {
|
||||||
|
|
|
@ -156,18 +156,21 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static QScriptValue getAttributes(QScriptContext* context, QScriptEngine* engine);
|
||||||
static QScriptValue visit(QScriptContext* context, QScriptEngine* engine);
|
static QScriptValue visit(QScriptContext* context, QScriptEngine* engine);
|
||||||
|
|
||||||
QScriptValue _guideFunction;
|
QScriptValue _guideFunction;
|
||||||
QScriptString _minimumHandle;
|
QScriptString _minimumHandle;
|
||||||
QScriptString _sizeHandle;
|
QScriptString _sizeHandle;
|
||||||
|
QScriptString _attributeValuesHandle;
|
||||||
QScriptString _isLeafHandle;
|
QScriptString _isLeafHandle;
|
||||||
QScriptValueList _arguments;
|
QScriptValueList _arguments;
|
||||||
|
QScriptValue _getAttributesFunction;
|
||||||
QScriptValue _visitFunction;
|
QScriptValue _visitFunction;
|
||||||
QScriptValue _info;
|
QScriptValue _info;
|
||||||
QScriptValue _minimum;
|
QScriptValue _minimum;
|
||||||
|
|
||||||
MetavoxelVisitor* _visitor;
|
MetavoxelVisitation* _visitation;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Contains the state associated with a visit to a metavoxel system.
|
/// Contains the state associated with a visit to a metavoxel system.
|
||||||
|
|
Loading…
Reference in a new issue