Working on scripty bits.

This commit is contained in:
Andrzej Kapolka 2013-12-16 17:53:53 -08:00
parent 6888dc4eeb
commit 6385a73379
7 changed files with 114 additions and 76 deletions

View file

@ -135,7 +135,7 @@ if (LIBOVR_FOUND AND NOT DISABLE_LIBOVR)
target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES})
endif (LIBOVR_FOUND AND NOT DISABLE_LIBOVR) endif (LIBOVR_FOUND AND NOT DISABLE_LIBOVR)
qt5_use_modules(${TARGET_NAME} Core Gui Multimedia Network OpenGL Svg WebKit WebKitWidgets) qt5_use_modules(${TARGET_NAME} Core Gui Multimedia Network OpenGL Script Svg WebKit WebKitWidgets)
# include headers for interface and InterfaceConfig. # include headers for interface and InterfaceConfig.
include_directories( include_directories(

View file

@ -39,6 +39,13 @@ void MetavoxelSystem::init() {
_data.setAttributeValue(p1, AttributeValue(color, encodeInline(qRgba(0xFF, 0xFF, 0xFF, 0xFF)))); _data.setAttributeValue(p1, AttributeValue(color, encodeInline(qRgba(0xFF, 0xFF, 0xFF, 0xFF))));
QScriptValue guideFunction = _scriptEngine.evaluate(
"(function(visitation) { "
" visitation.visitor.visit(visitation.info);"
"})");
_data.setAttributeValue(MetavoxelPath(), AttributeValue(AttributeRegistry::getInstance()->getGuideAttribute(),
encodeInline(PolymorphicDataPointer(new ScriptedMetavoxelGuide(guideFunction)))));
_buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); _buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw);
_buffer.create(); _buffer.create();
} }

View file

@ -10,6 +10,7 @@
#define __interface__MetavoxelSystem__ #define __interface__MetavoxelSystem__
#include <QOpenGLBuffer> #include <QOpenGLBuffer>
#include <QScriptEngine>
#include <QVector> #include <QVector>
#include <glm/glm.hpp> #include <glm/glm.hpp>
@ -50,6 +51,7 @@ private:
static ProgramObject _program; static ProgramObject _program;
static int _pointScaleLocation; static int _pointScaleLocation;
QScriptEngine _scriptEngine;
MetavoxelData _data; MetavoxelData _data;
QVector<Point> _points; QVector<Point> _points;
PointVisitor _pointVisitor; PointVisitor _pointVisitor;

View file

@ -109,7 +109,7 @@ bool QRgbAttribute::merge(void*& parent, void* children[]) const {
PolymorphicData::~PolymorphicData() { PolymorphicData::~PolymorphicData() {
} }
template<> PolymorphicData* QSharedDataPointer<PolymorphicData>::clone() { template<> PolymorphicData* QExplicitlySharedDataPointer<PolymorphicData>::clone() {
return d->clone(); return d->clone();
} }

View file

@ -10,9 +10,9 @@
#define __interface__AttributeRegistry__ #define __interface__AttributeRegistry__
#include <QColor> #include <QColor>
#include <QExplicitlySharedDataPointer>
#include <QHash> #include <QHash>
#include <QSharedData> #include <QSharedData>
#include <QSharedDataPointer>
#include <QSharedPointer> #include <QSharedPointer>
#include <QString> #include <QString>
@ -247,9 +247,9 @@ public:
virtual PolymorphicData* clone() const = 0; virtual PolymorphicData* clone() const = 0;
}; };
template<> PolymorphicData* QSharedDataPointer<PolymorphicData>::clone(); template<> PolymorphicData* QExplicitlySharedDataPointer<PolymorphicData>::clone();
typedef QSharedDataPointer<PolymorphicData> PolymorphicDataPointer; typedef QExplicitlySharedDataPointer<PolymorphicData> PolymorphicDataPointer;
/// Provides polymorphic streaming and averaging. /// Provides polymorphic streaming and averaging.
class PolymorphicAttribute : public InlineAttribute<PolymorphicDataPointer> { class PolymorphicAttribute : public InlineAttribute<PolymorphicDataPointer> {

View file

@ -6,6 +6,9 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
// //
#include <QScriptEngine>
#include <QtDebug>
#include "MetavoxelData.h" #include "MetavoxelData.h"
MetavoxelData::~MetavoxelData() { MetavoxelData::~MetavoxelData() {
@ -15,66 +18,23 @@ MetavoxelData::~MetavoxelData() {
} }
} }
class Visitation {
public:
MetavoxelVisitor& visitor;
QVector<MetavoxelNode*> nodes;
MetavoxelInfo info;
void apply();
protected:
bool allNodesLeaves() const;
};
const int X_MAXIMUM_FLAG = 1;
const int Y_MAXIMUM_FLAG = 2;
const int Z_MAXIMUM_FLAG = 4;
void Visitation::apply() {
info.isLeaf = allNodesLeaves();
if (!visitor.visit(info) || info.isLeaf) {
return;
}
Visitation nextVisitation = { visitor, QVector<MetavoxelNode*>(nodes.size()),
{ glm::vec3(), info.size * 0.5f, QVector<AttributeValue>(nodes.size()) } };
for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) {
for (int j = 0; j < nodes.size(); j++) {
MetavoxelNode* node = nodes.at(j);
MetavoxelNode* child = node ? node->getChild(i) : NULL;
nextVisitation.info.attributeValues[j] = ((nextVisitation.nodes[j] = child)) ?
child->getAttributeValue(info.attributeValues[j].getAttribute()) : info.attributeValues[j];
}
nextVisitation.info.minimum = 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);
nextVisitation.apply();
}
}
bool Visitation::allNodesLeaves() const {
foreach (MetavoxelNode* node, nodes) {
if (node != NULL && !node->isLeaf()) {
return false;
}
}
return true;
}
void MetavoxelData::guide(MetavoxelVisitor& visitor) { void MetavoxelData::guide(MetavoxelVisitor& visitor) {
// start with the root values/defaults // start with the root values/defaults (plus the guide attribute)
const float TOP_LEVEL_SIZE = 1.0f; const float TOP_LEVEL_SIZE = 1.0f;
const QVector<AttributePointer>& attributes = visitor.getAttributes(); const QVector<AttributePointer>& attributes = visitor.getAttributes();
Visitation firstVisitation = { visitor, QVector<MetavoxelNode*>(attributes.size()), MetavoxelVisitation firstVisitation = { visitor, QVector<MetavoxelNode*>(attributes.size() + 1),
{ glm::vec3(), TOP_LEVEL_SIZE, QVector<AttributeValue>(attributes.size()) } }; { glm::vec3(), TOP_LEVEL_SIZE, QVector<AttributeValue>(attributes.size() + 1) } };
for (int i = 0; i < attributes.size(); i++) { for (int i = 0; i < attributes.size(); i++) {
MetavoxelNode* node = _roots.value(attributes[i]); MetavoxelNode* node = _roots.value(attributes[i]);
firstVisitation.nodes[i] = node; firstVisitation.nodes[i] = node;
firstVisitation.info.attributeValues[i] = node ? node->getAttributeValue(attributes[i]) : attributes[i]; firstVisitation.info.attributeValues[i] = node ? node->getAttributeValue(attributes[i]) : attributes[i];
} }
firstVisitation.apply(); 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<MetavoxelGuide*>(firstVisitation.info.attributeValues.last().getInlineValue<
PolymorphicDataPointer>().data())->guide(firstVisitation);
} }
void MetavoxelData::setAttributeValue(const MetavoxelPath& path, const AttributeValue& attributeValue) { void MetavoxelData::setAttributeValue(const MetavoxelPath& path, const AttributeValue& attributeValue) {
@ -169,15 +129,6 @@ void MetavoxelNode::destroy(const AttributePointer& attribute) {
} }
} }
bool MetavoxelNode::allChildrenEqual(const AttributePointer& attribute) const {
for (int i = 0; i < CHILD_COUNT; i++) {
if (!attribute->equal(_attributeValue, _children[i]->_attributeValue)) {
return false;
}
}
return true;
}
void MetavoxelNode::clearChildren(const AttributePointer& attribute) { void MetavoxelNode::clearChildren(const AttributePointer& attribute) {
for (int i = 0; i < CHILD_COUNT; i++) { for (int i = 0; i < CHILD_COUNT; i++) {
if (_children[i]) { if (_children[i]) {
@ -206,15 +157,78 @@ PolymorphicData* DefaultMetavoxelGuide::clone() const {
return new DefaultMetavoxelGuide(); return new DefaultMetavoxelGuide();
} }
void DefaultMetavoxelGuide::guide(MetavoxelTour& tour) const { const int X_MAXIMUM_FLAG = 1;
const int Y_MAXIMUM_FLAG = 2;
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) {
return;
}
MetavoxelVisitation nextVisitation = { visitation.visitor, QVector<MetavoxelNode*>(visitation.nodes.size()),
{ glm::vec3(), visitation.info.size * 0.5f, QVector<AttributeValue>(visitation.nodes.size()) } };
for (int i = 0; i < MetavoxelNode::CHILD_COUNT; i++) {
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.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<MetavoxelGuide*>(nextVisitation.info.attributeValues.last().getInlineValue<
PolymorphicDataPointer>().data())->guide(nextVisitation);
}
} }
ScriptedMetavoxelGuide::ScriptedMetavoxelGuide(const QScriptValue& guideFunction) : _guideFunction(guideFunction) { QScriptValue ScriptedMetavoxelGuide::visit(QScriptContext* context, QScriptEngine* engine) {
qDebug() << context->callee().data().toVariant() << " oh hi thar\n";
MetavoxelInfo info;
QScriptValue infoValue = context->argument(0);
return QScriptValue();
}
ScriptedMetavoxelGuide::ScriptedMetavoxelGuide(const QScriptValue& guideFunction) :
_guideFunction(guideFunction),
_sizeHandle(guideFunction.engine()->toStringHandle("size")),
_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("visit", _visitFunction);
_arguments[0].setProperty("visitor", visitor);
_arguments[0].setProperty("info", _info);
_info.setProperty("minimum", _minimum);
} }
PolymorphicData* ScriptedMetavoxelGuide::clone() const { PolymorphicData* ScriptedMetavoxelGuide::clone() const {
return new ScriptedMetavoxelGuide(_guideFunction); return new ScriptedMetavoxelGuide(_guideFunction);
} }
void ScriptedMetavoxelGuide::guide(MetavoxelTour& tour) const { void ScriptedMetavoxelGuide::guide(MetavoxelVisitation& visitation) {
_visitFunction.setData(_guideFunction.engine()->newVariant(QVariant::fromValue<void*>(this)));
_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);
_guideFunction.call(QScriptValue(), _arguments);
}
bool MetavoxelVisitation::allNodesLeaves() const {
foreach (MetavoxelNode* node, nodes) {
if (node != NULL && !node->isLeaf()) {
return false;
}
}
return true;
} }

View file

@ -11,6 +11,7 @@
#include <QBitArray> #include <QBitArray>
#include <QHash> #include <QHash>
#include <QScriptString>
#include <QScriptValue> #include <QScriptValue>
#include <QVector> #include <QVector>
@ -18,9 +19,11 @@
#include "AttributeRegistry.h" #include "AttributeRegistry.h"
class QScriptContext;
class MetavoxelNode; class MetavoxelNode;
class MetavoxelPath; class MetavoxelPath;
class MetavoxelTour; class MetavoxelVisitation;
class MetavoxelVisitor; class MetavoxelVisitor;
/// The base metavoxel representation shared between server and client. /// The base metavoxel representation shared between server and client.
@ -71,7 +74,6 @@ public:
private: private:
Q_DISABLE_COPY(MetavoxelNode) Q_DISABLE_COPY(MetavoxelNode)
bool allChildrenEqual(const AttributePointer& attribute) const;
void clearChildren(const AttributePointer& attribute); void clearChildren(const AttributePointer& attribute);
void* _attributeValue; void* _attributeValue;
@ -130,7 +132,7 @@ class MetavoxelGuide : public PolymorphicData {
public: public:
/// Guides the specified visitor to the contained voxels. /// Guides the specified visitor to the contained voxels.
virtual void guide(MetavoxelTour& tour) const = 0; virtual void guide(MetavoxelVisitation& visitation) = 0;
}; };
/// Guides visitors through the explicit content of the system. /// Guides visitors through the explicit content of the system.
@ -139,7 +141,7 @@ public:
virtual PolymorphicData* clone() const; virtual PolymorphicData* clone() const;
virtual void guide(MetavoxelTour& tour) const; virtual void guide(MetavoxelVisitation& visitation);
}; };
/// Represents a guide implemented in Javascript. /// Represents a guide implemented in Javascript.
@ -150,16 +152,29 @@ public:
virtual PolymorphicData* clone() const; virtual PolymorphicData* clone() const;
virtual void guide(MetavoxelTour& tour) const; virtual void guide(MetavoxelVisitation& visitation);
private: private:
static QScriptValue visit(QScriptContext* context, QScriptEngine* engine);
QScriptValue _guideFunction; QScriptValue _guideFunction;
QScriptString _sizeHandle;
QScriptValueList _arguments;
QScriptValue _visitFunction;
QScriptValue _info;
QScriptValue _minimum;
}; };
/// Contains the state associated with a tour of a metavoxel system. /// Contains the state associated with a visit to a metavoxel system.
class MetavoxelTour { class MetavoxelVisitation {
public:
MetavoxelVisitor& visitor;
QVector<MetavoxelNode*> nodes;
MetavoxelInfo info;
bool allNodesLeaves() const;
}; };
#endif /* defined(__interface__MetavoxelData__) */ #endif /* defined(__interface__MetavoxelData__) */