More work on spanners.

This commit is contained in:
Andrzej Kapolka 2014-02-20 17:18:15 -08:00
parent 09677b06f2
commit b408e31d91
9 changed files with 101 additions and 34 deletions

View file

@ -218,7 +218,6 @@ int MetavoxelClient::parseData(const QByteArray& packet) {
}
void MetavoxelClient::sendData(const QByteArray& data) {
QMutexLocker locker(&_node->getMutex());
NodeList::getInstance()->writeDatagram(data, _node);
}

View file

@ -151,6 +151,13 @@ QVariant MetavoxelEditor::getValue() const {
return editor ? editor->metaObject()->userProperty().read(editor) : QVariant();
}
void MetavoxelEditor::detachValue() {
SharedObjectEditor* editor = qobject_cast<SharedObjectEditor*>(_valueArea->widget());
if (editor) {
editor->detachObject();
}
}
bool MetavoxelEditor::eventFilter(QObject* watched, QEvent* event) {
// pass along to the active tool
MetavoxelTool* tool = getActiveTool();
@ -522,6 +529,7 @@ void InsertSpannerTool::simulate(float deltaTime) {
}
void InsertSpannerTool::render() {
_editor->detachValue();
Spanner* spanner = static_cast<Spanner*>(_editor->getValue().value<SharedObjectPointer>().data());
Transformable* transformable = qobject_cast<Transformable*>(spanner);
if (transformable) {
@ -532,6 +540,7 @@ void InsertSpannerTool::render() {
glm::vec3 rayDirection = inverseRotation * Application::getInstance()->getMouseRayDirection();
float position = _editor->getGridPosition();
float distance = (position - rayOrigin.z) / rayDirection.z;
transformable->setTranslation(rotation * glm::vec3(glm::vec2(rayOrigin + rayDirection * distance), position));
}
const float SPANNER_ALPHA = 0.25f;

View file

@ -38,6 +38,7 @@ public:
glm::quat getGridRotation() const;
QVariant getValue() const;
void detachValue();
virtual bool eventFilter(QObject* watched, QEvent* event);

View file

@ -355,17 +355,7 @@ Bitstream& Bitstream::operator>>(QObject*& object) {
object = NULL;
return *this;
}
object = metaObject->newInstance();
for (int i = 0; i < metaObject->propertyCount(); i++) {
QMetaProperty property = metaObject->property(i);
if (!property.isStored(object)) {
continue;
}
const TypeStreamer* streamer = getTypeStreamers().value(property.userType());
if (streamer) {
property.write(object, streamer->read(*this));
}
}
readProperties(object = metaObject->newInstance());
return *this;
}
@ -476,13 +466,34 @@ Bitstream& Bitstream::operator>(QScriptString& string) {
}
Bitstream& Bitstream::operator<(const SharedObjectPointer& object) {
return *this << object.data();
if (!object) {
return *this << (int)0;
}
return *this << object->getID() << (QObject*)object.data();
}
Bitstream& Bitstream::operator>(SharedObjectPointer& object) {
QObject* rawObject;
*this >> rawObject;
object = static_cast<SharedObject*>(rawObject);
int id;
*this >> id;
if (id == 0) {
object = SharedObjectPointer();
return *this;
}
QPointer<SharedObject>& pointer = _transientSharedObjects[id];
if (pointer) {
const QMetaObject* metaObject;
_metaObjectStreamer >> metaObject;
if (metaObject != pointer->metaObject()) {
qWarning() << "Class mismatch: " << pointer->metaObject()->className() << metaObject->className();
}
readProperties(pointer.data());
} else {
QObject* rawObject;
*this >> rawObject;
pointer = static_cast<SharedObject*>(rawObject);
}
object = static_cast<SharedObject*>(pointer.data());
return *this;
}
@ -492,6 +503,20 @@ void Bitstream::clearSharedObject() {
emit sharedObjectCleared(_sharedObjectStreamer.takePersistentID(object));
}
void Bitstream::readProperties(QObject* object) {
const QMetaObject* metaObject = object->metaObject();
for (int i = 0; i < metaObject->propertyCount(); i++) {
QMetaProperty property = metaObject->property(i);
if (!property.isStored(object)) {
continue;
}
const TypeStreamer* streamer = getTypeStreamers().value(property.userType());
if (streamer) {
property.write(object, streamer->read(*this));
}
}
}
QHash<QByteArray, const QMetaObject*>& Bitstream::getMetaObjects() {
static QHash<QByteArray, const QMetaObject*> metaObjects;
return metaObjects;

View file

@ -11,6 +11,7 @@
#include <QHash>
#include <QMetaType>
#include <QPointer>
#include <QScriptString>
#include <QSharedPointer>
#include <QVariant>
@ -317,6 +318,8 @@ private slots:
void clearSharedObject();
private:
void readProperties(QObject* object);
QDataStream& _underlying;
quint8 _byte;
@ -328,6 +331,8 @@ private:
RepeatedValueStreamer<QScriptString> _scriptStringStreamer;
RepeatedValueStreamer<SharedObjectPointer> _sharedObjectStreamer;
QHash<int, QPointer<SharedObject> > _transientSharedObjects;
static QHash<QByteArray, const QMetaObject*>& getMetaObjects();
static QMultiHash<const QMetaObject*, const QMetaObject*>& getMetaObjectSubClasses();
static QHash<int, const TypeStreamer*>& getTypeStreamers();

View file

@ -548,7 +548,7 @@ void SpannerVisitor::prepare() {
}
bool SpannerVisitor::visit(MetavoxelInfo& info) {
for (int i = info.inputValues.size() - _spannerInputCount; i < info.inputValues.size(); i++) {
for (int i = _inputs.size() - _spannerInputCount; i < _inputs.size(); i++) {
foreach (const SharedObjectPointer& object, info.inputValues.at(i).getInlineValue<SharedObjectSet>()) {
Spanner* spanner = static_cast<Spanner*>(object.data());
if (spanner->testAndSetVisited()) {
@ -862,9 +862,6 @@ void SpannerRenderer::render(float alpha) {
}
Transformable::Transformable() : _scale(1.0f) {
connect(this, SIGNAL(translationChanged(const glm::vec3&)), SLOT(updateBounds()));
connect(this, SIGNAL(rotationChanged(const glm::vec3&)), SLOT(updateBounds()));
connect(this, SIGNAL(scaleChanged(float)), SLOT(updateBounds()));
}
void Transformable::setTranslation(const glm::vec3& translation) {
@ -885,12 +882,6 @@ void Transformable::setScale(float scale) {
}
}
void Transformable::updateBounds() {
// temporary fake bounds
glm::vec3 scaleVector(_scale, _scale, _scale);
setBounds(Box(_translation - scaleVector, _translation + scaleVector));
}
StaticModel::StaticModel() {
}

View file

@ -360,10 +360,6 @@ signals:
void rotationChanged(const glm::vec3& rotation);
void scaleChanged(float scale);
protected slots:
virtual void updateBounds();
private:
glm::vec3 _translation;

View file

@ -18,7 +18,7 @@
REGISTER_META_OBJECT(SharedObject)
SharedObject::SharedObject() : _referenceCount(0) {
SharedObject::SharedObject() : _id(++_lastID), _referenceCount(0) {
}
void SharedObject::incrementReferenceCount() {
@ -74,6 +74,16 @@ bool SharedObject::equals(const SharedObject* other) const {
return true;
}
void SharedObject::dump(QDebug debug) const {
debug << this;
const QMetaObject* metaObject = this->metaObject();
for (int i = 0; i < metaObject->propertyCount(); i++) {
debug << metaObject->property(i).name() << metaObject->property(i).read(this);
}
}
int SharedObject::_lastID = 0;
SharedObjectEditor::SharedObjectEditor(const QMetaObject* metaObject, bool nullable, QWidget* parent) : QWidget(parent) {
QVBoxLayout* layout = new QVBoxLayout();
layout->setAlignment(Qt::AlignTop);
@ -110,6 +120,22 @@ void SharedObjectEditor::setObject(const SharedObjectPointer& object) {
}
}
void SharedObjectEditor::detachObject() {
SharedObject* oldObject = _object.data();
if (!_object.detach()) {
return;
}
oldObject->disconnect(this);
const QMetaObject* metaObject = _object->metaObject();
QFormLayout* form = static_cast<QFormLayout*>(layout()->itemAt(1));
for (int i = 0; i < form->rowCount(); i++) {
QWidget* widget = form->itemAt(i, QFormLayout::FieldRole)->widget();
QMetaProperty property = metaObject->property(widget->property("propertyIndex").toInt());
connect(_object.data(), signal(property.notifySignal().methodSignature()), SLOT(updateProperty()));
}
}
const QMetaObject* getOwningAncestor(const QMetaObject* metaObject, int propertyIndex) {
while (propertyIndex < metaObject->propertyOffset()) {
metaObject = metaObject->superClass();
@ -182,7 +208,7 @@ void SharedObjectEditor::propertyChanged() {
if (widget != sender()) {
continue;
}
_object.detach();
detachObject();
QObject* object = _object.data();
QMetaProperty property = object->metaObject()->property(widget->property("propertyIndex").toInt());
QByteArray valuePropertyName = QItemEditorFactory::defaultFactory()->valuePropertyName(property.userType());

View file

@ -13,6 +13,7 @@
#include <QObject>
#include <QSet>
#include <QWidget>
#include <QtDebug>
class QComboBox;
@ -24,6 +25,8 @@ public:
Q_INVOKABLE SharedObject();
int getID() { return _id; }
int getReferenceCount() const { return _referenceCount; }
void incrementReferenceCount();
void decrementReferenceCount();
@ -34,6 +37,9 @@ public:
/// Tests this object for equality with another.
virtual bool equals(const SharedObject* other) const;
// Dumps the contents of this object to the debug output.
virtual void dump(QDebug debug = qDebug()) const;
signals:
/// Emitted when the reference count drops to one.
@ -41,7 +47,10 @@ signals:
private:
int _id;
int _referenceCount;
static int _lastID;
};
/// A pointer to a shared object.
@ -54,7 +63,8 @@ public:
T* data() const { return _data; }
void detach();
/// "Detaches" this object, making a new copy if its reference count is greater than one.
bool detach();
void swap(SharedObjectPointerTemplate<T>& other) { qSwap(_data, other._data); }
@ -98,11 +108,13 @@ template<class T> inline SharedObjectPointerTemplate<T>::~SharedObjectPointerTem
}
}
template<class T> inline void SharedObjectPointerTemplate<T>::detach() {
template<class T> inline bool SharedObjectPointerTemplate<T>::detach() {
if (_data && _data->getReferenceCount() > 1) {
_data->decrementReferenceCount();
(_data = _data->clone())->incrementReferenceCount();
return true;
}
return false;
}
template<class T> inline void SharedObjectPointerTemplate<T>::reset() {
@ -160,6 +172,9 @@ public:
const SharedObjectPointer& getObject() const { return _object; }
/// "Detaches" the object pointer, copying it if anyone else is holding a reference.
void detachObject();
public slots:
void setObject(const SharedObjectPointer& object);