mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 09:23:17 +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");
|
||||
}
|
||||
|
||||
AttributeRegistry::getInstance()->configureScriptEngine(&_scriptEngine);
|
||||
|
||||
MetavoxelPath p1;
|
||||
p1 += 7;
|
||||
p1 += 7;
|
||||
|
@ -41,6 +43,13 @@ void MetavoxelSystem::init() {
|
|||
|
||||
QScriptValue guideFunction = _scriptEngine.evaluate(
|
||||
"(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);"
|
||||
"})");
|
||||
_data.setAttributeValue(MetavoxelPath(), AttributeValue(AttributeRegistry::getInstance()->getGuideAttribute(),
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <QScriptEngine>
|
||||
|
||||
#include "AttributeRegistry.h"
|
||||
#include "MetavoxelData.h"
|
||||
|
||||
|
@ -17,6 +19,14 @@ AttributeRegistry::AttributeRegistry() :
|
|||
_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& pointer = _attributes[attribute->getName()];
|
||||
if (!pointer) {
|
||||
|
@ -25,6 +35,11 @@ AttributePointer AttributeRegistry::registerAttribute(AttributePointer attribute
|
|||
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) :
|
||||
_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() {
|
||||
|
@ -106,6 +122,10 @@ bool QRgbAttribute::merge(void*& parent, void* children[]) const {
|
|||
return allChildrenEqual;
|
||||
}
|
||||
|
||||
void* QRgbAttribute::createFromScript(const QScriptValue& value, QScriptEngine* engine) const {
|
||||
return encodeInline((QRgb)value.toUInt32());
|
||||
}
|
||||
|
||||
PolymorphicData::~PolymorphicData() {
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,17 @@
|
|||
#include <QColor>
|
||||
#include <QExplicitlySharedDataPointer>
|
||||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QSharedData>
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
#include "Bitstream.h"
|
||||
|
||||
class QScriptContext;
|
||||
class QScriptEngine;
|
||||
class QScriptValue;
|
||||
|
||||
class Attribute;
|
||||
|
||||
typedef QSharedPointer<Attribute> AttributePointer;
|
||||
|
@ -31,6 +36,9 @@ public:
|
|||
|
||||
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.
|
||||
/// \return either the pointer passed as an argument, if the attribute wasn't already registered, or the existing
|
||||
/// attribute
|
||||
|
@ -55,6 +63,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
static QScriptValue getAttribute(QScriptContext* context, QScriptEngine* engine);
|
||||
|
||||
static AttributeRegistry _instance;
|
||||
|
||||
QHash<QString, AttributePointer> _attributes;
|
||||
|
@ -114,15 +124,17 @@ public:
|
|||
};
|
||||
|
||||
/// Represents a registered attribute.
|
||||
class Attribute {
|
||||
class Attribute : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static const int MERGE_COUNT = 8;
|
||||
|
||||
Attribute(const QString& name);
|
||||
virtual ~Attribute();
|
||||
|
||||
const QString& getName() const { return _name; }
|
||||
Q_INVOKABLE QString getName() const { return objectName(); }
|
||||
|
||||
void* create() const { return create(getDefaultValue()); }
|
||||
virtual void* create(void* copy) const = 0;
|
||||
|
@ -139,9 +151,7 @@ public:
|
|||
|
||||
virtual void* getDefaultValue() const = 0;
|
||||
|
||||
private:
|
||||
|
||||
QString _name;
|
||||
virtual void* createFromScript(const QScriptValue& value, QScriptEngine* engine) const { return create(); }
|
||||
};
|
||||
|
||||
/// A simple attribute class that stores its values inline.
|
||||
|
@ -193,6 +203,8 @@ public:
|
|||
QRgbAttribute(const QString& name, QRgb defaultValue = QRgb());
|
||||
|
||||
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.
|
||||
|
|
|
@ -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) {
|
||||
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 minimumValue = infoValue.property(guide->_minimumHandle);
|
||||
info.minimum = glm::vec3(minimumValue.property(0).toNumber(), minimumValue.property(1).toNumber(),
|
||||
minimumValue.property(2).toNumber());
|
||||
info.size = infoValue.property(guide->_sizeHandle).toNumber();
|
||||
info.isLeaf = infoValue.property(guide->_isLeafHandle).toBool();
|
||||
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() };
|
||||
|
||||
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) :
|
||||
_guideFunction(guideFunction),
|
||||
_minimumHandle(guideFunction.engine()->toStringHandle("minimum")),
|
||||
_sizeHandle(guideFunction.engine()->toStringHandle("size")),
|
||||
_attributeValuesHandle(guideFunction.engine()->toStringHandle("attributeValues")),
|
||||
_isLeafHandle(guideFunction.engine()->toStringHandle("isLeaf")),
|
||||
_getAttributesFunction(guideFunction.engine()->newFunction(getAttributes, 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("visit", _visitFunction);
|
||||
_arguments[0].setProperty("visitor", visitor);
|
||||
_arguments[0].setProperty("info", _info);
|
||||
|
@ -221,14 +257,19 @@ PolymorphicData* ScriptedMetavoxelGuide::clone() const {
|
|||
}
|
||||
|
||||
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(1, visitation.info.minimum.y);
|
||||
_minimum.setProperty(2, visitation.info.minimum.z);
|
||||
_info.setProperty(_sizeHandle, visitation.info.size);
|
||||
_info.setProperty(_isLeafHandle, visitation.info.isLeaf);
|
||||
_visitor = &visitation.visitor;
|
||||
_visitation = &visitation;
|
||||
_guideFunction.call(QScriptValue(), _arguments);
|
||||
if (_guideFunction.engine()->hasUncaughtException()) {
|
||||
qDebug() << "Script error: " << _guideFunction.engine()->uncaughtException().toString() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool MetavoxelVisitation::allNodesLeaves() const {
|
||||
|
|
|
@ -156,18 +156,21 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
static QScriptValue getAttributes(QScriptContext* context, QScriptEngine* engine);
|
||||
static QScriptValue visit(QScriptContext* context, QScriptEngine* engine);
|
||||
|
||||
QScriptValue _guideFunction;
|
||||
QScriptString _minimumHandle;
|
||||
QScriptString _sizeHandle;
|
||||
QScriptString _attributeValuesHandle;
|
||||
QScriptString _isLeafHandle;
|
||||
QScriptValueList _arguments;
|
||||
QScriptValue _getAttributesFunction;
|
||||
QScriptValue _visitFunction;
|
||||
QScriptValue _info;
|
||||
QScriptValue _minimum;
|
||||
|
||||
MetavoxelVisitor* _visitor;
|
||||
MetavoxelVisitation* _visitation;
|
||||
};
|
||||
|
||||
/// Contains the state associated with a visit to a metavoxel system.
|
||||
|
|
Loading…
Reference in a new issue