bool QPositionNode::eventFilter(QObject* obj, QEvent* event) { if( event->type() == QEvent::DynamicPropertyChange ) { QDynamicPropertyChangeEvent* ev = static_cast<QDynamicPropertyChangeEvent*>(event); if( ev->propertyName() == "Position" ) { QVec3f pos = obj->property("Position").value<QVec3f>(); savePosition( pos.X, pos.Y, pos.Z ); obj->setProperty("__AbsoluteTransformation", QVariant::fromValue(QMatrix4f::TransMat( pos.X, pos.Y, pos.Z) ) ); } if( ev->propertyName() == "Scale" ) { // No scale allowed obj->setProperty("Scale", QVariant::fromValue(QVec3f(1, 1, 1)) ); } // Set absolute transformation to the relative one but don't apply it to the xml data if( ev->propertyName() == "__RelativeTransformation" ) { QMatrix4f mat = obj->property("__RelativeTransformation").value<QMatrix4f>(); obj->setProperty("__AbsoluteTransformation", QVariant::fromValue(mat) ); } } return QXmlTreeNode::eventFilter(obj, event); }
void Vec3fProperty::setValue(const QVariant& value) { if (value.type() == QVariant::String) { QString v = value.toString(); QRegExp rx("([+-]?([0-9]*[\\.])?[0-9]+(e[+-]?[0-9]+)?)"); rx.setCaseSensitivity(Qt::CaseInsensitive); int count = 0; int pos = 0; float x = 0.0f, y = 0.0f, z = 0.0f; while ((pos = rx.indexIn(v, pos)) != -1) { if (count == 0) x = rx.cap(1).toDouble(); else if (count == 1) y = rx.cap(1).toDouble(); else if (count == 2) z = rx.cap(1).toDouble(); else if (count > 2) break; ++count; pos += rx.matchedLength(); } m_x->setProperty("x", x); m_y->setProperty("y", y); m_z->setProperty("z", z); Property::setValue(QVariant::fromValue(QVec3f(x, y, z))); } else Property::setValue(value); }
QVec3f QSceneNode::scale() const { return QVec3f( roundIt( m_xmlNode.attribute("sx", "1.0").remove('f').toFloat(), 5 ), roundIt( m_xmlNode.attribute("sy", "1.0").remove('f').toFloat(), 5 ), roundIt( m_xmlNode.attribute("sz", "1.0").remove('f').toFloat(), 5 )); }
QVec3f QSceneNode::rotation() const { return QVec3f( roundIt( m_xmlNode.attribute("rx", "0.0").remove('f').toFloat(), 5 ), roundIt( m_xmlNode.attribute("ry", "0.0").remove('f').toFloat(), 5 ), roundIt( m_xmlNode.attribute("rz", "0.0").remove('f').toFloat(), 5 )); }
QVec3f QSceneNode::position() const { return QVec3f( roundIt( m_xmlNode.attribute("tx", "0.0").remove('f').toFloat(), 5 ), roundIt( m_xmlNode.attribute("ty", "0.0").remove('f').toFloat(), 5 ), roundIt( m_xmlNode.attribute("tz", "0.0").remove('f').toFloat(), 5 )); }
QPositionNode::QPositionNode(const QDomElement& xmlNode, int row, QXmlTreeModel* model, QXmlTreeNode* parent) : QXmlTreeNode(xmlNode, row, model, parent), m_dynamicProperty(false) { QString data; QTextStream stream(&data); xmlNode.save(stream, 4); m_entityID = GameEngine::entityWorldID( qPrintable(parent->property("Name").toString()) ); GameEngine::setComponentData(m_entityID, qPrintable( xmlNode.tagName() ), qPrintable(data)); QXmlTreeNode* root = static_cast<AttachmentTreeModel*>(model)->sceneNodeParent(); // If the entity has no position we have to create one for the crowd particle if( !root->property("Position").isValid() ) { QVec3f pos( m_xmlNode.attribute("x").toFloat(), m_xmlNode.attribute("y").toFloat(), m_xmlNode.attribute("z").toFloat() ); // Since the parent doesn't have a position yet we create one dynamically (not necessary if the particle is a child of // an entity created by an attachment of a Horde3D scene graph node ) m_dynamicProperty = true; root->setProperty( "Position", QVariant::fromValue(pos) ); // We have to add scale too, otherwise the transformation changes in the editor are not possible root->setProperty( "Scale", QVariant::fromValue( QVec3f(1, 1, 1) ) ); root->installEventFilter(this); QVariant transProp = root->property("__AbsoluteTransformation"); if( !transProp.isValid() ) { root->setProperty("__AbsoluteTransformation", QVariant::fromValue(QMatrix4f::TransMat( pos.X, pos.Y, pos.Z) ) ); root->setProperty("__RelativeTransformation", QVariant::fromValue(QMatrix4f::TransMat( pos.X, pos.Y, pos.Z) ) ); } } else // Remove any position attribute, since the position should be used from the scene node { m_xmlNode.removeAttribute("x"); m_xmlNode.removeAttribute("y"); m_xmlNode.removeAttribute("z"); } }
void Vec3fProperty::setX(float x) { Property::setValue(QVariant::fromValue(QVec3f(x, y(), z()))); }
void Vec3fProperty::setZ(float z) { Property::setValue(QVariant::fromValue(QVec3f(x(), y(), z))); }
void Vec3fProperty::setY(float y) { Property::setValue(QVariant::fromValue(QVec3f(x(), y, z()))); }
QVec3f QEmitterNode::force() const { return QVec3f(m_xmlNode.attribute("forceX").toFloat(), m_xmlNode.attribute("forceY").toFloat(), m_xmlNode.attribute("forceZ").toFloat()); }