diff options
57 files changed, 7254 insertions, 13 deletions
diff --git a/src/extras/animations/animations.pri b/src/extras/animations/animations.pri new file mode 100644 index 000000000..71d6099fc --- /dev/null +++ b/src/extras/animations/animations.pri @@ -0,0 +1,26 @@ +HEADERS += \ + $$PWD/qanimationcontroller.h \ + $$PWD/qanimationcontroller_p.h \ + $$PWD/qanimationgroup.h \ + $$PWD/qanimationgroup_p.h \ + $$PWD/qkeyframeanimation.h \ + $$PWD/qkeyframeanimation_p.h \ + $$PWD/qmorphinganimation.h \ + $$PWD/qmorphinganimation_p.h \ + $$PWD/qabstractanimation.h \ + $$PWD/qabstractanimation_p.h \ + $$PWD/qmorphtarget.h \ + $$PWD/qmorphtarget_p.h \ + $$PWD/qvertexblendanimation.h \ + $$PWD/qvertexblendanimation_p.h + +SOURCES += \ + $$PWD/qanimationcontroller.cpp \ + $$PWD/qanimationgroup.cpp \ + $$PWD/qkeyframeanimation.cpp \ + $$PWD/qmorphinganimation.cpp \ + $$PWD/qabstractanimation.cpp \ + $$PWD/qmorphtarget.cpp \ + $$PWD/qvertexblendanimation.cpp + +INCLUDEPATH += $$PWD diff --git a/src/extras/animations/qabstractanimation.cpp b/src/extras/animations/qabstractanimation.cpp new file mode 100644 index 000000000..f87455c18 --- /dev/null +++ b/src/extras/animations/qabstractanimation.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractanimation.h" +#include "Qt3DExtras/private/qabstractanimation_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QAbstractAnimationPrivate::QAbstractAnimationPrivate(QAbstractAnimation::AnimationType type) + : QObjectPrivate() + , m_animationType(type) + , m_position(0.0f) + , m_duration(0.0f) +{ + +} + +QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + +} + +QString QAbstractAnimation::animationName() const +{ + Q_D(const QAbstractAnimation); + return d->m_animationName; +} + +QAbstractAnimation::AnimationType QAbstractAnimation::animationType() const +{ + Q_D(const QAbstractAnimation); + return d->m_animationType; +} + +float QAbstractAnimation::position() const +{ + Q_D(const QAbstractAnimation); + return d->m_position; +} + +float QAbstractAnimation::duration() const +{ + Q_D(const QAbstractAnimation); + return d->m_duration; +} + +void QAbstractAnimation::setAnimationName(const QString &name) +{ + Q_D(QAbstractAnimation); + if (name != d->m_animationName) { + d->m_animationName = name; + emit animationNameChanged(name); + } +} + +void QAbstractAnimation::setPosition(float position) +{ + Q_D(QAbstractAnimation); + if (!qFuzzyCompare(position, d->m_position)) { + d->m_position = position; + emit positionChanged(position); + } +} + +void QAbstractAnimation::setDuration(float duration) +{ + Q_D(QAbstractAnimation); + if (!qFuzzyCompare(duration, d->m_duration)) { + d->m_duration = duration; + emit durationChanged(duration); + } +} + +} // Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/animations/qabstractanimation.h b/src/extras/animations/qabstractanimation.h new file mode 100644 index 000000000..242fe293a --- /dev/null +++ b/src/extras/animations/qabstractanimation.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QABSTRACTANIMATION_H +#define QT3DEXTRAS_QABSTRACTANIMATION_H + +#include <QtCore/qobject.h> +#include <QtCore/qvector.h> + +#include <Qt3DExtras/qt3dextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QAbstractAnimationPrivate; + +class QT3DEXTRASSHARED_EXPORT QAbstractAnimation : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString animationName READ animationName WRITE setAnimationName NOTIFY animationNameChanged) + Q_PROPERTY(QAbstractAnimation::AnimationType animationType READ animationType CONSTANT) + Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(float duration READ duration NOTIFY durationChanged) + +public: + enum AnimationType { + KeyframeAnimation = 1, + MorphingAnimation = 2, + VertexBlendAnimation = 3, + }; + + QString animationName() const; + QAbstractAnimation::AnimationType animationType() const; + float position() const; + float duration() const; + +public Q_SLOTS: + void setAnimationName(const QString &name); + void setPosition(float position); + +protected: + explicit QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = nullptr); + + void setDuration(float duration); + +Q_SIGNALS: + void animationNameChanged(const QString &name); + void positionChanged(float position); + void durationChanged(float duration); + +private: + Q_DECLARE_PRIVATE(QAbstractAnimation) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QABSTRACTANIMATION_H diff --git a/src/extras/animations/qabstractanimation_p.h b/src/extras/animations/qabstractanimation_p.h new file mode 100644 index 000000000..1370ef2c7 --- /dev/null +++ b/src/extras/animations/qabstractanimation_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QABSTRACTANIMATION_P_H +#define QT3DEXTRAS_QABSTRACTANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qobject_p.h> +#include <Qt3DExtras/QAbstractAnimation> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QAbstractAnimationPrivate : public QObjectPrivate +{ +public: + QAbstractAnimationPrivate(QAbstractAnimation::AnimationType type); + + QString m_animationName; + QAbstractAnimation::AnimationType m_animationType; + float m_position; + float m_duration; + + Q_DECLARE_PUBLIC(QAbstractAnimation) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_P_H diff --git a/src/extras/animations/qanimationcontroller.cpp b/src/extras/animations/qanimationcontroller.cpp new file mode 100644 index 000000000..adef3d45c --- /dev/null +++ b/src/extras/animations/qanimationcontroller.cpp @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanimationcontroller.h" +#include "qanimationgroup.h" + +#include <private/qanimationcontroller_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QAnimationControllerPrivate::QAnimationControllerPrivate() + : QObjectPrivate() + , m_activeAnimationGroup(0) + , m_position(0.0f) + , m_positionScale(1.0f) + , m_positionOffset(0.0f) + , m_entity(nullptr) + , m_recursive(true) +{ + +} + +void QAnimationControllerPrivate::updatePosition(float position) +{ + m_position = position; + if (m_activeAnimationGroup >= 0 && m_activeAnimationGroup < m_animationGroups.size()) { + const float pos = m_positionScale * position + m_positionOffset; + m_animationGroups[m_activeAnimationGroup]->setPosition(pos); + } +} + +QAnimationGroup *QAnimationControllerPrivate::findGroup(const QString &name) +{ + for (QAnimationGroup *g : m_animationGroups) { + if (g->name() == name) + return g; + } + return nullptr; +} + +void QAnimationControllerPrivate::extractAnimations() +{ + Q_Q(QAnimationController); + if (!m_entity) + return; + QList<Qt3DExtras::QAbstractAnimation *> animations + = m_entity->findChildren<Qt3DExtras::QAbstractAnimation *>(QString(), + m_recursive ? Qt::FindChildrenRecursively : Qt::FindDirectChildrenOnly); + if (animations.size() > 0) { + for (Qt3DExtras::QAbstractAnimation *a : animations) { + QAnimationGroup *group = findGroup(a->animationName()); + if (!group) { + group = new QAnimationGroup(q); + group->setName(a->animationName()); + m_animationGroups.push_back(group); + } + group->addAnimation(a); + } + } +} +void QAnimationControllerPrivate::clearAnimations() +{ + for (Qt3DExtras::QAnimationGroup *a : m_animationGroups) + a->deleteLater(); + m_animationGroups.clear(); + m_activeAnimationGroup = 0; +} + +QAnimationController::QAnimationController(QObject *parent) + : QObject(*new QAnimationControllerPrivate, parent) +{ + +} + +QVector<QAnimationGroup *> QAnimationController::animationGroupList() +{ + Q_D(QAnimationController); + return d->m_animationGroups; +} + +int QAnimationController::activeAnimationGroup() const +{ + Q_D(const QAnimationController); + return d->m_activeAnimationGroup; +} + +float QAnimationController::position() const +{ + Q_D(const QAnimationController); + return d->m_position; +} + +float QAnimationController::positionScale() const +{ + Q_D(const QAnimationController); + return d->m_positionScale; +} + +float QAnimationController::positionOffset() const +{ + Q_D(const QAnimationController); + return d->m_positionOffset; +} + +Qt3DCore::QEntity *QAnimationController::entity() const +{ + Q_D(const QAnimationController); + return d->m_entity; +} + +bool QAnimationController::recursive() const +{ + Q_D(const QAnimationController); + return d->m_recursive; +} + +void QAnimationController::setAnimationGroups(const QVector<QAnimationGroup *> &animationGroups) +{ + Q_D(QAnimationController); + d->m_animationGroups = animationGroups; + if (d->m_activeAnimationGroup >= d->m_animationGroups.size()) + d->m_activeAnimationGroup = 0; + d->updatePosition(d->m_position); +} + +void QAnimationController::addAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroup) +{ + Q_D(QAnimationController); + if (!d->m_animationGroups.contains(animationGroup)) + d->m_animationGroups.push_back(animationGroup); +} + +void QAnimationController::removeAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroup) +{ + Q_D(QAnimationController); + if (d->m_animationGroups.contains(animationGroup)) + d->m_animationGroups.removeAll(animationGroup); + if (d->m_activeAnimationGroup >= d->m_animationGroups.size()) + d->m_activeAnimationGroup = 0; +} + +void QAnimationController::setActiveAnimationGroup(int index) +{ + Q_D(QAnimationController); + if (d->m_activeAnimationGroup != index) { + d->m_activeAnimationGroup = index; + d->updatePosition(d->m_position); + emit activeAnimationGroupChanged(index); + } +} +void QAnimationController::setPosition(float position) +{ + Q_D(QAnimationController); + if (!qFuzzyCompare(d->m_position, position)) { + d->updatePosition(position); + emit positionChanged(position); + } +} + +void QAnimationController::setPositionScale(float scale) +{ + Q_D(QAnimationController); + if (!qFuzzyCompare(d->m_positionScale, scale)) { + d->m_positionScale = scale; + emit positionScaleChanged(scale); + } +} + +void QAnimationController::setPositionOffset(float offset) +{ + Q_D(QAnimationController); + if (!qFuzzyCompare(d->m_positionOffset, offset)) { + d->m_positionOffset = offset; + emit positionOffsetChanged(offset); + } +} + +void QAnimationController::setEntity(Qt3DCore::QEntity *entity) +{ + Q_D(QAnimationController); + if (d->m_entity != entity) { + d->clearAnimations(); + d->m_entity = entity; + d->extractAnimations(); + d->updatePosition(d->m_position); + emit entityChanged(entity); + } +} + +void QAnimationController::setRecursive(bool recursive) +{ + Q_D(QAnimationController); + if (d->m_recursive != recursive) { + d->m_recursive = recursive; + emit recursiveChanged(recursive); + } +} + +int QAnimationController::getAnimationIndex(const QString &name) const +{ + Q_D(const QAnimationController); + for (int i = 0; i < d->m_animationGroups.size(); ++i) { + if (d->m_animationGroups[i]->name() == name) + return i; + } + return -1; +} + +QAnimationGroup *QAnimationController::getGroup(int index) const +{ + Q_D(const QAnimationController); + return d->m_animationGroups.at(index); +} + +} // Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/animations/qanimationcontroller.h b/src/extras/animations/qanimationcontroller.h new file mode 100644 index 000000000..4ee32dd8b --- /dev/null +++ b/src/extras/animations/qanimationcontroller.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QANIMATIONCONTROLLER_H +#define QT3DEXTRAS_QANIMATIONCONTROLLER_H + +#include <Qt3DExtras/qkeyframeanimation.h> +#include <Qt3DExtras/qanimationgroup.h> +#include <Qt3DCore/qentity.h> + +#include <Qt3DExtras/qt3dextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QAnimationControllerPrivate; + +class QT3DEXTRASSHARED_EXPORT QAnimationController : public QObject +{ + Q_OBJECT + Q_PROPERTY(int activeAnimationGroup READ activeAnimationGroup WRITE setActiveAnimationGroup NOTIFY activeAnimationGroupChanged) + Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(float positionScale READ positionScale WRITE setPositionScale NOTIFY positionScaleChanged) + Q_PROPERTY(float positionOffset READ positionOffset WRITE setPositionOffset NOTIFY positionOffsetChanged) + Q_PROPERTY(Qt3DCore::QEntity *entity READ entity WRITE setEntity NOTIFY entityChanged) + Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) + +public: + QAnimationController(QObject *parent = nullptr); + + QVector<Qt3DExtras::QAnimationGroup *> animationGroupList(); + + int activeAnimationGroup() const; + float position() const; + float positionScale() const; + float positionOffset() const; + Qt3DCore::QEntity *entity() const; + bool recursive() const; + + void setAnimationGroups(const QVector<Qt3DExtras::QAnimationGroup *> &animationGroups); + void addAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroups); + void removeAnimationGroup(Qt3DExtras::QAnimationGroup *animationGroups); + + Q_INVOKABLE int getAnimationIndex(const QString &name) const; + Q_INVOKABLE Qt3DExtras::QAnimationGroup *getGroup(int index) const; + +public Q_SLOTS: + void setActiveAnimationGroup(int index); + void setPosition(float position); + void setPositionScale(float scale); + void setPositionOffset(float offset); + void setEntity(Qt3DCore::QEntity *entity); + void setRecursive(bool recursive); + +Q_SIGNALS: + void activeAnimationGroupChanged(int index); + void positionChanged(float position); + void positionScaleChanged(float scale); + void positionOffsetChanged(float offset); + void entityChanged(Qt3DCore::QEntity *entity); + void recursiveChanged(bool recursive); + +private: + Q_DECLARE_PRIVATE(QAnimationController) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_H diff --git a/src/extras/animations/qanimationcontroller_p.h b/src/extras/animations/qanimationcontroller_p.h new file mode 100644 index 000000000..dd5079ef5 --- /dev/null +++ b/src/extras/animations/qanimationcontroller_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QANIMATIONCONTROLLER_P_H +#define QT3DEXTRAS_QANIMATIONCONTROLLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qobject_p.h> +#include <Qt3DExtras/QAnimationGroup> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QAnimationControllerPrivate : public QObjectPrivate +{ +public: + QAnimationControllerPrivate(); + + QString m_name; + int m_activeAnimationGroup; + QVector<QAnimationGroup *> m_animationGroups; + float m_position; + float m_positionScale; + float m_positionOffset; + Qt3DCore::QEntity *m_entity; + bool m_recursive; + + void updatePosition(float position); + void extractAnimations(); + void clearAnimations(); + QAnimationGroup *findGroup(const QString &name); + + Q_DECLARE_PUBLIC(QAnimationController) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QANIMATIONCONTROLLER_P_H diff --git a/src/extras/animations/qanimationgroup.cpp b/src/extras/animations/qanimationgroup.cpp new file mode 100644 index 000000000..e9febe811 --- /dev/null +++ b/src/extras/animations/qanimationgroup.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanimationgroup.h" +#include "Qt3DExtras/private/qanimationgroup_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QAnimationGroupPrivate::QAnimationGroupPrivate() + : QObjectPrivate() + , m_position(0.0f) + , m_duration(0.0f) +{ + +} + +void QAnimationGroupPrivate::updatePosition(float position) +{ + m_position = position; + for (QAbstractAnimation *aa : m_animations) + aa->setPosition(position); +} + +QAnimationGroup::QAnimationGroup(QObject *parent) + : QObject(*new QAnimationGroupPrivate, parent) +{ + +} + +QString QAnimationGroup::name() const +{ + Q_D(const QAnimationGroup); + return d->m_name; +} + +QVector<Qt3DExtras::QAbstractAnimation *> QAnimationGroup::animationList() +{ + Q_D(QAnimationGroup); + return d->m_animations; +} + +float QAnimationGroup::position() const +{ + Q_D(const QAnimationGroup); + return d->m_position; +} + +float QAnimationGroup::duration() const +{ + Q_D(const QAnimationGroup); + return d->m_duration; +} + +void QAnimationGroup::setName(const QString &name) +{ + Q_D(QAnimationGroup); + if (d->m_name != name) { + d->m_name = name; + emit nameChanged(name); + } +} + +void QAnimationGroup::setAnimations(const QVector<Qt3DExtras::QAbstractAnimation *> &animations) +{ + Q_D(QAnimationGroup); + d->m_animations = animations; + d->m_duration = 0.0f; + for (const Qt3DExtras::QAbstractAnimation *a : animations) + d->m_duration = qMax(d->m_duration, a->duration()); +} + +void QAnimationGroup::addAnimation(QAbstractAnimation *animation) +{ + Q_D(QAnimationGroup); + d->m_animations.push_back(animation); + d->m_duration = qMax(d->m_duration, animation->duration()); +} + +void QAnimationGroup::setPosition(float position) +{ + Q_D(QAnimationGroup); + if (!qFuzzyCompare(d->m_position, position)) { + d->updatePosition(position); + emit positionChanged(position); + } +} + +} // Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/animations/qanimationgroup.h b/src/extras/animations/qanimationgroup.h new file mode 100644 index 000000000..4595a2082 --- /dev/null +++ b/src/extras/animations/qanimationgroup.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QANIMATIONGROUP_H +#define QT3DEXTRAS_QANIMATIONGROUP_H + +#include <qobject.h> + +#include <Qt3DExtras/qabstractanimation.h> + +#include <Qt3DExtras/qt3dextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QAnimationGroupPrivate; + +class QT3DEXTRASSHARED_EXPORT QAnimationGroup : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(float position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(float duration READ duration NOTIFY durationChanged) + +public: + explicit QAnimationGroup(QObject *parent = nullptr); + + QString name() const; + QVector<Qt3DExtras::QAbstractAnimation *> animationList(); + float position() const; + float duration() const; + + void setAnimations(const QVector<Qt3DExtras::QAbstractAnimation *> &animations); + void addAnimation(Qt3DExtras::QAbstractAnimation *animation); + void removeAnimation(Qt3DExtras::QAbstractAnimation *animation); + +public Q_SLOTS: + void setName(const QString &name); + void setPosition(float position); + +Q_SIGNALS: + void nameChanged(const QString &name); + void positionChanged(float position); + void durationChanged(float duration); + +private: + + Q_DECLARE_PRIVATE(QAnimationGroup) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QANIMATIONGROUP_H diff --git a/src/extras/animations/qanimationgroup_p.h b/src/extras/animations/qanimationgroup_p.h new file mode 100644 index 000000000..cffe44636 --- /dev/null +++ b/src/extras/animations/qanimationgroup_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QANIMATIONGROUP_P_H +#define QT3DEXTRAS_QANIMATIONGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qobject_p.h> +#include <Qt3DExtras/QAnimationGroup> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QAnimationGroupPrivate : public QObjectPrivate +{ +public: + QAnimationGroupPrivate(); + + QString m_name; + QVector<Qt3DExtras::QAbstractAnimation *> m_animations; + float m_position; + float m_duration; + + void updatePosition(float position); + + Q_DECLARE_PUBLIC(QAnimationGroup) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QANIMATIONGROUP_P_H diff --git a/src/extras/animations/qkeyframeanimation.cpp b/src/extras/animations/qkeyframeanimation.cpp new file mode 100644 index 000000000..425cbe0df --- /dev/null +++ b/src/extras/animations/qkeyframeanimation.cpp @@ -0,0 +1,262 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qkeyframeanimation.h" +#include "Qt3DExtras/private/qkeyframeanimation_p.h" + +#include <cmath> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QKeyframeAnimationPrivate::QKeyframeAnimationPrivate() + : QAbstractAnimationPrivate(QAbstractAnimation::KeyframeAnimation) + , m_minposition(0.0f) + , m_maxposition(0.0f) + , m_prevPosition(-1.0f) + , m_target(nullptr) + , m_startMode(QKeyframeAnimation::Constant) + , m_endMode(QKeyframeAnimation::Constant) +{ + +} + +QKeyframeAnimation::QKeyframeAnimation(QObject *parent) + : QAbstractAnimation(*new QKeyframeAnimationPrivate(), parent) +{ + Q_D(QKeyframeAnimation); + d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged, + this, &QKeyframeAnimation::updateAnimation); +} + + +void QKeyframeAnimation::setFramePositions(const QVector<float> &positions) +{ + Q_D(QKeyframeAnimation); + d->m_framePositions = positions; + d->m_prevPosition = -1.0f; + if (d->m_framePositions.size() == 0) { + d->m_minposition = d->m_maxposition = 0.0f; + return; + } + d->m_minposition = d->m_framePositions.first(); + d->m_maxposition = d->m_framePositions.last(); + float lastPos = d->m_minposition; + for (float p : d->m_framePositions) { + if (p < lastPos || p > d->m_maxposition) + qWarning() << "positions not ordered correctly"; + lastPos = p; + } + setDuration(d->m_maxposition); +} + +void QKeyframeAnimation::setKeyframes(const QVector<Qt3DCore::QTransform *> &keyframes) +{ + Q_D(QKeyframeAnimation); + d->m_keyframes = keyframes; +} + +// slerp which allows long path +QQuaternion lslerp(QQuaternion q1, QQuaternion q2, float t) +{ + QQuaternion ret; + // Handle the easy cases first. + if (t <= 0.0f) + return q1; + else if (t >= 1.0f) + return q2; + + float cos = qBound(-1.0f, QQuaternion::dotProduct(q1, q2), 1.0f); + float angle = std::acos(cos); + float sin = std::sin(angle); + if (!qFuzzyIsNull(sin)) { + float a = std::sin((1.0 - t) * angle) / sin; + float b = std::sin(t * angle) / sin; + ret = (q1 * a + q2 * b).normalized(); + } else { + ret = q1 * (1.0f-t) + q2 * t; + } + return ret; +} + +void QKeyframeAnimationPrivate::calculateFrame(float position) +{ + if (m_target && m_framePositions.size() > 0 + && m_keyframes.size() == m_framePositions.size() + && m_prevPosition != m_position) { + if (m_position >= m_minposition && m_position < m_maxposition) { + for (int i = 0; i < m_framePositions.size() - 1; i++) { + if (position >= m_framePositions.at(i) + && position < m_framePositions.at(i+1)) { + float ip = (position - m_framePositions.at(i)) + / (m_framePositions.at(i+1) - m_framePositions.at(i)); + float eIp = m_easing.valueForProgress(ip); + float eIip = 1.0f - eIp; + + Qt3DCore::QTransform *a = m_keyframes.at(i); + Qt3DCore::QTransform *b = m_keyframes.at(i+1); + + QVector3D s = a->scale3D() * eIip + b->scale3D() * eIp; + QVector3D t = a->translation() * eIip + b->translation() * eIp; + QQuaternion r = QQuaternion::slerp(a->rotation(), b->rotation(), eIp); + + m_target->setRotation(r); + m_target->setScale3D(s); + m_target->setTranslation(t); + return; + } + } + } else if (position < m_minposition) { + m_target->setRotation(m_keyframes.first()->rotation()); + m_target->setScale3D(m_keyframes.first()->scale3D()); + m_target->setTranslation(m_keyframes.first()->translation()); + } else { + m_target->setRotation(m_keyframes.last()->rotation()); + m_target->setScale3D(m_keyframes.last()->scale3D()); + m_target->setTranslation(m_keyframes.last()->translation()); + } + m_prevPosition = m_position; + } +} + +void QKeyframeAnimation::updateAnimation(float position) +{ + Q_D(QKeyframeAnimation); + d->calculateFrame(position); +} + +QVector<float> QKeyframeAnimation::framePositions() const +{ + Q_D(const QKeyframeAnimation); + return d->m_framePositions; +} + +QVector<Qt3DCore::QTransform *> QKeyframeAnimation::keyframeList() const +{ + Q_D(const QKeyframeAnimation); + return d->m_keyframes; +} + +void QKeyframeAnimation::setTarget(Qt3DCore::QTransform *target) +{ + Q_D(QKeyframeAnimation); + if (d->m_target != target) { + d->m_target = target; + emit targetChanged(d->m_target); + d->m_prevPosition = -1.0f; + + if (target) { + d->m_baseScale = target->scale3D(); + d->m_baseTranslation = target->translation(); + d->m_baseRotation = target->rotation(); + } + } +} + +QKeyframeAnimation::RepeatMode QKeyframeAnimation::startMode() const +{ + Q_D(const QKeyframeAnimation); + return d->m_startMode; +} + +QKeyframeAnimation::RepeatMode QKeyframeAnimation::endMode() const +{ + Q_D(const QKeyframeAnimation); + return d->m_endMode; +} + +void QKeyframeAnimation::setEasing(QEasingCurve::Type easing) +{ + Q_D(QKeyframeAnimation); + if (d->m_easing.type() != easing) { + d->m_easing.setType(easing); + emit easingChanged(easing); + } +} + +void QKeyframeAnimation::setTargetName(const QString &name) +{ + Q_D(QKeyframeAnimation); + d->m_targetName = name; + emit targetNameChanged(name); +} + +void QKeyframeAnimation::setStartMode(QKeyframeAnimation::RepeatMode mode) +{ + Q_D(QKeyframeAnimation); + if (d->m_startMode != mode) { + d->m_startMode = mode; + emit startModeChanged(mode); + } +} + +void QKeyframeAnimation::setEndMode(QKeyframeAnimation::RepeatMode mode) +{ + Q_D(QKeyframeAnimation); + if (mode != d->m_endMode) { + d->m_endMode = mode; + emit endModeChanged(mode); + } +} + +void QKeyframeAnimation::addKeyframe(Qt3DCore::QTransform *keyframe) +{ + Q_D(QKeyframeAnimation); + d->m_keyframes.push_back(keyframe); +} + +QString QKeyframeAnimation::targetName() const +{ + Q_D(const QKeyframeAnimation); + return d->m_targetName; +} + +QEasingCurve::Type QKeyframeAnimation::easing() const +{ + Q_D(const QKeyframeAnimation); + return d->m_easing.type(); +} + +Qt3DCore::QTransform *QKeyframeAnimation::target() const +{ + Q_D(const QKeyframeAnimation); + return d->m_target; +} + +} // Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/animations/qkeyframeanimation.h b/src/extras/animations/qkeyframeanimation.h new file mode 100644 index 000000000..178c9dbf1 --- /dev/null +++ b/src/extras/animations/qkeyframeanimation.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QKEYFRAMEANIMATION_H +#define QT3DEXTRAS_QKEYFRAMEANIMATION_H + +#include <Qt3DCore/qtransform.h> + +#include <Qt3DExtras/qabstractanimation.h> +#include <Qt3DExtras/qt3dextras_global.h> + +#include <QtCore/qeasingcurve.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QKeyframeAnimationPrivate; + +class QT3DEXTRASSHARED_EXPORT QKeyframeAnimation : public QAbstractAnimation +{ + Q_OBJECT + Q_PROPERTY(QVector<float> framePositions READ framePositions WRITE setFramePositions NOTIFY framePositionsChanged) + Q_PROPERTY(Qt3DCore::QTransform *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QEasingCurve::Type easing READ easing WRITE setEasing NOTIFY easingChanged) + Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged) + Q_PROPERTY(QKeyframeAnimation::RepeatMode startMode READ startMode WRITE setStartMode NOTIFY startModeChanged) + Q_PROPERTY(QKeyframeAnimation::RepeatMode endMode READ endMode WRITE setEndMode NOTIFY endModeChanged) + +public: + explicit QKeyframeAnimation(QObject *parent = nullptr); + + enum RepeatMode + { + None, + Constant, + Repeat, + }; + Q_ENUM(RepeatMode) + + QVector<float> framePositions() const; + QVector<Qt3DCore::QTransform *> keyframeList() const; + Qt3DCore::QTransform *target() const; + QEasingCurve::Type easing() const; + QString targetName() const; + RepeatMode startMode() const; + RepeatMode endMode() const; + + void setKeyframes(const QVector<Qt3DCore::QTransform *> &keyframes); + void addKeyframe(Qt3DCore::QTransform *keyframe); + void removeKeyframe(Qt3DCore::QTransform *keyframe); + +public Q_SLOTS: + void setFramePositions(const QVector<float> &positions); + void setTarget(Qt3DCore::QTransform *target); + void setEasing(QEasingCurve::Type easing); + void setTargetName(const QString &name); + void setStartMode(RepeatMode mode); + void setEndMode(RepeatMode mode); + +Q_SIGNALS: + void framePositionsChanged(const QVector<float> &positions); + void targetChanged(Qt3DCore::QTransform *target); + void easingChanged(QEasingCurve::Type easing); + void targetNameChanged(const QString &name); + void startModeChanged(RepeatMode startMode); + void endModeChanged(RepeatMode endMode); + +private: + void updateAnimation(float position); + + Q_DECLARE_PRIVATE(QKeyframeAnimation) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QKEYFRAMEANIMATION_H diff --git a/src/extras/animations/qkeyframeanimation_p.h b/src/extras/animations/qkeyframeanimation_p.h new file mode 100644 index 000000000..0095b9432 --- /dev/null +++ b/src/extras/animations/qkeyframeanimation_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QKEYFRAMEANIMATION_P_H +#define QT3DEXTRAS_QKEYFRAMEANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qobject_p.h> +#include <Qt3DExtras/qkeyframeanimation.h> +#include <private/qabstractanimation_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QKeyframeAnimationPrivate : public QAbstractAnimationPrivate +{ +public: + QKeyframeAnimationPrivate(); + + void calculateFrame(float position); + + float m_prevPosition; + QVector<float> m_framePositions; + QVector<Qt3DCore::QTransform *> m_keyframes; + Qt3DCore::QTransform *m_target; + QEasingCurve m_easing; + QString m_animationName; + QString m_targetName; + float m_minposition; + float m_maxposition; + QKeyframeAnimation::RepeatMode m_startMode; + QKeyframeAnimation::RepeatMode m_endMode; + QVector3D m_baseScale; + QVector3D m_baseTranslation; + QQuaternion m_baseRotation; + QMetaObject::Connection m_positionConnection; + + Q_DECLARE_PUBLIC(QKeyframeAnimation) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QKEYFRAMEANIMATION_P_H diff --git a/src/extras/animations/qmorphinganimation.cpp b/src/extras/animations/qmorphinganimation.cpp new file mode 100644 index 000000000..e7fe05147 --- /dev/null +++ b/src/extras/animations/qmorphinganimation.cpp @@ -0,0 +1,280 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmorphinganimation.h" +#include <private/qmorphinganimation_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QMorphingAnimationPrivate::QMorphingAnimationPrivate() + : QAbstractAnimationPrivate(QAbstractAnimation::MorphingAnimation) + , m_flattened(nullptr) + , m_method(QMorphingAnimation::Relative) + , m_interpolator(0.0f) + , m_target(nullptr) + , m_currentTarget(nullptr) +{ + m_easing.setType(QEasingCurve::InOutCubic); +} + +QMorphingAnimationPrivate::~QMorphingAnimationPrivate() +{ + for (QVector<float> *weights : m_weights) + delete weights; +} + +void QMorphingAnimationPrivate::updateAnimation(float position) +{ + Q_Q(QMorphingAnimation); + if (!m_target || !m_target->geometry()) + return; + + m_morphKey.resize(m_morphTargets.size()); + + for (int i = 0; i < m_targetPositions.size() - 1; ++i) { + if (position > m_targetPositions.at(i) && position <= m_targetPositions.at(i + 1)) { + float interpolator = (position - m_targetPositions.at(i)) + / (m_targetPositions.at(i + 1) - m_targetPositions.at(i)); + interpolator = m_easing.valueForProgress(interpolator); + float iip = 1.0f - interpolator; + float sum = 0.0f; + QVector<int> relevantValues; + for (int j = 0; j < m_morphTargets.size(); ++j) { + m_morphKey[j] = interpolator * m_weights.at(i + 1)->at(j) + + iip * m_weights.at(i)->at(j); + sum += m_morphKey[j]; + if (!qFuzzyIsNull(m_morphKey[j])) + relevantValues.push_back(j); + } + + if (relevantValues.size() == 0 || qFuzzyIsNull(sum)) { + // only base is used + interpolator = 0.0f; + } else if (relevantValues.size() == 1) { + // one morph target has non-zero weight + setTargetInterpolated(relevantValues[0]); + interpolator = sum; + } else { + // more than one morph target has non-zero weight + // flatten morph targets to one + qWarning() << Q_FUNC_INFO << "Flattening required"; + } + if (!qFuzzyCompare(interpolator, m_interpolator)) { + if (m_method == QMorphingAnimation::Normalized) + m_interpolator = interpolator; + else + m_interpolator = -interpolator; + emit q->interpolatorChanged(m_interpolator); + } + return; + } + } +} + +void QMorphingAnimationPrivate::setTargetInterpolated(int morphTarget) +{ + QMorphTarget *target = m_morphTargets[morphTarget]; + Qt3DRender::QGeometry *geometry = m_target->geometry(); + + // remove attributes from previous frame + if (m_currentTarget && (target != m_currentTarget)) { + const QVector<Qt3DRender::QAttribute *> targetAttributes = m_currentTarget->attributeList(); + for (int i = 0; i < targetAttributes.size(); ++i) + geometry->removeAttribute(targetAttributes.at(i)); + } + + const QVector<Qt3DRender::QAttribute *> targetAttributes = target->attributeList(); + + // add attributes from current frame to the geometry + if (target != m_currentTarget) { + for (int i = 0; i < m_attributeNames.size(); ++i) { + QString targetName = m_attributeNames.at(i); + targetName.append("Target"); + targetAttributes[i]->setName(targetName); + geometry->addAttribute(targetAttributes.at(i)); + } + } + m_currentTarget = target; +} + +QMorphingAnimation::QMorphingAnimation(QObject *parent) + : QAbstractAnimation(*new QMorphingAnimationPrivate, parent) +{ + Q_D(QMorphingAnimation); + d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged, + this, &QMorphingAnimation::updateAnimation); +} + +QVector<float> QMorphingAnimation::targetPositions() const +{ + Q_D(const QMorphingAnimation); + return d->m_targetPositions; +} + +float QMorphingAnimation::interpolator() const +{ + Q_D(const QMorphingAnimation); + return d->m_interpolator; +} + +Qt3DRender::QGeometryRenderer *QMorphingAnimation::target() const +{ + Q_D(const QMorphingAnimation); + return d->m_target; +} + +QString QMorphingAnimation::targetName() const +{ + Q_D(const QMorphingAnimation); + return d->m_targetName; +} + +QMorphingAnimation::Method QMorphingAnimation::method() const +{ + Q_D(const QMorphingAnimation); + return d->m_method; +} + +QEasingCurve::Type QMorphingAnimation::easing() const +{ + Q_D(const QMorphingAnimation); + return d->m_easing.type(); +} + +void QMorphingAnimation::setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets) +{ + Q_D(QMorphingAnimation); + d->m_morphTargets = targets; + d->m_attributeNames = targets[0]->attributeNames(); +} + +void QMorphingAnimation::addMorphTarget(Qt3DExtras::QMorphTarget *target) +{ + Q_D(QMorphingAnimation); + if (!d->m_morphTargets.contains(target)) + d->m_morphTargets.push_back(target); +} + +void QMorphingAnimation::removeMorphTarget(Qt3DExtras::QMorphTarget *target) +{ + Q_D(QMorphingAnimation); + d->m_morphTargets.removeAll(target); +} + +void QMorphingAnimation::setTargetPositions(const QVector<float> &targetPositions) +{ + Q_D(QMorphingAnimation); + d->m_targetPositions = targetPositions; + emit targetPositionsChanged(targetPositions); + setDuration(d->m_targetPositions.last()); + if (d->m_weights.size() < targetPositions.size()) { + d->m_weights.resize(targetPositions.size()); + for (int i = 0; i < d->m_weights.size(); ++i) { + if (d->m_weights[i] == nullptr) + d->m_weights[i] = new QVector<float>(); + } + } +} + +void QMorphingAnimation::setTarget(Qt3DRender::QGeometryRenderer *target) +{ + Q_D(QMorphingAnimation); + if (d->m_target != target) { + d->m_target = target; + emit targetChanged(target); + } +} + +void QMorphingAnimation::setWeights(int positionIndex, const QVector<float> &weights) +{ + Q_D(QMorphingAnimation); + if (d->m_weights.size() < positionIndex) + d->m_weights.resize(positionIndex + 1); + if (d->m_weights[positionIndex] == nullptr) + d->m_weights[positionIndex] = new QVector<float>(); + *d->m_weights[positionIndex] = weights; +} + +QVector<float> QMorphingAnimation::getWeights(int positionIndex) +{ + Q_D(QMorphingAnimation); + return *d->m_weights[positionIndex]; +} + +QVector<Qt3DExtras::QMorphTarget *> QMorphingAnimation::morphTargetList() +{ + Q_D(QMorphingAnimation); + return d->m_morphTargets; +} + +void QMorphingAnimation::setTargetName(const QString name) +{ + Q_D(QMorphingAnimation); + if (d->m_targetName != name) { + d->m_targetName = name; + emit targetNameChanged(name); + } +} + +void QMorphingAnimation::setMethod(QMorphingAnimation::Method method) +{ + Q_D(QMorphingAnimation); + if (d->m_method != method) { + d->m_method = method; + emit methodChanged(method); + } +} + +void QMorphingAnimation::setEasing(QEasingCurve::Type easing) +{ + Q_D(QMorphingAnimation); + if (d->m_easing.type() != easing) { + d->m_easing.setType(easing); + emit easingChanged(easing); + } +} + +void QMorphingAnimation::updateAnimation(float position) +{ + Q_D(QMorphingAnimation); + d->updateAnimation(position); +} + +} // Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/animations/qmorphinganimation.h b/src/extras/animations/qmorphinganimation.h new file mode 100644 index 000000000..f8ca71ec9 --- /dev/null +++ b/src/extras/animations/qmorphinganimation.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QMORPHINGANIMATION_H +#define QT3DEXTRAS_QMORPHINGANIMATION_H + +#include <Qt3DRender/qgeometryrenderer.h> + +#include <Qt3DExtras/qabstractanimation.h> +#include <Qt3DExtras/qmorphtarget.h> +#include <Qt3DExtras/qt3dextras_global.h> + +#include <QtCore/qeasingcurve.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QMorphingAnimationPrivate; + +class QT3DEXTRASSHARED_EXPORT QMorphingAnimation : public QAbstractAnimation +{ + Q_OBJECT + Q_PROPERTY(QVector<float> targetPositions READ targetPositions WRITE setTargetPositions NOTIFY targetPositionsChanged) + Q_PROPERTY(float interpolator READ interpolator NOTIFY interpolatorChanged) + Q_PROPERTY(Qt3DRender::QGeometryRenderer *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged) + Q_PROPERTY(QMorphingAnimation::Method method READ method WRITE setMethod NOTIFY methodChanged) + Q_PROPERTY(QEasingCurve::Type easing READ easing WRITE setEasing NOTIFY easingChanged) + +public: + enum Method + { + Normalized, + Relative + }; + Q_ENUM(Method) + + explicit QMorphingAnimation(QObject *parent = nullptr); + + QVector<float> targetPositions() const; + float interpolator() const; + Qt3DRender::QGeometryRenderer *target() const; + QString targetName() const; + QMorphingAnimation::Method method() const; + QEasingCurve::Type easing() const; + + void setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets); + void addMorphTarget(Qt3DExtras::QMorphTarget *target); + void removeMorphTarget(Qt3DExtras::QMorphTarget *target); + + void setWeights(int positionIndex, const QVector<float> &weights); + QVector<float> getWeights(int positionIndex); + + QVector<Qt3DExtras::QMorphTarget *> morphTargetList(); + +public Q_SLOTS: + void setTargetPositions(const QVector<float> &targetPositions); + void setTarget(Qt3DRender::QGeometryRenderer *target); + void setTargetName(const QString name); + void setMethod(QMorphingAnimation::Method method); + void setEasing(QEasingCurve::Type easing); + +Q_SIGNALS: + void targetPositionsChanged(const QVector<float> &targetPositions); + void interpolatorChanged(float interpolator); + void targetChanged(Qt3DRender::QGeometryRenderer *target); + void targetNameChanged(const QString &name); + void methodChanged(QMorphingAnimation::Method method); + void easingChanged(QEasingCurve::Type easing); + +private: + + void updateAnimation(float position); + + Q_DECLARE_PRIVATE(QMorphingAnimation) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QMORPHINGANIMATION_H diff --git a/src/extras/animations/qmorphinganimation_p.h b/src/extras/animations/qmorphinganimation_p.h new file mode 100644 index 000000000..e4a18f199 --- /dev/null +++ b/src/extras/animations/qmorphinganimation_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QMORPHINGANIMATION_P_H +#define QT3DEXTRAS_QMORPHINGANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qeasingcurve.h> +#include <Qt3DExtras/qmorphinganimation.h> + +#include <private/qobject_p.h> +#include <private/qabstractanimation_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QMorphingAnimationPrivate : public QAbstractAnimationPrivate +{ +public: + QMorphingAnimationPrivate(); + ~QMorphingAnimationPrivate(); + + void updateAnimation(float position); + void setTargetInterpolated(int morphTarget); + + QVector<float> m_targetPositions; + QVector<QVector<float>*> m_weights; + QVector<float> m_morphKey; + QStringList m_attributeNames; + QVector<Qt3DExtras::QMorphTarget *> m_morphTargets; + QMorphTarget *m_flattened; + QMorphingAnimation::Method m_method; + QEasingCurve m_easing; + float m_interpolator; + Qt3DRender::QGeometryRenderer *m_target; + QString m_targetName; + + QMorphTarget *m_currentTarget; + + QMetaObject::Connection m_positionConnection; + + Q_DECLARE_PUBLIC(QMorphingAnimation) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QMORPHINGANIMATION_P_H diff --git a/src/extras/animations/qmorphtarget.cpp b/src/extras/animations/qmorphtarget.cpp new file mode 100644 index 000000000..0c327a490 --- /dev/null +++ b/src/extras/animations/qmorphtarget.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmorphtarget.h" +#include "Qt3DExtras/private/qmorphtarget_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QMorphTargetPrivate::QMorphTargetPrivate() + : QObjectPrivate() +{ + +} + +void QMorphTargetPrivate::updateAttributeNames() +{ + m_attributeNames.clear(); + for (const Qt3DRender::QAttribute *attr : m_targetAttributes) + m_attributeNames.push_back(attr->name()); +} + +QMorphTarget::QMorphTarget(QObject *parent) + : QObject(*new QMorphTargetPrivate, parent) +{ + +} + +QVector<Qt3DRender::QAttribute *> QMorphTarget::attributeList() const +{ + Q_D(const QMorphTarget); + return d->m_targetAttributes; +} + +QStringList QMorphTarget::attributeNames() const +{ + Q_D(const QMorphTarget); + return d->m_attributeNames; +} + +void QMorphTarget::setAttributes(const QVector<Qt3DRender::QAttribute *> &attributes) +{ + Q_D(QMorphTarget); + d->m_targetAttributes = attributes; + d->m_attributeNames.clear(); + for (const Qt3DRender::QAttribute *attr : attributes) + d->m_attributeNames.push_back(attr->name()); + + emit attributeNamesChanged(d->m_attributeNames); +} + +void QMorphTarget::addAttribute(Qt3DRender::QAttribute *attribute) +{ + Q_D(QMorphTarget); + for (const Qt3DRender::QAttribute *attr : d->m_targetAttributes) { + if (attr->name() == attribute->name()) + return; + } + d->m_targetAttributes.push_back(attribute); + d->m_attributeNames.push_back(attribute->name()); + emit attributeNamesChanged(d->m_attributeNames); +} + +void QMorphTarget::removeAttribute(Qt3DRender::QAttribute *attribute) +{ + Q_D(QMorphTarget); + if (d->m_targetAttributes.contains(attribute)) { + d->m_targetAttributes.removeAll(attribute); + d->updateAttributeNames(); + emit attributeNamesChanged(d->m_attributeNames); + } +} + +QMorphTarget *QMorphTarget::fromGeometry(Qt3DRender::QGeometry *geometry, const QStringList &attributes) +{ + QMorphTarget *target = new QMorphTarget(); + for (Qt3DRender::QAttribute *attr : geometry->attributes()) { + if (attributes.contains(attr->name())) + target->addAttribute(attr); + } + return target; +} + +} // Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/animations/qmorphtarget.h b/src/extras/animations/qmorphtarget.h new file mode 100644 index 000000000..64c3037cb --- /dev/null +++ b/src/extras/animations/qmorphtarget.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QMORPHTARGET_H +#define QT3DEXTRAS_QMORPHTARGET_H + +#include <Qt3DRender/qattribute.h> +#include <Qt3DRender/qgeometry.h> + +#include <QtCore/qstringlist.h> + +#include <Qt3DExtras/qt3dextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QMorphTargetPrivate; + +class QT3DEXTRASSHARED_EXPORT QMorphTarget : public QObject +{ + Q_OBJECT + Q_PROPERTY(QStringList attributeNames READ attributeNames NOTIFY attributeNamesChanged) + +public: + explicit QMorphTarget(QObject *parent = nullptr); + + QVector<Qt3DRender::QAttribute *> attributeList() const; + QStringList attributeNames() const; + + void setAttributes(const QVector<Qt3DRender::QAttribute *> &attributes); + void addAttribute(Qt3DRender::QAttribute *attribute); + void removeAttribute(Qt3DRender::QAttribute *attribute); + + Q_INVOKABLE static QMorphTarget *fromGeometry(Qt3DRender::QGeometry *geometry, + const QStringList &attributes); + +Q_SIGNALS: + void attributeNamesChanged(const QStringList &attributeNames); + +private: + + Q_DECLARE_PRIVATE(QMorphTarget) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QMORPHTARGET_H diff --git a/src/extras/animations/qmorphtarget_p.h b/src/extras/animations/qmorphtarget_p.h new file mode 100644 index 000000000..7d42f8eb4 --- /dev/null +++ b/src/extras/animations/qmorphtarget_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QMORPHTARGET_P_H +#define QT3DEXTRAS_QMORPHTARGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DExtras/qmorphtarget.h> + +#include <private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QMorphTargetPrivate : public QObjectPrivate +{ +public: + QMorphTargetPrivate(); + + void updateAttributeNames(); + + QStringList m_attributeNames; + QVector<Qt3DRender::QAttribute *> m_targetAttributes; + + Q_DECLARE_PUBLIC(QMorphTarget) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QMORPHTARGET_P_H diff --git a/src/extras/animations/qvertexblendanimation.cpp b/src/extras/animations/qvertexblendanimation.cpp new file mode 100644 index 000000000..1b45992fe --- /dev/null +++ b/src/extras/animations/qvertexblendanimation.cpp @@ -0,0 +1,234 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qvertexblendanimation.h" + +#include <private/qvertexblendanimation_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +QVertexBlendAnimationPrivate::QVertexBlendAnimationPrivate() + : QAbstractAnimationPrivate(QAbstractAnimation::VertexBlendAnimation) + , m_currentBase(nullptr) + , m_currentTarget(nullptr) +{ + +} + +void QVertexBlendAnimationPrivate::getAttributesInPosition(float position, int *target0, + int *target1, float *interpolator) +{ + if (position < m_targetPositions.first()) { + *target0 = 0; + *target1 = qMin(1, m_targetPositions.size()); + *interpolator = 0.0f; + } else if (position > m_targetPositions.last()) { + *target0 = qMax(m_targetPositions.size() - 2, 0); + *target1 = qMax(m_targetPositions.size() - 1, 0); + *interpolator = 1.0f; + } else { + for (int i = 0; i < m_targetPositions.size() - 1; i++) { + if (position >= m_targetPositions[i] && position < m_targetPositions[i + 1]) { + *target0 = i; + *target1 = i + 1; + float a = (position - m_targetPositions[i]) + / (m_targetPositions[i + 1] - m_targetPositions[i]); + *interpolator = a; + } + } + } +} + +static Qt3DRender::QAttribute *findAttribute(QVector<Qt3DRender::QAttribute *> &attributes, + QString name) +{ + for (Qt3DRender::QAttribute *gattr : attributes) { + if (gattr->name() == name) + return gattr; + } + return nullptr; +} + +void QVertexBlendAnimationPrivate::updateAnimation(float position) +{ + Q_Q(QVertexBlendAnimation); + if (!m_target || !m_target->geometry()) + return; + + Qt3DExtras::QMorphTarget *base; + Qt3DExtras::QMorphTarget *target; + int target0, target1; + float interpolator; + getAttributesInPosition(position, &target0, &target1, &interpolator); + + base = m_morphTargets.at(target0); + target = m_morphTargets.at(target1); + + Qt3DRender::QGeometry *geometry = m_target->geometry(); + + // remove attributes from previous frame + if ((m_currentBase && (base != m_currentBase)) + || (m_currentTarget && (target != m_currentTarget))) { + const QVector<Qt3DRender::QAttribute *> baseAttributes = m_currentBase->attributeList(); + const QVector<Qt3DRender::QAttribute *> targetAttributes = m_currentTarget->attributeList(); + for (int i = 0; i < baseAttributes.size(); ++i) { + geometry->removeAttribute(baseAttributes.at(i)); + geometry->removeAttribute(targetAttributes.at(i)); + } + } + + const QVector<Qt3DRender::QAttribute *> baseAttributes = base->attributeList(); + const QVector<Qt3DRender::QAttribute *> targetAttributes = target->attributeList(); + const QStringList attributeNames = base->attributeNames(); + + // add attributes from current frame to the geometry + if (base != m_currentBase || target != m_currentTarget) { + for (int i = 0; i < baseAttributes.size(); ++i) { + const QString baseName = attributeNames.at(i); + QString targetName = baseName; + targetName.append("Target"); + + baseAttributes[i]->setName(baseName); + geometry->addAttribute(baseAttributes.at(i)); + targetAttributes[i]->setName(targetName); + geometry->addAttribute(targetAttributes.at(i)); + } + } + m_currentBase = base; + m_currentTarget = target; + + if (!qFuzzyCompare(interpolator, m_interpolator)) { + m_interpolator = interpolator; + emit q->interpolatorChanged(interpolator); + } +} + +QVertexBlendAnimation::QVertexBlendAnimation(QObject *parent) + : QAbstractAnimation(*new QVertexBlendAnimationPrivate, parent) +{ + Q_D(QVertexBlendAnimation); + d->m_positionConnection = QObject::connect(this, &QAbstractAnimation::positionChanged, + this, &QVertexBlendAnimation::updateAnimation); +} + +QVector<float> QVertexBlendAnimation::targetPositions() const +{ + Q_D(const QVertexBlendAnimation); + return d->m_targetPositions; +} + +float QVertexBlendAnimation::interpolator() const +{ + Q_D(const QVertexBlendAnimation); + return d->m_interpolator; +} + +Qt3DRender::QGeometryRenderer *QVertexBlendAnimation::target() const +{ + Q_D(const QVertexBlendAnimation); + return d->m_target; +} + +QString QVertexBlendAnimation::targetName() const +{ + Q_D(const QVertexBlendAnimation); + return d->m_targetName; +} + +void QVertexBlendAnimation::setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets) +{ + Q_D(QVertexBlendAnimation); + d->m_morphTargets = targets; +} + +void QVertexBlendAnimation::addMorphTarget(Qt3DExtras::QMorphTarget *target) +{ + Q_D(QVertexBlendAnimation); + if (!d->m_morphTargets.contains(target)) + d->m_morphTargets.push_back(target); +} + +void QVertexBlendAnimation::removeMorphTarget(Qt3DExtras::QMorphTarget *target) +{ + Q_D(QVertexBlendAnimation); + d->m_morphTargets.removeAll(target); +} + +void QVertexBlendAnimation::setTargetPositions(const QVector<float> &targetPositions) +{ + Q_D(QVertexBlendAnimation); + if (d->m_targetPositions == targetPositions) + return; + d->m_targetPositions = targetPositions; + emit targetPositionsChanged(targetPositions); + setDuration(d->m_targetPositions.last()); +} + +void QVertexBlendAnimation::setTarget(Qt3DRender::QGeometryRenderer *target) +{ + Q_D(QVertexBlendAnimation); + if (d->m_target != target) { + d->m_target = target; + emit targetChanged(target); + } +} + +QVector<Qt3DExtras::QMorphTarget *> QVertexBlendAnimation::morphTargetList() +{ + Q_D(QVertexBlendAnimation); + return d->m_morphTargets; +} + +void QVertexBlendAnimation::setTargetName(const QString name) +{ + Q_D(QVertexBlendAnimation); + if (d->m_targetName != name) { + d->m_targetName = name; + emit targetNameChanged(name); + } +} + +void QVertexBlendAnimation::updateAnimation(float position) +{ + Q_D(QVertexBlendAnimation); + d->updateAnimation(position); +} + +} // Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/animations/qvertexblendanimation.h b/src/extras/animations/qvertexblendanimation.h new file mode 100644 index 000000000..ebd313e83 --- /dev/null +++ b/src/extras/animations/qvertexblendanimation.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QVERTEXBLENDANIMATION_H +#define QT3DEXTRAS_QVERTEXBLENDANIMATION_H + +#include <Qt3DRender/qgeometryrenderer.h> +#include <Qt3DExtras/qabstractanimation.h> +#include <Qt3DExtras/qmorphtarget.h> + +#include <Qt3DExtras/qt3dextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QVertexBlendAnimationPrivate; + +class QT3DEXTRASSHARED_EXPORT QVertexBlendAnimation : public QAbstractAnimation +{ + Q_OBJECT + Q_PROPERTY(QVector<float> targetPositions READ targetPositions WRITE setTargetPositions NOTIFY targetPositionsChanged) + Q_PROPERTY(float interpolator READ interpolator NOTIFY interpolatorChanged) + Q_PROPERTY(Qt3DRender::QGeometryRenderer *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged) + +public: + explicit QVertexBlendAnimation(QObject *parent = nullptr); + + QVector<float> targetPositions() const; + float interpolator() const; + Qt3DRender::QGeometryRenderer *target() const; + QString targetName() const; + + void setMorphTargets(const QVector<Qt3DExtras::QMorphTarget *> &targets); + void addMorphTarget(Qt3DExtras::QMorphTarget *target); + void removeMorphTarget(Qt3DExtras::QMorphTarget *target); + + QVector<Qt3DExtras::QMorphTarget *> morphTargetList(); + +public Q_SLOTS: + void setTargetPositions(const QVector<float> &targetPositions); + void setTarget(Qt3DRender::QGeometryRenderer *target); + void setTargetName(const QString name); + +Q_SIGNALS: + void targetPositionsChanged(const QVector<float> &targetPositions); + void interpolatorChanged(float interpolator); + void targetChanged(Qt3DRender::QGeometryRenderer *target); + void targetNameChanged(const QString &name); + +private: + + void updateAnimation(float position); + + Q_DECLARE_PRIVATE(QVertexBlendAnimation) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QVERTEXBLENDANIMATION_H diff --git a/src/extras/animations/qvertexblendanimation_p.h b/src/extras/animations/qvertexblendanimation_p.h new file mode 100644 index 000000000..812953e04 --- /dev/null +++ b/src/extras/animations/qvertexblendanimation_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QVERTEXBLENDANIMATION_P_H +#define QT3DEXTRAS_QVERTEXBLENDANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include <Qt3DExtras/qvertexblendanimation.h> + +#include <private/qobject_p.h> +#include <private/qabstractanimation_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QVertexBlendAnimationPrivate : public QAbstractAnimationPrivate +{ +public: + QVertexBlendAnimationPrivate(); + + void getAttributesInPosition(float position, int *target0, int *target1, float *interpolator); + void updateAnimation(float position); + + QVector<float> m_targetPositions; + QVector<Qt3DExtras::QMorphTarget *> m_morphTargets; + float m_interpolator; + Qt3DRender::QGeometryRenderer *m_target; + QString m_targetName; + QMorphTarget *m_currentBase; + QMorphTarget *m_currentTarget; + + QMetaObject::Connection m_positionConnection; + + Q_DECLARE_PUBLIC(QVertexBlendAnimation) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QVertexBlendANIMATION_P_H diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri index 04cd87246..21ef6fef6 100644 --- a/src/extras/defaults/defaults.pri +++ b/src/extras/defaults/defaults.pri @@ -4,7 +4,6 @@ HEADERS += \ $$PWD/qphongmaterial.h \ $$PWD/qphongmaterial_p.h \ $$PWD/qdiffusemapmaterial_p.h \ - $$PWD/qdiffusemapmaterial.h \ $$PWD/qnormaldiffusespecularmapmaterial.h \ $$PWD/qnormaldiffusespecularmapmaterial_p.h \ $$PWD/qnormaldiffusemapmaterial.h \ @@ -27,7 +26,10 @@ HEADERS += \ $$PWD/qfirstpersoncameracontroller.h \ $$PWD/qfirstpersoncameracontroller_p.h \ $$PWD/qorbitcameracontroller.h \ - $$PWD/qorbitcameracontroller_p.h + $$PWD/qorbitcameracontroller_p.h \ + $$PWD/qmorphphongmaterial.h \ + $$PWD/qmorphphongmaterial_p.h \ + $$PWD/qdiffusemapmaterial.h SOURCES += \ $$PWD/qphongmaterial.cpp \ @@ -43,5 +45,6 @@ SOURCES += \ $$PWD/qphongalphamaterial.cpp \ $$PWD/qt3dwindow.cpp \ $$PWD/qfirstpersoncameracontroller.cpp \ - $$PWD/qorbitcameracontroller.cpp + $$PWD/qorbitcameracontroller.cpp \ + $$PWD/qmorphphongmaterial.cpp diff --git a/src/extras/defaults/qmorphphongmaterial.cpp b/src/extras/defaults/qmorphphongmaterial.cpp new file mode 100644 index 000000000..22f520de5 --- /dev/null +++ b/src/extras/defaults/qmorphphongmaterial.cpp @@ -0,0 +1,291 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmorphphongmaterial.h" +#include "qmorphphongmaterial_p.h" +#include <Qt3DRender/qfilterkey.h> +#include <Qt3DRender/qmaterial.h> +#include <Qt3DRender/qeffect.h> +#include <Qt3DRender/qtechnique.h> +#include <Qt3DRender/qshaderprogram.h> +#include <Qt3DRender/qparameter.h> +#include <Qt3DRender/qrenderpass.h> +#include <Qt3DRender/qgraphicsapifilter.h> +#include <QUrl> +#include <QVector3D> +#include <QVector4D> + +QT_BEGIN_NAMESPACE + +using namespace Qt3DRender; + +namespace Qt3DExtras { + +QMorphPhongMaterialPrivate::QMorphPhongMaterialPrivate() + : QMaterialPrivate() + , m_phongEffect(new QEffect()) + , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f))) + , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 1.0f))) + , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f))) + , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f)) + , m_interpolatorParameter(new QParameter(QStringLiteral("interpolator"), 0.0f)) + , m_phongGL3Technique(new QTechnique()) + , m_phongGL2Technique(new QTechnique()) + , m_phongES2Technique(new QTechnique()) + , m_phongGL3RenderPass(new QRenderPass()) + , m_phongGL2RenderPass(new QRenderPass()) + , m_phongES2RenderPass(new QRenderPass()) + , m_phongGL3Shader(new QShaderProgram()) + , m_phongGL2ES2Shader(new QShaderProgram()) + , m_filterKey(new QFilterKey) +{ +} + +void QMorphPhongMaterialPrivate::init() +{ + connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMorphPhongMaterialPrivate::handleAmbientChanged); + connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMorphPhongMaterialPrivate::handleDiffuseChanged); + connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMorphPhongMaterialPrivate::handleSpecularChanged); + connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMorphPhongMaterialPrivate::handleShininessChanged); + connect(m_interpolatorParameter, &Qt3DRender::QParameter::valueChanged, + this, &QMorphPhongMaterialPrivate::handleInterpolatorChanged); + + m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/morphphong.vert")))); + m_phongGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.frag")))); + m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/morphphong.vert")))); + m_phongGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.frag")))); + + m_phongGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + m_phongGL3Technique->graphicsApiFilter()->setMajorVersion(3); + m_phongGL3Technique->graphicsApiFilter()->setMinorVersion(1); + m_phongGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile); + + m_phongGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL); + m_phongGL2Technique->graphicsApiFilter()->setMajorVersion(2); + m_phongGL2Technique->graphicsApiFilter()->setMinorVersion(0); + m_phongGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile); + + m_phongES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES); + m_phongES2Technique->graphicsApiFilter()->setMajorVersion(2); + m_phongES2Technique->graphicsApiFilter()->setMinorVersion(0); + m_phongES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile); + + m_phongGL3RenderPass->setShaderProgram(m_phongGL3Shader); + m_phongGL2RenderPass->setShaderProgram(m_phongGL2ES2Shader); + m_phongES2RenderPass->setShaderProgram(m_phongGL2ES2Shader); + + m_phongGL3Technique->addRenderPass(m_phongGL3RenderPass); + m_phongGL2Technique->addRenderPass(m_phongGL2RenderPass); + m_phongES2Technique->addRenderPass(m_phongES2RenderPass); + + Q_Q(QMorphPhongMaterial); + m_filterKey->setParent(q); + m_filterKey->setName(QStringLiteral("renderingStyle")); + m_filterKey->setValue(QStringLiteral("forward")); + + m_phongGL3Technique->addFilterKey(m_filterKey); + m_phongGL2Technique->addFilterKey(m_filterKey); + m_phongES2Technique->addFilterKey(m_filterKey); + + m_phongEffect->addTechnique(m_phongGL3Technique); + m_phongEffect->addTechnique(m_phongGL2Technique); + m_phongEffect->addTechnique(m_phongES2Technique); + + m_phongEffect->addParameter(m_ambientParameter); + m_phongEffect->addParameter(m_diffuseParameter); + m_phongEffect->addParameter(m_specularParameter); + m_phongEffect->addParameter(m_shininessParameter); + m_phongEffect->addParameter(m_interpolatorParameter); + + q->setEffect(m_phongEffect); +} + +void QMorphPhongMaterialPrivate::handleAmbientChanged(const QVariant &var) +{ + Q_Q(QMorphPhongMaterial); + emit q->ambientChanged(var.value<QColor>()); +} + +void QMorphPhongMaterialPrivate::handleDiffuseChanged(const QVariant &var) +{ + Q_Q(QMorphPhongMaterial); + emit q->diffuseChanged(var.value<QColor>()); +} + +void QMorphPhongMaterialPrivate::handleSpecularChanged(const QVariant &var) +{ + Q_Q(QMorphPhongMaterial); + emit q->specularChanged(var.value<QColor>()); +} + +void QMorphPhongMaterialPrivate::handleShininessChanged(const QVariant &var) +{ + Q_Q(QMorphPhongMaterial); + emit q->shininessChanged(var.toFloat()); +} + +void QMorphPhongMaterialPrivate::handleInterpolatorChanged(const QVariant &var) +{ + Q_Q(QMorphPhongMaterial); + emit q->interpolatorChanged(var.toFloat()); +} + +/*! + \class Qt3DExtras::QMorphPhongMaterial + \brief The QMorphPhongMaterial class provides a default implementation of the phong lighting effect. + \inmodule Qt3DExtras + \since 5.7 + \inherits Qt3DRender::QMaterial + + The phong lighting effect is based on the combination of 3 lighting components ambient, diffuse + and specular. The relative strengths of these components are controlled by means of their + reflectivity coefficients which are modelled as RGB triplets: + + \list + \li Ambient is the color that is emitted by an object without any other light source. + \li Diffuse is the color that is emitted for rought surface reflections with the lights. + \li Specular is the color emitted for shiny surface reflections with the lights. + \li The shininess of a surface is controlled by a float property. + \endlist + + This material uses an effect with a single render pass approach and performs per fragment + lighting. Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2. +*/ + +/*! + Constructs a new QMorphPhongMaterial instance with parent object \a parent. +*/ +QMorphPhongMaterial::QMorphPhongMaterial(QNode *parent) + : QMaterial(*new QMorphPhongMaterialPrivate, parent) +{ + Q_D(QMorphPhongMaterial); + d->init(); +} + +/*! + Destroys the QMorphPhongMaterial. +*/ +QMorphPhongMaterial::~QMorphPhongMaterial() +{ +} + +/*! + \property QMorphPhongMaterial::ambient + + Holds the ambient color. +*/ +QColor QMorphPhongMaterial::ambient() const +{ + Q_D(const QMorphPhongMaterial); + return d->m_ambientParameter->value().value<QColor>(); +} + +/*! + \property QMorphPhongMaterial::diffuse + + Holds the diffuse color. +*/ +QColor QMorphPhongMaterial::diffuse() const +{ + Q_D(const QMorphPhongMaterial); + return d->m_diffuseParameter->value().value<QColor>(); +} + +/*! + \property QMorphPhongMaterial::specular + + Holds the specular color. +*/ +QColor QMorphPhongMaterial::specular() const +{ + Q_D(const QMorphPhongMaterial); + return d->m_specularParameter->value().value<QColor>(); +} + +/*! + \property QMorphPhongMaterial::shininess + + Holds the shininess exponent. +*/ +float QMorphPhongMaterial::shininess() const +{ + Q_D(const QMorphPhongMaterial); + return d->m_shininessParameter->value().toFloat(); +} + +float QMorphPhongMaterial::interpolator() const +{ + Q_D(const QMorphPhongMaterial); + return d->m_interpolatorParameter->value().toFloat(); +} + +void QMorphPhongMaterial::setAmbient(const QColor &ambient) +{ + Q_D(QMorphPhongMaterial); + d->m_ambientParameter->setValue(ambient); +} + +void QMorphPhongMaterial::setDiffuse(const QColor &diffuse) +{ + Q_D(QMorphPhongMaterial); + d->m_diffuseParameter->setValue(diffuse); +} + +void QMorphPhongMaterial::setSpecular(const QColor &specular) +{ + Q_D(QMorphPhongMaterial); + d->m_specularParameter->setValue(specular); +} + +void QMorphPhongMaterial::setShininess(float shininess) +{ + Q_D(QMorphPhongMaterial); + d->m_shininessParameter->setValue(shininess); +} + +void QMorphPhongMaterial::setInterpolator(float interpolator) +{ + Q_D(QMorphPhongMaterial); + d->m_interpolatorParameter->setValue(interpolator); +} + +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/extras/defaults/qmorphphongmaterial.h b/src/extras/defaults/qmorphphongmaterial.h new file mode 100644 index 000000000..3b65088b1 --- /dev/null +++ b/src/extras/defaults/qmorphphongmaterial.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QMORPHPHONGMATERIAL_H +#define QT3DEXTRAS_QMORPHPHONGMATERIAL_H + +#include <Qt3DExtras/qt3dextras_global.h> +#include <Qt3DRender/qmaterial.h> +#include <QColor> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { + +class QMorphPhongMaterialPrivate; + +class QT3DEXTRASSHARED_EXPORT QMorphPhongMaterial : public Qt3DRender::QMaterial +{ + Q_OBJECT + Q_PROPERTY(QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged) + Q_PROPERTY(QColor diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged) + Q_PROPERTY(QColor specular READ specular WRITE setSpecular NOTIFY specularChanged) + Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged) + Q_PROPERTY(float interpolator READ interpolator WRITE setInterpolator NOTIFY interpolatorChanged) + +public: + explicit QMorphPhongMaterial(Qt3DCore::QNode *parent = nullptr); + ~QMorphPhongMaterial(); + + QColor ambient() const; + QColor diffuse() const; + QColor specular() const; + float shininess() const; + float interpolator() const; + +public Q_SLOTS: + void setAmbient(const QColor &ambient); + void setDiffuse(const QColor &diffuse); + void setSpecular(const QColor &specular); + void setShininess(float shininess); + void setInterpolator(float interpolator); + +Q_SIGNALS: + void ambientChanged(const QColor &ambient); + void diffuseChanged(const QColor &diffuse); + void specularChanged(const QColor &specular); + void shininessChanged(float shininess); + void interpolatorChanged(float interpolator); + +private: + Q_DECLARE_PRIVATE(QMorphPhongMaterial) +}; + +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QMORPHPHONGMATERIAL_H + diff --git a/src/extras/defaults/qmorphphongmaterial_p.h b/src/extras/defaults/qmorphphongmaterial_p.h new file mode 100644 index 000000000..25bff9042 --- /dev/null +++ b/src/extras/defaults/qmorphphongmaterial_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QMORPHPHONGMATERIAL_P_H +#define QT3DEXTRAS_QMORPHPHONGMATERIAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DRender/private/qmaterial_p.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DRender { + +class QFilterKey; +class QEffect; +class QTechnique; +class QParameter; +class QShaderProgram; +class QRenderPass; + +} // namespace Qt3DRender + +namespace Qt3DExtras { + +class QMorphPhongMaterial; + +class QMorphPhongMaterialPrivate : public Qt3DRender::QMaterialPrivate +{ +public: + QMorphPhongMaterialPrivate(); + + void init(); + + void handleAmbientChanged(const QVariant &var); + void handleDiffuseChanged(const QVariant &var); + void handleSpecularChanged(const QVariant &var); + void handleShininessChanged(const QVariant &var); + void handleInterpolatorChanged(const QVariant &var); + + Qt3DRender::QEffect *m_phongEffect; + Qt3DRender::QParameter *m_ambientParameter; + Qt3DRender::QParameter *m_diffuseParameter; + Qt3DRender::QParameter *m_specularParameter; + Qt3DRender::QParameter *m_shininessParameter; + Qt3DRender::QParameter *m_interpolatorParameter; + Qt3DRender::QTechnique *m_phongGL3Technique; + Qt3DRender::QTechnique *m_phongGL2Technique; + Qt3DRender::QTechnique *m_phongES2Technique; + Qt3DRender::QRenderPass *m_phongGL3RenderPass; + Qt3DRender::QRenderPass *m_phongGL2RenderPass; + Qt3DRender::QRenderPass *m_phongES2RenderPass; + Qt3DRender::QShaderProgram *m_phongGL3Shader; + Qt3DRender::QShaderProgram *m_phongGL2ES2Shader; + Qt3DRender::QFilterKey *m_filterKey; + + Q_DECLARE_PUBLIC(QMorphPhongMaterial) +}; + +} // Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QPHONGMATERIAL_P_H + + diff --git a/src/extras/extras.pro b/src/extras/extras.pro index d723554ca..d11172005 100644 --- a/src/extras/extras.pro +++ b/src/extras/extras.pro @@ -9,6 +9,7 @@ DEFINES += QT_NO_FOREACH load(qt_module) +include (animations/animations.pri) include (geometries/geometries.pri) include (3dtext/3dtext.pri) include (defaults/defaults.pri) diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc index e7b1c1d9a..121bfd029 100644 --- a/src/extras/extras.qrc +++ b/src/extras/extras.qrc @@ -39,5 +39,7 @@ <file>shaders/gl3/unlittexture.frag</file> <file>shaders/es2/unlittexture.frag</file> <file>shaders/es2/unlittexture.vert</file> + <file>shaders/gl3/morphphong.vert</file> + <file>shaders/es2/morphphong.vert</file> </qresource> </RCC> diff --git a/src/extras/shaders/es2/morphphong.vert b/src/extras/shaders/es2/morphphong.vert new file mode 100644 index 000000000..d091e87c0 --- /dev/null +++ b/src/extras/shaders/es2/morphphong.vert @@ -0,0 +1,32 @@ +attribute vec3 vertexPosition; +attribute vec3 vertexNormal; +attribute vec3 vertexPositionTarget; +attribute vec3 vertexNormalTarget; + +varying vec3 worldPosition; +varying vec3 worldNormal; + +uniform mat4 modelMatrix; +uniform mat3 modelNormalMatrix; +uniform mat4 modelViewProjection; +uniform float interpolator; + +void main() +{ + vec3 morphPos; + vec3 morphNormal; + if (interpolator > 0.0) { + // normalized + morphPos = mix(vertexPosition, vertexPositionTarget, interpolator); + morphNormal = normalize(mix(vertexNormal, vertexNormalTarget, interpolator)); + } else { + // relative + morphPos = vertexPosition + vertexPositionTarget * abs(interpolator); + morphNormal = normalize(vertexNormal + vertexNormalTarget * abs(interpolator)); + } + + worldNormal = normalize( modelNormalMatrix * morphPos ); + worldPosition = vec3( modelMatrix * vec4( morphPos, 1.0 ) ); + + gl_Position = modelViewProjection * vec4( morphPos, 1.0 ); +} diff --git a/src/extras/shaders/gl3/morphphong.vert b/src/extras/shaders/gl3/morphphong.vert new file mode 100644 index 000000000..c74fbdcff --- /dev/null +++ b/src/extras/shaders/gl3/morphphong.vert @@ -0,0 +1,34 @@ +#version 150 core + +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec3 vertexPositionTarget; +in vec3 vertexNormalTarget; + +out vec3 worldPosition; +out vec3 worldNormal; + +uniform mat4 modelMatrix; +uniform mat3 modelNormalMatrix; +uniform mat4 modelViewProjection; +uniform float interpolator; + +void main() +{ + vec3 morphPos; + vec3 morphNormal; + if (interpolator > 0.0) { + // normalized + morphPos = mix(vertexPosition, vertexPositionTarget, interpolator); + morphNormal = normalize(mix(vertexNormal, vertexNormalTarget, interpolator)); + } else { + // relative + morphPos = vertexPosition + vertexPositionTarget * abs(interpolator); + morphNormal = normalize(vertexNormal + vertexNormalTarget * abs(interpolator)); + } + + worldNormal = normalize( modelNormalMatrix * morphPos ); + worldPosition = vec3( modelMatrix * vec4( morphPos, 1.0 ) ); + + gl_Position = modelViewProjection * vec4( morphPos, 1.0 ); +} diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.cpp b/src/plugins/sceneparsers/assimp/assimpimporter.cpp index dba13a291..66c219fe9 100644 --- a/src/plugins/sceneparsers/assimp/assimpimporter.cpp +++ b/src/plugins/sceneparsers/assimp/assimpimporter.cpp @@ -51,9 +51,12 @@ #include <Qt3DRender/qattribute.h> #include <Qt3DRender/qtexture.h> #include <Qt3DRender/qtextureimagedatagenerator.h> +#include <Qt3DExtras/qmorphphongmaterial.h> #include <Qt3DExtras/qdiffusemapmaterial.h> #include <Qt3DExtras/qdiffusespecularmapmaterial.h> #include <Qt3DExtras/qphongmaterial.h> +#include <Qt3DExtras/qkeyframeanimation.h> +#include <Qt3DExtras/qmorphinganimation.h> #include <QFileInfo> #include <QColor> #include <qmath.h> @@ -413,7 +416,15 @@ Qt3DCore::QEntity *AssimpImporter::scene(const QString &id) // Builds the Qt3D scene using the Assimp aiScene // and the various dicts filled previously by parse - return node(rootNode); + Qt3DCore::QEntity *n = node(rootNode); + if (m_scene->m_animations.size() > 0) { + qWarning() << "No target found for " << m_scene->m_animations.size() << " animations!"; + + for (Qt3DExtras::QKeyframeAnimation *anim : m_scene->m_animations) + delete anim; + m_scene->m_animations.clear(); + } + return n; } /*! @@ -429,6 +440,17 @@ Qt3DCore::QEntity *AssimpImporter::node(const QString &id) return node(n); } +template <typename T> +void findAnimationsForNode(QVector<T *> &animations, QVector<T *> &result, const QString &name) +{ + for (T *anim : animations) { + if (anim->targetName() == name) { + result.push_back(anim); + animations.removeAll(anim); + } + } +} + /*! * Returns a Node from an Assimp aiNode \a node. */ @@ -442,13 +464,54 @@ Qt3DCore::QEntity *AssimpImporter::node(aiNode *node) // Add Meshes to the node for (uint i = 0; i < node->mNumMeshes; i++) { uint meshIdx = node->mMeshes[i]; + QMaterial *material = nullptr; QGeometryRenderer *mesh = m_scene->m_meshes[meshIdx]; // mesh material uint materialIndex = m_scene->m_aiScene->mMeshes[meshIdx]->mMaterialIndex; + if (m_scene->m_materials.contains(materialIndex)) - entityNode->addComponent(m_scene->m_materials[materialIndex]); - // mesh - entityNode->addComponent(mesh); + material = m_scene->m_materials[materialIndex]; + + QList<Qt3DExtras::QMorphingAnimation *> morphingAnimations + = mesh->findChildren<Qt3DExtras::QMorphingAnimation *>(); + if (morphingAnimations.size() > 0) { + material = new Qt3DExtras::QMorphPhongMaterial(entityNode); + + QVector<Qt3DExtras::QMorphingAnimation *> animations; + findAnimationsForNode<Qt3DExtras::QMorphingAnimation>(m_scene->m_morphAnimations, + animations, + aiStringToQString(node->mName)); + const auto morphTargetList = morphingAnimations.at(0)->morphTargetList(); + for (Qt3DExtras::QMorphingAnimation *anim : animations) { + anim->setParent(entityNode); + anim->setTarget(mesh); + anim->setMorphTargets(morphTargetList); + } + + for (int j = 0; j < animations.size(); ++j) { + QObject::connect(animations[j], &Qt3DExtras::QMorphingAnimation::interpolatorChanged, + (Qt3DExtras::QMorphPhongMaterial *)material, + &Qt3DExtras::QMorphPhongMaterial::setInterpolator); + } + morphingAnimations[0]->deleteLater(); + } + + if (node->mNumMeshes == 1) { + if (material) + entityNode->addComponent(material); + // mesh + entityNode->addComponent(mesh); + } else { + QEntity *childEntity = QAbstractNodeFactory::createNode<Qt3DCore::QEntity>("QEntity"); + if (material) + childEntity->addComponent(material); + childEntity->addComponent(mesh); + childEntity->setParent(entityNode); + + Qt3DCore::QTransform *transform + = QAbstractNodeFactory::createNode<Qt3DCore::QTransform>("QTransform"); + childEntity->addComponent(transform); + } } // Add Children to Node @@ -467,6 +530,16 @@ Qt3DCore::QEntity *AssimpImporter::node(aiNode *node) transform->setMatrix(qTransformMatrix); entityNode->addComponent(transform); + QVector<Qt3DExtras::QKeyframeAnimation *> animations; + findAnimationsForNode<Qt3DExtras::QKeyframeAnimation>(m_scene->m_animations, + animations, + aiStringToQString(node->mName)); + + for (Qt3DExtras::QKeyframeAnimation *anim : animations) { + anim->setTarget(transform); + anim->setParent(entityNode); + } + // Add Camera if (m_scene->m_cameras.contains(node)) m_scene->m_cameras[node]->setParent(entityNode); @@ -497,7 +570,6 @@ void AssimpImporter::readSceneFile(const QString &path) m_scene->m_aiScene = m_scene->m_importer->ReadFile(path.toUtf8().constData(), aiProcess_SortByPType| aiProcess_Triangulate| - aiProcess_JoinIdenticalVertices| aiProcess_GenSmoothNormals| aiProcess_FlipUVs); if (m_scene->m_aiScene == nullptr) { @@ -713,8 +785,136 @@ void AssimpImporter::loadMesh(uint meshIndex) m_scene->m_meshes[meshIndex] = geometryRenderer; + if (mesh->mNumAnimMeshes > 0) { + + aiAnimMesh *animesh = mesh->mAnimMeshes[0]; + + if (animesh->mNumVertices != mesh->mNumVertices) + return; + + Qt3DExtras::QMorphingAnimation *morphingAnimation + = new Qt3DExtras::QMorphingAnimation(geometryRenderer); + QVector<QString> names; + QVector<Qt3DExtras::QMorphTarget *> targets; + uint voff = 0; + uint noff = 0; + uint tanoff = 0; + uint texoff = 0; + uint coloff = 0; + uint offset = 0; + if (animesh->mVertices) { + names.push_back(VERTICES_ATTRIBUTE_NAME); + offset += 3; + } + if (animesh->mNormals) { + names.push_back(NORMAL_ATTRIBUTE_NAME); + noff = offset; + offset += 3; + } + if (animesh->mTangents) { + names.push_back(TANGENT_ATTRIBUTE_NAME); + tanoff = offset; + offset += 3; + } + if (animesh->mTextureCoords[0]) { + names.push_back(TEXTCOORD_ATTRIBUTE_NAME); + texoff = offset; + offset += 2; + } + if (animesh->mColors[0]) { + names.push_back(COLOR_ATTRIBUTE_NAME); + coloff = offset; + } + + ushort clumpSize = (animesh->mVertices ? 3 : 0) + + (animesh->mNormals ? 3 : 0) + + (animesh->mTangents ? 3 : 0) + + (animesh->mColors[0] ? 4 : 0) + + (animesh->mTextureCoords[0] ? 2 : 0); + + + for (uint i = 0; i < mesh->mNumAnimMeshes; i++) { + aiAnimMesh *animesh = mesh->mAnimMeshes[i]; + Qt3DExtras::QMorphTarget *target = new Qt3DExtras::QMorphTarget(geometryRenderer); + targets.push_back(target); + QVector<QAttribute *> attributes; + QByteArray targetBufferArray; + targetBufferArray.resize(clumpSize * mesh->mNumVertices * sizeof(float)); + float *dst = reinterpret_cast<float *>(targetBufferArray.data()); + + for (uint j = 0; j < mesh->mNumVertices; j++) { + if (animesh->mVertices) { + *dst++ = animesh->mVertices[j].x; + *dst++ = animesh->mVertices[j].y; + *dst++ = animesh->mVertices[j].z; + } + if (animesh->mNormals) { + *dst++ = animesh->mNormals[j].x; + *dst++ = animesh->mNormals[j].y; + *dst++ = animesh->mNormals[j].z; + } + if (animesh->mTangents) { + *dst++ = animesh->mTangents[j].x; + *dst++ = animesh->mTangents[j].y; + *dst++ = animesh->mTangents[j].z; + } + if (animesh->mTextureCoords[0]) { + *dst++ = animesh->mTextureCoords[0][j].x; + *dst++ = animesh->mTextureCoords[0][j].y; + } + if (animesh->mColors[0]) { + *dst++ = animesh->mColors[0][j].r; + *dst++ = animesh->mColors[0][j].g; + *dst++ = animesh->mColors[0][j].b; + *dst++ = animesh->mColors[0][j].a; + } + } + + Qt3DRender::QBuffer *targetBuffer + = QAbstractNodeFactory::createNode<Qt3DRender::QBuffer>("QBuffer"); + targetBuffer->setData(targetBufferArray); + targetBuffer->setParent(meshGeometry); + + if (animesh->mVertices) { + attributes.push_back(createAttribute(targetBuffer, VERTICES_ATTRIBUTE_NAME, + QAttribute::Float, 3, + animesh->mNumVertices, voff * sizeof(float), + clumpSize * sizeof(float), meshGeometry)); + } + if (animesh->mNormals) { + attributes.push_back(createAttribute(targetBuffer, NORMAL_ATTRIBUTE_NAME, + QAttribute::Float, 3, + animesh->mNumVertices, noff * sizeof(float), + clumpSize * sizeof(float), meshGeometry)); + } + if (animesh->mTangents) { + attributes.push_back(createAttribute(targetBuffer, TANGENT_ATTRIBUTE_NAME, + QAttribute::Float, 3, + animesh->mNumVertices, tanoff * sizeof(float), + clumpSize * sizeof(float), meshGeometry)); + } + if (animesh->mTextureCoords[0]) { + attributes.push_back(createAttribute(targetBuffer, TEXTCOORD_ATTRIBUTE_NAME, + QAttribute::Float, 2, + animesh->mNumVertices, texoff * sizeof(float), + clumpSize * sizeof(float), meshGeometry)); + } + if (animesh->mColors[0]) { + attributes.push_back(createAttribute(targetBuffer, COLOR_ATTRIBUTE_NAME, + QAttribute::Float, 4, + animesh->mNumVertices, coloff * sizeof(float), + clumpSize * sizeof(float), meshGeometry)); + } + target->setAttributes(attributes); + } + morphingAnimation->setMorphTargets(targets); + morphingAnimation->setTargetName(aiStringToQString(mesh->mName)); + morphingAnimation->setTarget(geometryRenderer); + } + qCDebug(AssimpImporterLog) << Q_FUNC_INFO << " Mesh " << aiStringToQString(mesh->mName) - << " Vertices " << mesh->mNumVertices << " Faces " << mesh->mNumFaces << " Indices " << indices; + << " Vertices " << mesh->mNumVertices << " Faces " + << mesh->mNumFaces << " Indices " << indices; } /*! @@ -790,10 +990,145 @@ void AssimpImporter::loadCamera(uint cameraIndex) m_scene->m_cameras[cameraNode] = camera; } +int findTimeIndex(const QVector<float> ×, float time) { + for (int i = 0; i < times.size(); i++) { + if (qFuzzyCompare(times[i], time)) + return i; + } + return -1; +} + +void insertAtTime(QVector<float> &positions, QVector<Qt3DCore::QTransform *> &tranforms, + Qt3DCore::QTransform *t, float time) +{ + if (positions.size() == 0) { + positions.push_back(time); + tranforms.push_back(t); + } else if (time < positions.first()) { + positions.push_front(time); + tranforms.push_front(t); + } else if (time > positions.last()) { + positions.push_back(time); + tranforms.push_back(t); + } else { + qWarning() << "Insert new key in the middle of the keyframe not implemented."; + } +} + // OPTIONAL void AssimpImporter::loadAnimation(uint animationIndex) { - Q_UNUSED(animationIndex); + aiAnimation *assimpAnim = m_scene->m_aiScene->mAnimations[animationIndex]; + qCDebug(AssimpImporterLog) << "load Animation: "<< aiStringToQString(assimpAnim->mName); + double tickScale = 1.0; + if (!qFuzzyIsNull(assimpAnim->mTicksPerSecond)) + tickScale = 1.0 / assimpAnim->mTicksPerSecond; + + /* keyframe animations */ + for (uint i = 0; i < assimpAnim->mNumChannels; ++i) { + aiNodeAnim *nodeAnim = assimpAnim->mChannels[i]; + aiNode *targetNode = m_scene->m_aiScene->mRootNode->FindNode(nodeAnim->mNodeName); + + Qt3DExtras::QKeyframeAnimation *kfa = new Qt3DExtras::QKeyframeAnimation(); + QVector<float> positions; + QVector<Qt3DCore::QTransform*> transforms; + if ((nodeAnim->mNumPositionKeys > 1) + || !(nodeAnim->mNumPositionKeys == 1 && nodeAnim->mPositionKeys[0].mValue.x == 0 + && nodeAnim->mPositionKeys[0].mValue.y == 0 + && nodeAnim->mPositionKeys[0].mValue.z == 0)) { + for (uint j = 0; j < nodeAnim->mNumPositionKeys; j++) { + positions.push_back(nodeAnim->mPositionKeys[j].mTime); + Qt3DCore::QTransform *t = new Qt3DCore::QTransform(); + t->setTranslation(QVector3D(nodeAnim->mPositionKeys[j].mValue.x, + nodeAnim->mPositionKeys[j].mValue.y, + nodeAnim->mPositionKeys[j].mValue.z)); + transforms.push_back(t); + } + } + if ((nodeAnim->mNumRotationKeys > 1) || + !(nodeAnim->mNumRotationKeys == 1 && nodeAnim->mRotationKeys[0].mValue.x == 0 + && nodeAnim->mRotationKeys[0].mValue.y == 0 + && nodeAnim->mRotationKeys[0].mValue.z == 0 + && nodeAnim->mRotationKeys[0].mValue.w == 1)) { + for (uint j = 0; j < nodeAnim->mNumRotationKeys; j++) { + int index = findTimeIndex(positions, nodeAnim->mRotationKeys[j].mTime); + if (index >= 0) { + Qt3DCore::QTransform *t = transforms[index]; + t->setRotation(QQuaternion(nodeAnim->mRotationKeys[j].mValue.w, + nodeAnim->mRotationKeys[j].mValue.x, + nodeAnim->mRotationKeys[j].mValue.y, + nodeAnim->mRotationKeys[j].mValue.z)); + } else { + Qt3DCore::QTransform *t = new Qt3DCore::QTransform(); + t->setRotation(QQuaternion(nodeAnim->mRotationKeys[j].mValue.w, + nodeAnim->mRotationKeys[j].mValue.x, + nodeAnim->mRotationKeys[j].mValue.y, + nodeAnim->mRotationKeys[j].mValue.z)); + insertAtTime(positions, transforms, t, nodeAnim->mRotationKeys[j].mTime); + } + } + } + if ((nodeAnim->mNumScalingKeys > 1) + || !(nodeAnim->mNumScalingKeys == 1 && nodeAnim->mScalingKeys[0].mValue.x == 1 + && nodeAnim->mScalingKeys[0].mValue.y == 1 + && nodeAnim->mScalingKeys[0].mValue.z == 1)) { + for (uint j = 0; j < nodeAnim->mNumScalingKeys; j++) { + int index = findTimeIndex(positions, nodeAnim->mScalingKeys[j].mTime); + if (index >= 0) { + Qt3DCore::QTransform *t = transforms[index]; + t->setScale3D(QVector3D(nodeAnim->mScalingKeys[j].mValue.x, + nodeAnim->mScalingKeys[j].mValue.y, + nodeAnim->mScalingKeys[j].mValue.z)); + } else { + Qt3DCore::QTransform *t = new Qt3DCore::QTransform(); + t->setScale3D(QVector3D(nodeAnim->mScalingKeys[j].mValue.x, + nodeAnim->mScalingKeys[j].mValue.y, + nodeAnim->mScalingKeys[j].mValue.z)); + insertAtTime(positions, transforms, t, nodeAnim->mScalingKeys[j].mTime); + } + } + } + for (int j = 0; j < positions.size(); ++j) + positions[j] = positions[j] * tickScale; + kfa->setFramePositions(positions); + kfa->setKeyframes(transforms); + kfa->setAnimationName(QString(assimpAnim->mName.C_Str())); + kfa->setTargetName(QString(targetNode->mName.C_Str())); + m_scene->m_animations.push_back(kfa); + } + /* mesh morph animations */ + for (uint i = 0; i < assimpAnim->mNumMorphMeshChannels; ++i) { + aiMeshMorphAnim *morphAnim = assimpAnim->mMorphMeshChannels[i]; + aiNode *targetNode = m_scene->m_aiScene->mRootNode->FindNode(morphAnim->mName); + aiMesh *mesh = m_scene->m_aiScene->mMeshes[targetNode->mMeshes[0]]; + + Qt3DExtras::QMorphingAnimation *morphingAnimation = new Qt3DExtras::QMorphingAnimation; + QVector<float> positions; + positions.resize(morphAnim->mNumKeys); + // set so that weights array is allocated to correct size in morphingAnimation + morphingAnimation->setTargetPositions(positions); + for (unsigned int j = 0; j < morphAnim->mNumKeys; ++j) { + aiMeshMorphKey &key = morphAnim->mKeys[j]; + positions[j] = key.mTime * tickScale; + + QVector<float> weights; + weights.resize(key.mNumValuesAndWeights); + for (int k = 0; k < weights.size(); k++) { + const unsigned int value = key.mValues[k]; + if (value < key.mNumValuesAndWeights) + weights[value] = key.mWeights[k]; + } + morphingAnimation->setWeights(j, weights); + } + + morphingAnimation->setTargetPositions(positions); + morphingAnimation->setAnimationName(QString(assimpAnim->mName.C_Str())); + morphingAnimation->setTargetName(QString(targetNode->mName.C_Str())); + morphingAnimation->setMethod((mesh->mMethod == aiMorphingMethod_MORPH_NORMALIZED) + ? Qt3DExtras::QMorphingAnimation::Normalized + : Qt3DExtras::QMorphingAnimation::Relative); + m_scene->m_morphAnimations.push_back(morphingAnimation); + } } /*! diff --git a/src/plugins/sceneparsers/assimp/assimpimporter.h b/src/plugins/sceneparsers/assimp/assimpimporter.h index fb60713b8..0d2c0c9e5 100644 --- a/src/plugins/sceneparsers/assimp/assimpimporter.h +++ b/src/plugins/sceneparsers/assimp/assimpimporter.h @@ -61,6 +61,7 @@ #include <QMap> #include <QDir> +#include <QVector> #include <QLoggingCategory> QT_BEGIN_NAMESPACE @@ -71,6 +72,11 @@ namespace Qt3DCore { class QCamera; } +namespace Qt3DExtras { +class QKeyframeAnimation; +class QMorphingAnimation; +} + namespace Qt3DRender { class QMaterial; @@ -138,6 +144,8 @@ private: QMap<QString, QAbstractTexture *> m_materialTextures; QMap<aiNode*, Qt3DCore::QEntity*> m_cameras; QHash<aiTextureType, QString> m_textureToParameterName; + QVector<Qt3DExtras::QKeyframeAnimation *> m_animations; + QVector<Qt3DExtras::QMorphingAnimation *> m_morphAnimations; // QMap<aiNode*, Light*> m_lights; }; diff --git a/src/quick3d/imports/extras/defaults.qrc b/src/quick3d/imports/extras/defaults.qrc new file mode 100644 index 000000000..7b07aafab --- /dev/null +++ b/src/quick3d/imports/extras/defaults.qrc @@ -0,0 +1,21 @@ +<RCC> +<qresource prefix="/qt-project.org/imports/Qt3D/Extras/"> +<file alias="defaults/qml/DefaultEffect.qml">defaults/qml/DefaultEffect.qml</file> +<file alias="defaults/qml/DefaultAlphaEffect.qml">defaults/qml/DefaultAlphaEffect.qml</file> +<file alias="defaults/qml/PhongMaterial.qml">defaults/qml/PhongMaterial.qml</file> +<file alias="defaults/qml/DiffuseMapMaterial.qml">defaults/qml/DiffuseMapMaterial.qml</file> +<file alias="defaults/qml/DiffuseSpecularMapMaterial.qml">defaults/qml/DiffuseSpecularMapMaterial.qml</file> +<file alias="defaults/qml/NormalDiffuseMapMaterial.qml">defaults/qml/NormalDiffuseMapMaterial.qml</file> +<file alias="defaults/qml/NormalDiffuseMapAlphaMaterial.qml">defaults/qml/NormalDiffuseMapAlphaMaterial.qml</file> +<file alias="defaults/qml/NormalDiffuseSpecularMapMaterial.qml">defaults/qml/NormalDiffuseSpecularMapMaterial.qml</file> +<file alias="defaults/qml/ForwardRenderer.qml">defaults/qml/ForwardRenderer.qml</file> +<file alias="defaults/qml/PerVertexColorMaterial.qml">defaults/qml/PerVertexColorMaterial.qml</file> +<file alias="defaults/qml/SkyboxEntity.qml">defaults/qml/SkyboxEntity.qml</file> +<file alias="defaults/qml/GoochMaterial.qml">defaults/qml/GoochMaterial.qml</file> +<file alias="defaults/qml/PhongAlphaMaterial.qml">defaults/qml/PhongAlphaMaterial.qml</file> +<file alias="defaults/qml/TextureMaterial.qml">defaults/qml/TextureMaterial.qml</file> +<file alias="defaults/qml/OrbitCameraController.qml">defaults/qml/OrbitCameraController.qml</file> +<file alias="defaults/qml/FirstPersonCameraController.qml">defaults/qml/FirstPersonCameraController.qml</file> +<file alias="defaults/qml/NormalDiffuseMapAlphaEffect.qml">defaults/qml/NormalDiffuseMapAlphaEffect.qml</file> +</qresource> +</RCC> diff --git a/src/quick3d/imports/extras/importsextras.pro b/src/quick3d/imports/extras/importsextras.pro index acc993fa7..6a70238f4 100644 --- a/src/quick3d/imports/extras/importsextras.pro +++ b/src/quick3d/imports/extras/importsextras.pro @@ -3,7 +3,7 @@ TARGET = quick3dextrasplugin TARGETPATH = Qt3D/Extras IMPORT_VERSION = 2.0 -QT += core-private qml qml-private quick quick-private 3dcore 3dcore-private 3dquick 3dquick-private 3dextras 3dlogic +QT += core-private qml qml-private quick quick-private 3dcore 3dcore-private 3dquick 3dquick-private 3dextras 3dlogic 3dquickextras 3dquickextras-private # Qt3D is free of Q_FOREACH - make sure it stays that way: DEFINES += QT_NO_FOREACH diff --git a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp index 7d695ea5b..55af6432b 100644 --- a/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp +++ b/src/quick3d/imports/extras/qt3dquick3dextrasplugin.cpp @@ -52,6 +52,19 @@ #include <Qt3DExtras/qcylindergeometry.h> #include <Qt3DExtras/qtext3dgeometry.h> #include <Qt3DExtras/qtext3dmesh.h> +#include <Qt3DExtras/qkeyframeanimation.h> +#include <Qt3DExtras/qanimationcontroller.h> +#include <Qt3DExtras/qabstractanimation.h> +#include <Qt3DExtras/qmorphinganimation.h> +#include <Qt3DExtras/qanimationgroup.h> +#include <Qt3DExtras/qmorphtarget.h> + +#include <Qt3DQuickExtras/private/quick3dkeyframeanimation_p.h> +#include <Qt3DQuickExtras/private/quick3danimationgroup_p.h> +#include <Qt3DQuickExtras/private/quick3danimationcontroller_p.h> +#include <Qt3DQuickExtras/private/quick3dmorphtarget_p.h> +#include <Qt3DQuickExtras/private/quick3dmorphinganimation_p.h> + #include <QtQml/qqml.h> QT_BEGIN_NAMESPACE @@ -106,6 +119,13 @@ void Qt3DQuick3DExtrasPlugin::registerTypes(const char *uri) qmlRegisterType<Qt3DExtras::QText3DGeometry>(uri, 2, 2, "Text3DGeometry"); qmlRegisterType<Qt3DExtras::QText3DMesh>(uri, 2, 2, "Text3DMesh"); + qmlRegisterUncreatableType<Qt3DExtras::QAbstractAnimation>(uri, 2, 0, "AbstractAnimation", QStringLiteral("AbstractAnimation is abstract")); + qmlRegisterExtendedType<Qt3DExtras::QKeyframeAnimation, Qt3DExtras::Quick::QQuick3DKeyframeAnimation>(uri, 2, 2, "KeyframeAnimation"); + qmlRegisterExtendedType<Qt3DExtras::QAnimationGroup, Qt3DExtras::Quick::QQuick3DAnimationGroup>(uri, 2, 2, "AnimationGroup"); + qmlRegisterExtendedType<Qt3DExtras::QAnimationController, Qt3DExtras::Quick::QQuick3DAnimationController>(uri, 2, 2, "AnimationController"); + qmlRegisterExtendedType<Qt3DExtras::QMorphingAnimation, Qt3DExtras::Quick::QQuick3DMorphingAnimation>(uri, 2, 2, "MorphingAnimation"); + qmlRegisterExtendedType<Qt3DExtras::QMorphTarget, Qt3DExtras::Quick::QQuick3DMorphTarget>(uri, 2, 2, "MorphTarget"); + // Register types provided as QML files compiled into the plugin for (int i = 0; i < int(sizeof(qmldir) / sizeof(qmldir[0])); i++) { auto path = QLatin1String("qrc:/qt-project.org/imports/Qt3D/Extras/defaults/qml/"); diff --git a/src/quick3d/quick3dextras/items/items.pri b/src/quick3d/quick3dextras/items/items.pri new file mode 100644 index 000000000..cdb1e1245 --- /dev/null +++ b/src/quick3d/quick3dextras/items/items.pri @@ -0,0 +1,15 @@ +HEADERS += \ + $$PWD/quick3danimationcontroller_p.h \ + $$PWD/quick3danimationgroup_p.h \ + $$PWD/quick3dkeyframeanimation_p.h \ + $$PWD/quick3dmorphinganimation_p.h \ + $$PWD/quick3dmorphtarget_p.h + +SOURCES += \ + $$PWD/quick3danimationcontroller.cpp \ + $$PWD/quick3danimationgroup.cpp \ + $$PWD/quick3dkeyframeanimation.cpp \ + $$PWD/quick3dmorphinganimation.cpp \ + $$PWD/quick3dmorphtarget.cpp + +INCLUDEPATH += $$PWD diff --git a/src/quick3d/quick3dextras/items/quick3danimationcontroller.cpp b/src/quick3d/quick3dextras/items/quick3danimationcontroller.cpp new file mode 100644 index 000000000..4aceb0d55 --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3danimationcontroller.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "quick3danimationcontroller_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +QQuick3DAnimationController::QQuick3DAnimationController(QObject *parent) + : QObject(parent) +{ +} + +QQmlListProperty<QAnimationGroup> QQuick3DAnimationController::animationGroups() +{ + return QQmlListProperty<QAnimationGroup>(this, 0, + &QQuick3DAnimationController::appendAnimationGroup, + &QQuick3DAnimationController::animationGroupCount, + &QQuick3DAnimationController::animationGroupAt, + &QQuick3DAnimationController::clearAnimationGroups); +} + + +void QQuick3DAnimationController::appendAnimationGroup(QQmlListProperty<QAnimationGroup> *list, QAnimationGroup *bar) +{ + QQuick3DAnimationController *controller = qobject_cast<QQuick3DAnimationController *>(list->object); + if (controller) + controller->parentAnimationController()->addAnimationGroup(bar); +} + +int QQuick3DAnimationController::animationGroupCount(QQmlListProperty<QAnimationGroup> *list) +{ + QQuick3DAnimationController *controller = qobject_cast<QQuick3DAnimationController *>(list->object); + if (controller) + return controller->parentAnimationController()->animationGroupList().count(); + return 0; +} + +QAnimationGroup *QQuick3DAnimationController::animationGroupAt(QQmlListProperty<QAnimationGroup> *list, int index) +{ + QQuick3DAnimationController *controller = qobject_cast<QQuick3DAnimationController *>(list->object); + if (controller) + return qobject_cast<QAnimationGroup *>(controller->parentAnimationController()->getGroup(index)); + return nullptr; +} + +void QQuick3DAnimationController::clearAnimationGroups(QQmlListProperty<QAnimationGroup> *list) +{ + QQuick3DAnimationController *controller = qobject_cast<QQuick3DAnimationController *>(list->object); + if (controller) { + QVector<QAnimationGroup *> emptyList; + controller->parentAnimationController()->setAnimationGroups(emptyList); + } +} + + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/quick3d/quick3dextras/items/quick3danimationcontroller_p.h b/src/quick3d/quick3dextras/items/quick3danimationcontroller_p.h new file mode 100644 index 000000000..82ad29e2c --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3danimationcontroller_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QUICK_QUICK3DANIMATIONCONTROLLER_P_H +#define QT3DEXTRAS_QUICK_QUICK3DANIMATIONCONTROLLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DQuickExtras/qt3dquickextras_global.h> +#include <QQmlListProperty> +#include <Qt3DExtras/QAnimationController> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DAnimationController : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty<Qt3DExtras::QAnimationGroup> animationGroups READ animationGroups) + +public: + + explicit QQuick3DAnimationController(QObject *parent = nullptr); + + inline Qt3DExtras::QAnimationController *parentAnimationController() const + { + return qobject_cast<Qt3DExtras::QAnimationController *>(parent()); + } + + QQmlListProperty<Qt3DExtras::QAnimationGroup> animationGroups(); + +private: + + static void appendAnimationGroup(QQmlListProperty<Qt3DExtras::QAnimationGroup> *list, Qt3DExtras::QAnimationGroup *bar); + static QAnimationGroup *animationGroupAt(QQmlListProperty<Qt3DExtras::QAnimationGroup> *list, int index); + static int animationGroupCount(QQmlListProperty<Qt3DExtras::QAnimationGroup> *list); + static void clearAnimationGroups(QQmlListProperty<Qt3DExtras::QAnimationGroup> *list); +}; + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DRENDER_RENDER_QUICK_QUICK3DEFFECT_P_H diff --git a/src/quick3d/quick3dextras/items/quick3danimationgroup.cpp b/src/quick3d/quick3dextras/items/quick3danimationgroup.cpp new file mode 100644 index 000000000..3e3813227 --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3danimationgroup.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "quick3danimationgroup_p.h" + +#include <Qt3DExtras/qabstractanimation.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +QQuick3DAnimationGroup::QQuick3DAnimationGroup(QObject *parent) + : QObject(parent) +{ +} + +QQmlListProperty<Qt3DExtras::QAbstractAnimation> QQuick3DAnimationGroup::animations() +{ + return QQmlListProperty<Qt3DExtras::QAbstractAnimation>(this, 0, + &QQuick3DAnimationGroup::appendAnimation, + &QQuick3DAnimationGroup::animationCount, + &QQuick3DAnimationGroup::animationAt, + &QQuick3DAnimationGroup::clearAnimation); +} + + +void QQuick3DAnimationGroup::appendAnimation(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list, + Qt3DExtras::QAbstractAnimation *animation) +{ + QQuick3DAnimationGroup *animationGroup = qobject_cast<QQuick3DAnimationGroup *>(list->object); + if (animationGroup) + animationGroup->parentAnimationGroup()->addAnimation(animation); +} + +int QQuick3DAnimationGroup::animationCount(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list) +{ + QQuick3DAnimationGroup *animationGroup = qobject_cast<QQuick3DAnimationGroup *>(list->object); + if (animationGroup) + return animationGroup->parentAnimationGroup()->animationList().count(); + return 0; +} + +Qt3DExtras::QAbstractAnimation *QQuick3DAnimationGroup::animationAt(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list, int index) +{ + QQuick3DAnimationGroup *animationGroup = qobject_cast<QQuick3DAnimationGroup *>(list->object); + if (animationGroup) { + return qobject_cast<Qt3DExtras::QAbstractAnimation *>( + animationGroup->parentAnimationGroup()->animationList().at(index)); + } + return nullptr; +} + +void QQuick3DAnimationGroup::clearAnimation(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list) +{ + QQuick3DAnimationGroup *animationGroup = qobject_cast<QQuick3DAnimationGroup *>(list->object); + if (animationGroup) { + QVector<Qt3DExtras::QAbstractAnimation *> emptyList; + animationGroup->parentAnimationGroup()->setAnimations(emptyList); + } +} + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/quick3d/quick3dextras/items/quick3danimationgroup_p.h b/src/quick3d/quick3dextras/items/quick3danimationgroup_p.h new file mode 100644 index 000000000..c7140c946 --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3danimationgroup_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QUICK_QUICK3DANIMATIONGROUP_P_H +#define QT3DEXTRAS_QUICK_QUICK3DANIMATIONGROUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqmllist.h> +#include <Qt3DExtras/qabstractanimation.h> +#include <Qt3DExtras/qanimationgroup.h> + +#include <Qt3DQuickExtras/qt3dquickextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DAnimationGroup : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty<Qt3DExtras::QAbstractAnimation> animations READ animations) + +public: + + explicit QQuick3DAnimationGroup(QObject *parent = nullptr); + + inline Qt3DExtras::QAnimationGroup *parentAnimationGroup() const + { + return qobject_cast<Qt3DExtras::QAnimationGroup *>(parent()); + } + + QQmlListProperty<Qt3DExtras::QAbstractAnimation> animations(); + +private: + + static void appendAnimation(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list, Qt3DExtras::QAbstractAnimation *animation); + static Qt3DExtras::QAbstractAnimation *animationAt(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list, int index); + static int animationCount(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list); + static void clearAnimation(QQmlListProperty<Qt3DExtras::QAbstractAnimation> *list); +}; + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DRENDER_RENDER_QUICK_QUICK3DEFFECT_P_H diff --git a/src/quick3d/quick3dextras/items/quick3dkeyframeanimation.cpp b/src/quick3d/quick3dextras/items/quick3dkeyframeanimation.cpp new file mode 100644 index 000000000..cfd9ca7d2 --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3dkeyframeanimation.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "quick3dkeyframeanimation_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +QQuick3DKeyframeAnimation::QQuick3DKeyframeAnimation(QObject *parent) + : QObject(parent) +{ +} + +QQmlListProperty<Qt3DCore::QTransform> QQuick3DKeyframeAnimation::keyframes() +{ + return QQmlListProperty<Qt3DCore::QTransform>(this, 0, + &QQuick3DKeyframeAnimation::appendKeyframe, + &QQuick3DKeyframeAnimation::keyframeCount, + &QQuick3DKeyframeAnimation::keyframeAt, + &QQuick3DKeyframeAnimation::clearKeyframes); +} + +void QQuick3DKeyframeAnimation::appendKeyframe(QQmlListProperty<Qt3DCore::QTransform> *list, + Qt3DCore::QTransform *transform) +{ + QQuick3DKeyframeAnimation *keyframeAnimation + = qobject_cast<QQuick3DKeyframeAnimation *>(list->object); + if (keyframeAnimation) + keyframeAnimation->parentKeyframeAnimation()->addKeyframe(transform); +} + +int QQuick3DKeyframeAnimation::keyframeCount(QQmlListProperty<Qt3DCore::QTransform> *list) +{ + QQuick3DKeyframeAnimation *keyframeAnimation + = qobject_cast<QQuick3DKeyframeAnimation *>(list->object); + if (keyframeAnimation) + return keyframeAnimation->parentKeyframeAnimation()->keyframeList().count(); + return 0; +} + +Qt3DCore::QTransform *QQuick3DKeyframeAnimation::keyframeAt(QQmlListProperty<Qt3DCore::QTransform> *list, + int index) +{ + QQuick3DKeyframeAnimation *keyframeAnimation + = qobject_cast<QQuick3DKeyframeAnimation *>(list->object); + if (keyframeAnimation) { + return qobject_cast<Qt3DCore::QTransform *>( + keyframeAnimation->parentKeyframeAnimation()->keyframeList().at(index)); + } + return nullptr; +} + +void QQuick3DKeyframeAnimation::clearKeyframes(QQmlListProperty<Qt3DCore::QTransform> *list) +{ + QQuick3DKeyframeAnimation *keyframeAnimation + = qobject_cast<QQuick3DKeyframeAnimation *>(list->object); + if (keyframeAnimation) { + QVector<Qt3DCore::QTransform *> emptyList; + keyframeAnimation->parentKeyframeAnimation()->setKeyframes(emptyList); + } +} + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/quick3d/quick3dextras/items/quick3dkeyframeanimation_p.h b/src/quick3d/quick3dextras/items/quick3dkeyframeanimation_p.h new file mode 100644 index 000000000..e8309de9e --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3dkeyframeanimation_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QUICK_QUICK3DKEYFRAMEANIMATION_P_H +#define QT3DEXTRAS_QUICK_QUICK3DKEYFRAMEANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqmllist.h> + +#include <Qt3DExtras/qkeyframeanimation.h> + +#include <Qt3DQuickExtras/qt3dquickextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DKeyframeAnimation : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty<Qt3DCore::QTransform> keyframes READ keyframes) + +public: + QQuick3DKeyframeAnimation(QObject *parent = nullptr); + + inline QKeyframeAnimation *parentKeyframeAnimation() const + { + return qobject_cast<QKeyframeAnimation *>(parent()); + } + + QQmlListProperty<Qt3DCore::QTransform> keyframes(); + +private: + + static void appendKeyframe(QQmlListProperty<Qt3DCore::QTransform> *list, + Qt3DCore::QTransform *transform); + static Qt3DCore::QTransform *keyframeAt(QQmlListProperty<Qt3DCore::QTransform> *list, + int index); + static int keyframeCount(QQmlListProperty<Qt3DCore::QTransform> *list); + static void clearKeyframes(QQmlListProperty<Qt3DCore::QTransform> *list); +}; + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QUICK_QUICK3DKEYFRAMEANIMATION_P_H diff --git a/src/quick3d/quick3dextras/items/quick3dmorphinganimation.cpp b/src/quick3d/quick3dextras/items/quick3dmorphinganimation.cpp new file mode 100644 index 000000000..61636f06d --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3dmorphinganimation.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "quick3dmorphinganimation_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +QQuick3DMorphingAnimation::QQuick3DMorphingAnimation(QObject *parent) + : QObject(parent) +{ +} + +QQmlListProperty<Qt3DExtras::QMorphTarget> QQuick3DMorphingAnimation::morphTargets() +{ + return QQmlListProperty<Qt3DExtras::QMorphTarget>(this, 0, + &QQuick3DMorphingAnimation::appendMorphTarget, + &QQuick3DMorphingAnimation::morphTargetCount, + &QQuick3DMorphingAnimation::morphTargetAt, + &QQuick3DMorphingAnimation::clearMorphTargets); +} + +void QQuick3DMorphingAnimation::appendMorphTarget(QQmlListProperty<Qt3DExtras::QMorphTarget> *list, + Qt3DExtras::QMorphTarget *morphTarget) +{ + QQuick3DMorphingAnimation *animation = qobject_cast<QQuick3DMorphingAnimation *>(list->object); + if (animation) + animation->parentMorphingAnimation()->addMorphTarget(morphTarget); +} + +int QQuick3DMorphingAnimation::morphTargetCount(QQmlListProperty<Qt3DExtras::QMorphTarget> *list) +{ + QQuick3DMorphingAnimation *animation = qobject_cast<QQuick3DMorphingAnimation *>(list->object); + if (animation) + return animation->parentMorphingAnimation()->morphTargetList().count(); + return 0; +} + +Qt3DExtras::QMorphTarget *QQuick3DMorphingAnimation::morphTargetAt(QQmlListProperty<Qt3DExtras::QMorphTarget> *list, + int index) +{ + QQuick3DMorphingAnimation *animation = qobject_cast<QQuick3DMorphingAnimation *>(list->object); + if (animation) { + return qobject_cast<Qt3DExtras::QMorphTarget *>( + animation->parentMorphingAnimation()->morphTargetList().at(index)); + } + return nullptr; +} + +void QQuick3DMorphingAnimation::clearMorphTargets(QQmlListProperty<Qt3DExtras::QMorphTarget> *list) +{ + QQuick3DMorphingAnimation *animation = qobject_cast<QQuick3DMorphingAnimation *>(list->object); + if (animation) { + QVector<Qt3DExtras::QMorphTarget *> emptyList; + animation->parentMorphingAnimation()->setMorphTargets(emptyList); + } +} + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/quick3d/quick3dextras/items/quick3dmorphinganimation_p.h b/src/quick3d/quick3dextras/items/quick3dmorphinganimation_p.h new file mode 100644 index 000000000..5f052fd04 --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3dmorphinganimation_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QUICK_QUICK3DMORPHINGANIMATION_P_H +#define QT3DEXTRAS_QUICK_QUICK3DMORPHINGANIMATION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqmllist.h> + +#include <Qt3DExtras/qmorphinganimation.h> + +#include <Qt3DQuickExtras/qt3dquickextras_global.h> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DMorphingAnimation : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty<Qt3DExtras::QMorphTarget> morphTargets READ morphTargets) + +public: + QQuick3DMorphingAnimation(QObject *parent = nullptr); + + inline QMorphingAnimation *parentMorphingAnimation() const + { + return qobject_cast<QMorphingAnimation *>(parent()); + } + + QQmlListProperty<Qt3DExtras::QMorphTarget> morphTargets(); + +private: + + static void appendMorphTarget(QQmlListProperty<Qt3DExtras::QMorphTarget> *list, + Qt3DExtras::QMorphTarget *morphTarget); + static Qt3DExtras::QMorphTarget *morphTargetAt(QQmlListProperty<Qt3DExtras::QMorphTarget> *list, + int index); + static int morphTargetCount(QQmlListProperty<Qt3DExtras::QMorphTarget> *list); + static void clearMorphTargets(QQmlListProperty<Qt3DExtras::QMorphTarget> *list); +}; + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QUICK_QUICK3DMORPHINGANIMATION_P_H diff --git a/src/quick3d/quick3dextras/items/quick3dmorphtarget.cpp b/src/quick3d/quick3dextras/items/quick3dmorphtarget.cpp new file mode 100644 index 000000000..8c1b9f0c1 --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3dmorphtarget.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "quick3dmorphtarget_p.h" + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +QQuick3DMorphTarget::QQuick3DMorphTarget(QObject *parent) + : QObject(parent) +{ +} + +QQmlListProperty<Qt3DRender::QAttribute> QQuick3DMorphTarget::attributes() +{ + return QQmlListProperty<Qt3DRender::QAttribute>(this, 0, + &QQuick3DMorphTarget::appendAttribute, + &QQuick3DMorphTarget::attributeCount, + &QQuick3DMorphTarget::attributeAt, + &QQuick3DMorphTarget::clearAttributes); +} + +void QQuick3DMorphTarget::appendAttribute(QQmlListProperty<Qt3DRender::QAttribute> *list, Qt3DRender::QAttribute *bar) +{ + QQuick3DMorphTarget *target = qobject_cast<QQuick3DMorphTarget *>(list->object); + if (target) + target->parentMorphTarget()->addAttribute(bar); +} + +int QQuick3DMorphTarget::attributeCount(QQmlListProperty<Qt3DRender::QAttribute> *list) +{ + QQuick3DMorphTarget *target = qobject_cast<QQuick3DMorphTarget *>(list->object); + if (target) + return target->parentMorphTarget()->attributeList().count(); + return 0; +} + +Qt3DRender::QAttribute *QQuick3DMorphTarget::attributeAt(QQmlListProperty<Qt3DRender::QAttribute> *list, int index) +{ + QQuick3DMorphTarget *target = qobject_cast<QQuick3DMorphTarget *>(list->object); + if (target) + return qobject_cast<Qt3DRender::QAttribute *>(target->parentMorphTarget()->attributeList().at(index)); + return nullptr; +} + +void QQuick3DMorphTarget::clearAttributes(QQmlListProperty<Qt3DRender::QAttribute> *list) +{ + QQuick3DMorphTarget *target = qobject_cast<QQuick3DMorphTarget *>(list->object); + if (target) { + QVector<Qt3DRender::QAttribute *> emptyList; + target->parentMorphTarget()->setAttributes(emptyList); + } +} + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE diff --git a/src/quick3d/quick3dextras/items/quick3dmorphtarget_p.h b/src/quick3d/quick3dextras/items/quick3dmorphtarget_p.h new file mode 100644 index 000000000..e5c664370 --- /dev/null +++ b/src/quick3d/quick3dextras/items/quick3dmorphtarget_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT3DEXTRAS_QUICK_QUICK3DMORPHTARGET_P_H +#define QT3DEXTRAS_QUICK_QUICK3DMORPHTARGET_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <Qt3DQuickExtras/qt3dquickextras_global.h> +#include <QQmlListProperty> +#include <Qt3DExtras/QMorphTarget> + +QT_BEGIN_NAMESPACE + +namespace Qt3DExtras { +namespace Quick { + +class QT3DQUICKEXTRASSHARED_EXPORT QQuick3DMorphTarget : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty<Qt3DRender::QAttribute> attributes READ attributes) + +public: + QQuick3DMorphTarget(QObject *parent = nullptr); + + inline QMorphTarget *parentMorphTarget() const { return qobject_cast<QMorphTarget *>(parent()); } + + QQmlListProperty<Qt3DRender::QAttribute> attributes(); + +private: + + static void appendAttribute(QQmlListProperty<Qt3DRender::QAttribute> *list, Qt3DRender::QAttribute *bar); + static Qt3DRender::QAttribute *attributeAt(QQmlListProperty<Qt3DRender::QAttribute> *list, int index); + static int attributeCount(QQmlListProperty<Qt3DRender::QAttribute> *list); + static void clearAttributes(QQmlListProperty<Qt3DRender::QAttribute> *list); +}; + +} // namespace Quick +} // namespace Qt3DExtras + +QT_END_NAMESPACE + +#endif // QT3DEXTRAS_QUICK_QUICK3DMORPHTARGET_P_H diff --git a/src/quick3d/quick3dextras/quick3dextras.pro b/src/quick3d/quick3dextras/quick3dextras.pro index 8965e9f5d..4f103765c 100644 --- a/src/quick3d/quick3dextras/quick3dextras.pro +++ b/src/quick3d/quick3dextras/quick3dextras.pro @@ -1,7 +1,7 @@ TARGET = Qt3DQuickExtras MODULE = 3dquickextras -QT += core core-private qml qml-private 3dcore 3dinput 3dquick 3drender 3drender-private 3dlogic +QT += core core-private qml qml-private 3dcore 3dinput 3dquick 3drender 3drender-private 3dlogic 3dextras CONFIG -= precompile_header # Qt3D is free of Q_FOREACH - make sure it stays that way: @@ -23,4 +23,6 @@ HEADERS += \ # otherwise mingw headers do not declare common functions like ::strcasecmp win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x +include(./items/items.pri) + load(qt_module) diff --git a/tests/manual/anim-viewer/anim-viewer.pro b/tests/manual/anim-viewer/anim-viewer.pro new file mode 100644 index 000000000..d9c3d8fb2 --- /dev/null +++ b/tests/manual/anim-viewer/anim-viewer.pro @@ -0,0 +1,13 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +TEMPLATE = app + +QT += qml quick 3dcore 3drender 3dinput 3dquick 3dextras 3dquickextras + +CONFIG += c++11 + +SOURCES += main.cpp + +RESOURCES += qml.qrc diff --git a/tests/manual/anim-viewer/assets/blendshapeanimation.dae b/tests/manual/anim-viewer/assets/blendshapeanimation.dae new file mode 100644 index 000000000..01edd1484 --- /dev/null +++ b/tests/manual/anim-viewer/assets/blendshapeanimation.dae @@ -0,0 +1,1281 @@ +<?xml version="1.0" encoding="utf-8"?> +<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1"> + <asset><contributor><author></author><authoring_tool>FBX COLLADA exporter</authoring_tool><comments></comments></contributor><created>2016-09-30T11:11:20Z</created><keywords></keywords><modified>2016-09-30T11:11:20Z</modified><revision></revision><subject></subject><title></title><unit meter="0.010000" name="centimeter"></unit><up_axis>Y_UP</up_axis></asset> + <library_materials> + <material id="lambert2" name="lambert2"> + <instance_effect url="#lambert2-fx"/> + </material> + </library_materials> + <library_effects> + <effect id="lambert2-fx" name="lambert2"> + <profile_COMMON> + <technique sid="standard"> + <lambert> + <emission> + <color sid="emission">0.000000 0.000000 0.000000 1.000000</color> + </emission> + <ambient> + <color sid="ambient">0.000000 0.000000 0.000000 1.000000</color> + </ambient> + <diffuse> + <color sid="diffuse">0.400000 0.400000 0.400000 1.000000</color> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color sid="transparent">0.000000 0.000000 0.000000 1.000000</color> + </transparent> + <transparency> + <float sid="transparency">1.000000</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + </library_effects> + <library_geometries> + <geometry id="pPlane16-lib" name="pPlane16Mesh"> + <mesh> + <source id="pPlane16-POSITION"> + <float_array id="pPlane16-POSITION-array" count="258"> +-0.312507 -0.000000 2.637385 +0.312506 -0.000000 2.637385 +-0.312507 -0.000000 2.359762 +0.312506 -0.000000 2.359762 +-0.312507 -0.000000 2.082143 +0.312506 -0.000000 2.082143 +-0.312507 -0.000000 1.804527 +0.312506 -0.000000 1.804527 +-0.312507 -0.000000 1.526906 +0.312506 -0.000000 1.526906 +-0.312506 0.000000 -1.526906 +0.312507 0.000000 -1.526906 +-0.312506 0.000000 -1.804527 +0.312507 0.000000 -1.804527 +-0.312506 0.000000 -2.082142 +0.312507 0.000000 -2.082142 +-0.312506 0.000000 -2.359762 +0.312507 0.000000 -2.359762 +-0.312506 0.000000 -2.637385 +0.312507 0.000000 -2.637385 +0.312507 0.000000 -2.498573 +-0.312506 0.000000 -2.498573 +0.312507 0.000000 -2.220952 +-0.312506 0.000000 -2.220952 +0.312507 0.000000 -1.943334 +-0.312506 0.000000 -1.943334 +0.312507 0.000000 -1.665716 +-0.312506 0.000000 -1.665716 +0.312506 -0.000000 1.665716 +-0.312507 -0.000000 1.665716 +0.312506 -0.000000 1.943335 +-0.312507 -0.000000 1.943335 +0.312506 -0.000000 2.220952 +-0.312507 -0.000000 2.220952 +0.312506 -0.000000 2.498574 +-0.312507 -0.000000 2.498574 +0.312506 -0.000000 1.380497 +-0.312507 -0.000000 1.380497 +0.312506 -0.000000 1.236356 +-0.312507 -0.000000 1.236356 +0.312506 -0.000000 1.096244 +-0.312507 -0.000000 1.096244 +0.312506 -0.000000 0.961413 +-0.312507 -0.000000 0.961413 +0.312506 -0.000000 0.832655 +-0.312507 -0.000000 0.832655 +0.312507 -0.000000 0.710343 +-0.312507 -0.000000 0.710343 +0.312507 -0.000000 0.594481 +-0.312507 -0.000000 0.594481 +0.312507 -0.000000 0.484749 +-0.312507 -0.000000 0.484749 +0.312507 -0.000000 0.380550 +-0.312507 -0.000000 0.380550 +0.312507 -0.000000 0.281054 +-0.312507 -0.000000 0.281054 +0.312507 -0.000000 0.185247 +-0.312507 -0.000000 0.185247 +0.312507 -0.000000 0.091978 +-0.312507 -0.000000 0.091978 +0.312507 -0.000000 -0.000000 +-0.312507 -0.000000 -0.000000 +0.312507 0.000000 -0.091978 +-0.312507 0.000000 -0.091978 +0.312507 0.000000 -0.185248 +-0.312507 0.000000 -0.185248 +0.312507 0.000000 -0.281054 +-0.312507 0.000000 -0.281054 +0.312507 0.000000 -0.380550 +-0.312507 0.000000 -0.380550 +0.312507 0.000000 -0.484749 +-0.312507 0.000000 -0.484749 +0.312507 0.000000 -0.594481 +-0.312507 0.000000 -0.594481 +0.312507 0.000000 -0.710343 +-0.312507 0.000000 -0.710343 +0.312507 0.000000 -0.832655 +-0.312506 0.000000 -0.832655 +0.312507 0.000000 -0.961414 +-0.312506 0.000000 -0.961414 +0.312507 0.000000 -1.096244 +-0.312506 0.000000 -1.096244 +0.312507 0.000000 -1.236356 +-0.312506 0.000000 -1.236356 +0.312507 0.000000 -1.380498 +-0.312506 0.000000 -1.380498 +</float_array> + <technique_common> + <accessor source="#pPlane16-POSITION-array" count="86" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="pPlane16-Normal0"> + <float_array id="pPlane16-Normal0-array" count="258"> +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +</float_array> + <technique_common> + <accessor source="#pPlane16-Normal0-array" count="86" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="pPlane16-UV0"> + <float_array id="pPlane16-UV0-array" count="172"> +0.000000 0.000000 +1.000000 0.000000 +0.000000 0.052632 +1.000000 0.052632 +0.000000 0.105263 +1.000000 0.105263 +0.000000 0.157895 +1.000000 0.157895 +0.000000 0.210526 +1.000000 0.210526 +0.000000 0.789474 +1.000000 0.789474 +0.000000 0.842105 +1.000000 0.842105 +0.000000 0.894737 +1.000000 0.894737 +0.000000 0.947368 +1.000000 0.947368 +0.000000 1.000000 +1.000000 1.000000 +1.000000 0.973684 +0.000000 0.973684 +1.000000 0.921053 +0.000000 0.921053 +1.000000 0.868421 +0.000000 0.868421 +1.000000 0.815789 +0.000000 0.815789 +1.000000 0.184211 +0.000000 0.184211 +1.000000 0.131579 +0.000000 0.131579 +1.000000 0.078947 +0.000000 0.078947 +1.000000 0.026316 +0.000000 0.026316 +1.000000 0.232794 +0.000000 0.232794 +1.000000 0.255061 +0.000000 0.255061 +1.000000 0.277328 +0.000000 0.277328 +1.000000 0.299595 +0.000000 0.299595 +1.000000 0.321862 +0.000000 0.321862 +1.000000 0.344130 +0.000000 0.344130 +1.000000 0.366397 +0.000000 0.366397 +1.000000 0.388664 +0.000000 0.388664 +1.000000 0.410931 +0.000000 0.410931 +1.000000 0.433198 +0.000000 0.433198 +1.000000 0.455466 +0.000000 0.455466 +1.000000 0.477733 +0.000000 0.477733 +1.000000 0.500000 +0.000000 0.500000 +1.000000 0.522267 +0.000000 0.522267 +1.000000 0.544534 +0.000000 0.544534 +1.000000 0.566802 +0.000000 0.566802 +1.000000 0.589069 +0.000000 0.589069 +1.000000 0.611336 +0.000000 0.611336 +1.000000 0.633603 +0.000000 0.633603 +1.000000 0.655870 +0.000000 0.655870 +1.000000 0.678138 +0.000000 0.678138 +1.000000 0.700405 +0.000000 0.700405 +1.000000 0.722672 +0.000000 0.722672 +1.000000 0.744939 +0.000000 0.744939 +1.000000 0.767206 +0.000000 0.767206 +</float_array> + <technique_common> + <accessor source="#pPlane16-UV0-array" count="86" stride="2"> + <param name="S" type="float"/> + <param name="T" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="pPlane16-VERTEX"> + <input semantic="POSITION" source="#pPlane16-POSITION"/> + <input semantic="NORMAL" source="#pPlane16-Normal0"/> + </vertices> + <triangles count="84" material="lambert2"><input semantic="VERTEX" offset="0" source="#pPlane16-VERTEX"/><input semantic="TEXCOORD" offset="1" set="0" source="#pPlane16-UV0"/><p> 0 0 1 1 34 34 0 0 34 34 35 35 2 2 3 3 32 32 2 2 32 32 33 33 4 4 5 5 30 30 4 4 30 30 31 31 6 6 7 7 28 28 6 6 28 28 29 29 10 10 11 11 26 26 10 10 26 26 27 27 12 12 13 13 24 24 12 12 24 24 25 25 14 14 15 15 22 22 14 14 22 22 23 23 16 16 17 17 20 20 16 16 20 20 21 21 21 21 20 20 19 19 21 21 19 19 18 18 23 23 22 22 17 17 23 23 17 17 16 16 25 25 24 24 15 15 25 25 15 15 14 14 27 27 26 26 13 13 27 27 13 13 12 12 29 29 28 28 9 9 29 29 9 9 8 8 31 31 30 30 7 7 31 31 7 7 6 6 33 33 32 32 5 5 33 33 5 5 4 4 35 35 34 34 3 3 35 35 3 3 2 2 8 8 9 9 36 36 8 8 36 36 37 37 36 36 39 39 37 37 39 39 36 36 38 38 40 40 39 39 38 38 39 39 40 40 41 41 41 41 40 40 42 42 41 41 42 42 43 43 44 44 43 43 42 42 43 43 44 44 45 45 44 44 47 47 45 45 47 47 44 44 46 46 48 48 47 47 46 46 47 47 48 48 49 49 49 49 48 48 50 50 49 49 50 50 51 51 51 51 50 50 52 52 51 51 52 52 53 53 52 52 55 55 53 53 55 55 52 52 54 54 55 55 54 54 56 56 55 55 56 56 57 57 58 58 57 57 56 56 57 57 58 58 59 59 58 58 61 61 59 59 61 61 58 58 60 60 60 60 63 63 61 61 63 63 60 60 62 62 64 64 63 63 62 62 63 63 64 64 65 65 65 65 64 64 66 66 65 65 66 66 67 67 66 66 69 69 67 67 69 69 66 66 68 68 69 69 68 68 70 70 69 69 70 70 71 71 71 71 70 70 72 72 71 71 72 72 73 73 74 74 73 73 72 72 73 73 74 74 75 75 74 74 77 77 75 75 77 77 74 74 76 76 77 77 76 76 78 78 77 77 78 78 79 79 79 79 78 78 80 80 79 79 80 80 81 81 82 82 81 81 80 80 81 81 82 82 83 83 82 82 85 85 83 83 85 85 82 82 84 84 85 85 84 84 11 11 85 85 11 11 10 10</p></triangles> + </mesh> + </geometry> + <geometry id="pPlane13-lib" name="pPlane13Mesh"> + <mesh> + <source id="pPlane13-POSITION"> + <float_array id="pPlane13-POSITION-array" count="258"> +0.277128 -0.000000 2.637385 +0.902142 -0.000000 2.637385 +0.277128 -0.000000 2.359762 +0.902142 -0.000000 2.359762 +0.277128 -0.000000 2.082143 +0.902142 -0.000000 2.082143 +0.277128 -0.000000 1.804527 +0.902142 -0.000000 1.804527 +0.277128 -0.000000 1.526906 +0.902142 -0.000000 1.526906 +-0.312506 0.000000 -1.526906 +0.312507 0.000000 -1.526906 +-0.312506 0.000000 -1.804527 +0.312507 0.000000 -1.804527 +-0.312506 0.000000 -2.082142 +0.312507 0.000000 -2.082142 +-0.312506 0.000000 -2.359762 +0.312507 0.000000 -2.359762 +-0.312506 0.000000 -2.637385 +0.312507 0.000000 -2.637385 +0.312507 0.000000 -2.498573 +-0.312506 0.000000 -2.498573 +0.312507 0.000000 -2.220952 +-0.312506 0.000000 -2.220952 +0.312507 0.000000 -1.943334 +-0.312506 0.000000 -1.943334 +0.312507 0.000000 -1.665716 +-0.312506 0.000000 -1.665716 +0.902142 -0.000000 1.665716 +0.277128 -0.000000 1.665716 +0.902142 -0.000000 1.943335 +0.277128 -0.000000 1.943335 +0.902142 -0.000000 2.220952 +0.277128 -0.000000 2.220952 +0.902142 -0.000000 2.498574 +0.277128 -0.000000 2.498574 +0.901823 -0.000000 1.377058 +0.276814 -0.000000 1.378653 +0.899714 -0.000000 1.226396 +0.274789 -0.000000 1.236163 +0.894316 -0.000000 1.076746 +0.269829 -0.000000 1.101454 +0.884449 -0.000000 0.929918 +0.261180 -0.000000 0.975449 +0.869252 -0.000000 0.787199 +0.248482 -0.000000 0.858589 +0.848199 -0.000000 0.649525 +0.231682 -0.000000 0.750752 +0.821141 -0.000000 0.517632 +0.210924 -0.000000 0.651211 +0.788364 -0.000000 0.392129 +0.186414 -0.000000 0.558660 +0.750629 -0.000000 0.273497 +0.158320 -0.000000 0.471312 +0.709139 -0.000000 0.162012 +0.126714 -0.000000 0.387082 +0.665419 -0.000000 0.057629 +0.091640 -0.000000 0.303802 +0.621099 -0.000000 -0.040095 +0.053245 -0.000000 0.219401 +0.577691 -0.000000 -0.132024 +0.011945 -0.000000 0.132024 +0.536391 0.000000 -0.219402 +-0.031463 0.000000 0.040094 +0.497996 0.000000 -0.303803 +-0.075782 0.000000 -0.057630 +0.462922 0.000000 -0.387082 +-0.119503 0.000000 -0.162013 +0.431317 0.000000 -0.471312 +-0.160993 0.000000 -0.273498 +0.403221 0.000000 -0.558660 +-0.198729 0.000000 -0.392129 +0.378712 0.000000 -0.651212 +-0.231505 0.000000 -0.517632 +0.357954 0.000000 -0.750752 +-0.258563 0.000000 -0.649525 +0.341155 0.000000 -0.858589 +-0.279616 0.000000 -0.787199 +0.328456 0.000000 -0.975448 +-0.294814 0.000000 -0.929919 +0.319807 0.000000 -1.101453 +-0.304681 0.000000 -1.076746 +0.314846 0.000000 -1.236163 +-0.310079 0.000000 -1.226396 +0.312821 0.000000 -1.378653 +-0.312188 0.000000 -1.377058 +</float_array> + <technique_common> + <accessor source="#pPlane13-POSITION-array" count="86" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="pPlane13-Normal0"> + <float_array id="pPlane13-Normal0-array" count="258"> +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +</float_array> + <technique_common> + <accessor source="#pPlane13-Normal0-array" count="86" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="pPlane13-UV0"> + <float_array id="pPlane13-UV0-array" count="172"> +0.000000 0.000000 +1.000000 0.000000 +0.000000 0.052632 +1.000000 0.052632 +0.000000 0.105263 +1.000000 0.105263 +0.000000 0.157895 +1.000000 0.157895 +0.000000 0.210526 +1.000000 0.210526 +0.000000 0.789474 +1.000000 0.789474 +0.000000 0.842105 +1.000000 0.842105 +0.000000 0.894737 +1.000000 0.894737 +0.000000 0.947368 +1.000000 0.947368 +0.000000 1.000000 +1.000000 1.000000 +1.000000 0.973684 +0.000000 0.973684 +1.000000 0.921053 +0.000000 0.921053 +1.000000 0.868421 +0.000000 0.868421 +1.000000 0.815789 +0.000000 0.815789 +1.000000 0.184211 +0.000000 0.184211 +1.000000 0.131579 +0.000000 0.131579 +1.000000 0.078947 +0.000000 0.078947 +1.000000 0.026316 +0.000000 0.026316 +1.000000 0.232794 +0.000000 0.232794 +1.000000 0.255061 +0.000000 0.255061 +1.000000 0.277328 +0.000000 0.277328 +1.000000 0.299595 +0.000000 0.299595 +1.000000 0.321862 +0.000000 0.321862 +1.000000 0.344130 +0.000000 0.344130 +1.000000 0.366397 +0.000000 0.366397 +1.000000 0.388664 +0.000000 0.388664 +1.000000 0.410931 +0.000000 0.410931 +1.000000 0.433198 +0.000000 0.433198 +1.000000 0.455466 +0.000000 0.455466 +1.000000 0.477733 +0.000000 0.477733 +1.000000 0.500000 +0.000000 0.500000 +1.000000 0.522267 +0.000000 0.522267 +1.000000 0.544534 +0.000000 0.544534 +1.000000 0.566802 +0.000000 0.566802 +1.000000 0.589069 +0.000000 0.589069 +1.000000 0.611336 +0.000000 0.611336 +1.000000 0.633603 +0.000000 0.633603 +1.000000 0.655870 +0.000000 0.655870 +1.000000 0.678138 +0.000000 0.678138 +1.000000 0.700405 +0.000000 0.700405 +1.000000 0.722672 +0.000000 0.722672 +1.000000 0.744939 +0.000000 0.744939 +1.000000 0.767206 +0.000000 0.767206 +</float_array> + <technique_common> + <accessor source="#pPlane13-UV0-array" count="86" stride="2"> + <param name="S" type="float"/> + <param name="T" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="pPlane13-VERTEX"> + <input semantic="POSITION" source="#pPlane13-POSITION"/> + <input semantic="NORMAL" source="#pPlane13-Normal0"/> + </vertices> + <triangles count="84"><input semantic="VERTEX" offset="0" source="#pPlane13-VERTEX"/><input semantic="TEXCOORD" offset="1" set="0" source="#pPlane13-UV0"/><p> 0 0 1 1 34 34 0 0 34 34 35 35 2 2 3 3 32 32 2 2 32 32 33 33 4 4 5 5 30 30 4 4 30 30 31 31 6 6 7 7 28 28 6 6 28 28 29 29 10 10 11 11 26 26 10 10 26 26 27 27 12 12 13 13 24 24 12 12 24 24 25 25 14 14 15 15 22 22 14 14 22 22 23 23 16 16 17 17 20 20 16 16 20 20 21 21 21 21 20 20 19 19 21 21 19 19 18 18 23 23 22 22 17 17 23 23 17 17 16 16 25 25 24 24 15 15 25 25 15 15 14 14 27 27 26 26 13 13 27 27 13 13 12 12 29 29 28 28 9 9 29 29 9 9 8 8 31 31 30 30 7 7 31 31 7 7 6 6 33 33 32 32 5 5 33 33 5 5 4 4 35 35 34 34 3 3 35 35 3 3 2 2 8 8 9 9 36 36 8 8 36 36 37 37 36 36 39 39 37 37 39 39 36 36 38 38 40 40 39 39 38 38 39 39 40 40 41 41 41 41 40 40 42 42 41 41 42 42 43 43 44 44 43 43 42 42 43 43 44 44 45 45 44 44 47 47 45 45 47 47 44 44 46 46 48 48 47 47 46 46 47 47 48 48 49 49 49 49 48 48 50 50 49 49 50 50 51 51 51 51 50 50 52 52 51 51 52 52 53 53 52 52 55 55 53 53 55 55 52 52 54 54 55 55 54 54 56 56 55 55 56 56 57 57 58 58 57 57 56 56 57 57 58 58 59 59 58 58 61 61 59 59 61 61 58 58 60 60 60 60 63 63 61 61 63 63 60 60 62 62 64 64 63 63 62 62 63 63 64 64 65 65 65 65 64 64 66 66 65 65 66 66 67 67 66 66 69 69 67 67 69 69 66 66 68 68 69 69 68 68 70 70 69 69 70 70 71 71 71 71 70 70 72 72 71 71 72 72 73 73 74 74 73 73 72 72 73 73 74 74 75 75 74 74 77 77 75 75 77 77 74 74 76 76 77 77 76 76 78 78 77 77 78 78 79 79 79 79 78 78 80 80 79 79 80 80 81 81 82 82 81 81 80 80 81 81 82 82 83 83 82 82 85 85 83 83 85 85 82 82 84 84 85 85 84 84 11 11 85 85 11 11 10 10</p></triangles> + </mesh> + </geometry> + <geometry id="pPlane17-lib" name="pPlane17Mesh"> + <mesh> + <source id="pPlane17-POSITION"> + <float_array id="pPlane17-POSITION-array" count="258"> +-0.902142 -0.000000 2.637385 +-0.277128 -0.000000 2.637385 +-0.902142 -0.000000 2.359762 +-0.277128 -0.000000 2.359762 +-0.902142 -0.000000 2.082143 +-0.277128 -0.000000 2.082143 +-0.902142 -0.000000 1.804527 +-0.277128 -0.000000 1.804527 +-0.902142 -0.000000 1.526906 +-0.277128 -0.000000 1.526906 +-0.312506 0.000000 -1.526906 +0.312507 0.000000 -1.526906 +-0.312506 0.000000 -1.804527 +0.312507 0.000000 -1.804527 +-0.312506 0.000000 -2.082142 +0.312507 0.000000 -2.082142 +-0.312506 0.000000 -2.359762 +0.312507 0.000000 -2.359762 +-0.312506 0.000000 -2.637385 +0.312507 0.000000 -2.637385 +0.312507 0.000000 -2.498573 +-0.312506 0.000000 -2.498573 +0.312507 0.000000 -2.220952 +-0.312506 0.000000 -2.220952 +0.312507 0.000000 -1.943334 +-0.312506 0.000000 -1.943334 +0.312507 0.000000 -1.665716 +-0.312506 0.000000 -1.665716 +-0.277128 -0.000000 1.665716 +-0.902142 -0.000000 1.665716 +-0.277128 -0.000000 1.943335 +-0.902142 -0.000000 1.943335 +-0.277128 -0.000000 2.220952 +-0.902142 -0.000000 2.220952 +-0.277128 -0.000000 2.498574 +-0.902142 -0.000000 2.498574 +-0.276814 -0.000000 1.378653 +-0.901823 -0.000000 1.377058 +-0.274789 -0.000000 1.236163 +-0.899714 -0.000000 1.226396 +-0.269829 -0.000000 1.101454 +-0.894316 -0.000000 1.076746 +-0.261179 -0.000000 0.975449 +-0.884449 -0.000000 0.929919 +-0.248481 -0.000000 0.858589 +-0.869251 -0.000000 0.787199 +-0.231682 -0.000000 0.750752 +-0.848198 -0.000000 0.649526 +-0.210923 -0.000000 0.651211 +-0.821140 -0.000000 0.517632 +-0.186414 -0.000000 0.558660 +-0.788364 -0.000000 0.392129 +-0.158320 -0.000000 0.471312 +-0.750629 -0.000000 0.273498 +-0.126714 -0.000000 0.387082 +-0.709139 -0.000000 0.162012 +-0.091639 -0.000000 0.303803 +-0.665418 -0.000000 0.057630 +-0.053244 -0.000000 0.219402 +-0.621099 -0.000000 -0.040095 +-0.011945 -0.000000 0.132024 +-0.577691 -0.000000 -0.132024 +0.031464 0.000000 0.040095 +-0.536390 0.000000 -0.219402 +0.075783 0.000000 -0.057630 +-0.497995 0.000000 -0.303803 +0.119504 0.000000 -0.162012 +-0.462921 0.000000 -0.387082 +0.160994 0.000000 -0.273498 +-0.431315 0.000000 -0.471312 +0.198730 0.000000 -0.392129 +-0.403220 0.000000 -0.558660 +0.231506 0.000000 -0.517633 +-0.378712 0.000000 -0.651212 +0.258564 0.000000 -0.649526 +-0.357953 0.000000 -0.750752 +0.279617 0.000000 -0.787199 +-0.341154 0.000000 -0.858589 +0.294815 0.000000 -0.929919 +-0.328455 0.000000 -0.975449 +0.304681 0.000000 -1.076746 +-0.319806 0.000000 -1.101453 +0.310079 0.000000 -1.226396 +-0.314846 0.000000 -1.236163 +0.312188 0.000000 -1.377058 +-0.312821 0.000000 -1.378653 +</float_array> + <technique_common> + <accessor source="#pPlane17-POSITION-array" count="86" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="pPlane17-Normal0"> + <float_array id="pPlane17-Normal0-array" count="258"> +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +0.000000 1.000000 0.000000 +-0.000000 1.000000 0.000000 +</float_array> + <technique_common> + <accessor source="#pPlane17-Normal0-array" count="86" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="pPlane17-UV0"> + <float_array id="pPlane17-UV0-array" count="172"> +0.000000 0.000000 +1.000000 0.000000 +0.000000 0.052632 +1.000000 0.052632 +0.000000 0.105263 +1.000000 0.105263 +0.000000 0.157895 +1.000000 0.157895 +0.000000 0.210526 +1.000000 0.210526 +0.000000 0.789474 +1.000000 0.789474 +0.000000 0.842105 +1.000000 0.842105 +0.000000 0.894737 +1.000000 0.894737 +0.000000 0.947368 +1.000000 0.947368 +0.000000 1.000000 +1.000000 1.000000 +1.000000 0.973684 +0.000000 0.973684 +1.000000 0.921053 +0.000000 0.921053 +1.000000 0.868421 +0.000000 0.868421 +1.000000 0.815789 +0.000000 0.815789 +1.000000 0.184211 +0.000000 0.184211 +1.000000 0.131579 +0.000000 0.131579 +1.000000 0.078947 +0.000000 0.078947 +1.000000 0.026316 +0.000000 0.026316 +1.000000 0.232794 +0.000000 0.232794 +1.000000 0.255061 +0.000000 0.255061 +1.000000 0.277328 +0.000000 0.277328 +1.000000 0.299595 +0.000000 0.299595 +1.000000 0.321862 +0.000000 0.321862 +1.000000 0.344130 +0.000000 0.344130 +1.000000 0.366397 +0.000000 0.366397 +1.000000 0.388664 +0.000000 0.388664 +1.000000 0.410931 +0.000000 0.410931 +1.000000 0.433198 +0.000000 0.433198 +1.000000 0.455466 +0.000000 0.455466 +1.000000 0.477733 +0.000000 0.477733 +1.000000 0.500000 +0.000000 0.500000 +1.000000 0.522267 +0.000000 0.522267 +1.000000 0.544534 +0.000000 0.544534 +1.000000 0.566802 +0.000000 0.566802 +1.000000 0.589069 +0.000000 0.589069 +1.000000 0.611336 +0.000000 0.611336 +1.000000 0.633603 +0.000000 0.633603 +1.000000 0.655870 +0.000000 0.655870 +1.000000 0.678138 +0.000000 0.678138 +1.000000 0.700405 +0.000000 0.700405 +1.000000 0.722672 +0.000000 0.722672 +1.000000 0.744939 +0.000000 0.744939 +1.000000 0.767206 +0.000000 0.767206 +</float_array> + <technique_common> + <accessor source="#pPlane17-UV0-array" count="86" stride="2"> + <param name="S" type="float"/> + <param name="T" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="pPlane17-VERTEX"> + <input semantic="POSITION" source="#pPlane17-POSITION"/> + <input semantic="NORMAL" source="#pPlane17-Normal0"/> + </vertices> + <triangles count="84"><input semantic="VERTEX" offset="0" source="#pPlane17-VERTEX"/><input semantic="TEXCOORD" offset="1" set="0" source="#pPlane17-UV0"/><p> 0 0 1 1 34 34 0 0 34 34 35 35 2 2 3 3 32 32 2 2 32 32 33 33 4 4 5 5 30 30 4 4 30 30 31 31 6 6 7 7 28 28 6 6 28 28 29 29 10 10 11 11 26 26 10 10 26 26 27 27 12 12 13 13 24 24 12 12 24 24 25 25 14 14 15 15 22 22 14 14 22 22 23 23 16 16 17 17 20 20 16 16 20 20 21 21 21 21 20 20 19 19 21 21 19 19 18 18 23 23 22 22 17 17 23 23 17 17 16 16 25 25 24 24 15 15 25 25 15 15 14 14 27 27 26 26 13 13 27 27 13 13 12 12 29 29 28 28 9 9 29 29 9 9 8 8 31 31 30 30 7 7 31 31 7 7 6 6 33 33 32 32 5 5 33 33 5 5 4 4 35 35 34 34 3 3 35 35 3 3 2 2 8 8 9 9 36 36 8 8 36 36 37 37 36 36 39 39 37 37 39 39 36 36 38 38 40 40 39 39 38 38 39 39 40 40 41 41 41 41 40 40 42 42 41 41 42 42 43 43 44 44 43 43 42 42 43 43 44 44 45 45 44 44 47 47 45 45 47 47 44 44 46 46 48 48 47 47 46 46 47 47 48 48 49 49 49 49 48 48 50 50 49 49 50 50 51 51 51 51 50 50 52 52 51 51 52 52 53 53 52 52 55 55 53 53 55 55 52 52 54 54 55 55 54 54 56 56 55 55 56 56 57 57 58 58 57 57 56 56 57 57 58 58 59 59 58 58 61 61 59 59 61 61 58 58 60 60 60 60 63 63 61 61 63 63 60 60 62 62 64 64 63 63 62 62 63 63 64 64 65 65 65 65 64 64 66 66 65 65 66 66 67 67 66 66 69 69 67 67 69 69 66 66 68 68 69 69 68 68 70 70 69 69 70 70 71 71 71 71 70 70 72 72 71 71 72 72 73 73 74 74 73 73 72 72 73 73 74 74 75 75 74 74 77 77 75 75 77 77 74 74 76 76 77 77 76 76 78 78 77 77 78 78 79 79 79 79 78 78 80 80 79 79 80 80 81 81 82 82 81 81 80 80 81 81 82 82 83 83 82 82 85 85 83 83 85 85 82 82 84 84 85 85 84 84 11 11 85 85 11 11 10 10</p></triangles> + </mesh> + </geometry> + </library_geometries> + <library_controllers> + <controller id="pPlane16-lib-morph"> + <morph source="#pPlane16-lib" method="NORMALIZED"> + <source id="pPlane16-lib-morph-targets"> + <Name_array id="pPlane16-lib-morph-targets-array" count="2"> + pPlane13-lib pPlane17-lib</Name_array> + <technique_common> + <accessor source="#pPlane16-lib-morph-targets-array" count="2"> + <param type="name"/> + </accessor> + </technique_common> + </source> + <source id="pPlane16-lib-morph-weights"> + <float_array id="pPlane16-lib-morph-weights-array" count="2"> + +0.000000 0.000824</float_array> + <technique_common> + <accessor source="#pPlane16-lib-morph-weights-array" count="2"> + <param name="WEIGHT" type="float"/> + </accessor> + </technique_common> + </source> + <targets> + <input semantic="MORPH_TARGET" source="#pPlane16-lib-morph-targets"/> + <input semantic="MORPH_WEIGHT" source="#pPlane16-lib-morph-weights"/> + </targets> + </morph> + </controller> + </library_controllers> + <library_animations> + <animation id="pPlane16-anim" name="pPlane16"><animation><source id="pPlane16-Matrix-animation-input"><float_array id="pPlane16-Matrix-animation-input-array" count="241"> + +0.000000 0.041667 0.083333 0.125000 0.166667 0.208333 0.250000 0.291667 0.333333 0.375000 0.416667 0.458333 0.500000 0.541667 0.583333 0.625000 +0.666667 0.708333 0.750000 0.791667 0.833333 0.875000 0.916667 0.958333 1.000000 1.041667 1.083333 1.125000 1.166667 1.208333 1.250000 1.291667 +1.333333 1.375000 1.416667 1.458333 1.500000 1.541667 1.583333 1.625000 1.666667 1.708333 1.750000 1.791667 1.833333 1.875000 1.916667 1.958333 +2.000000 2.041667 2.083333 2.125000 2.166667 2.208333 2.250000 2.291667 2.333333 2.375000 2.416667 2.458333 2.500000 2.541667 2.583333 2.625000 +2.666667 2.708333 2.750000 2.791667 2.833333 2.875000 2.916667 2.958333 3.000000 3.041667 3.083333 3.125000 3.166667 3.208333 3.250000 3.291667 +3.333333 3.375000 3.416667 3.458333 3.500000 3.541667 3.583333 3.625000 3.666667 3.708333 3.750000 3.791667 3.833333 3.875000 3.916667 3.958333 +4.000000 4.041667 4.083333 4.125000 4.166667 4.208333 4.250000 4.291667 4.333333 4.375000 4.416667 4.458333 4.500000 4.541667 4.583333 4.625000 +4.666667 4.708333 4.750000 4.791667 4.833333 4.875000 4.916667 4.958333 5.000000 5.041667 5.083333 5.125000 5.166667 5.208333 5.250000 5.291667 +5.333333 5.375000 5.416667 5.458333 5.500000 5.541667 5.583333 5.625000 5.666667 5.708333 5.750000 5.791667 5.833333 5.875000 5.916667 5.958333 +6.000000 6.041667 6.083333 6.125000 6.166667 6.208333 6.250000 6.291667 6.333333 6.375000 6.416667 6.458333 6.500000 6.541667 6.583333 6.625000 +6.666667 6.708333 6.750000 6.791667 6.833333 6.875000 6.916667 6.958333 7.000000 7.041667 7.083333 7.125000 7.166667 7.208333 7.250000 7.291667 +7.333333 7.375000 7.416667 7.458333 7.500000 7.541667 7.583333 7.625000 7.666667 7.708333 7.750000 7.791667 7.833333 7.875000 7.916667 7.958333 +8.000000 8.041667 8.083333 8.125000 8.166667 8.208333 8.250000 8.291667 8.333333 8.375000 8.416667 8.458333 8.500000 8.541667 8.583333 8.625000 +8.666667 8.708333 8.750000 8.791667 8.833333 8.875000 8.916667 8.958333 9.000000 9.041667 9.083333 9.125000 9.166667 9.208333 9.250000 9.291667 +9.333333 9.375000 9.416667 9.458333 9.500000 9.541667 9.583333 9.625000 9.666667 9.708333 9.750000 9.791667 9.833333 9.875000 9.916667 9.958333 +10.000000</float_array><technique_common><accessor source="#pPlane16-Matrix-animation-input-array" count="241"><param name="TIME" type="float"/></accessor></technique_common></source><source id="pPlane16-Matrix-animation-output-transform"><float_array id="pPlane16-Matrix-animation-output-transform-array" count="3856"> + +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.288479 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 1.140794 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 2.537553 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 4.459312 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 6.886627 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 9.800054 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 13.180146 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 17.007462 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 21.262554 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 25.925980 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 30.978294 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 36.400055 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 42.171814 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 48.274124 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 54.687553 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 61.392647 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 68.369957 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 75.600052 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 83.063484 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 90.740799 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 98.612556 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 106.659309 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 114.861633 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 123.200050 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 131.655136 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 140.207443 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 148.837540 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 157.525970 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 166.253296 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 175.000046 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 183.746811 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 192.474121 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 201.162552 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 209.792633 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 218.344955 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 226.800049 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 235.138458 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 243.340790 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 251.387543 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 259.259338 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 266.936646 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 274.400055 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 281.630157 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 288.607483 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 295.312561 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 301.726013 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 307.828278 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 313.600067 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 319.021820 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 324.074127 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 328.737549 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 332.992645 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 336.819977 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 340.200073 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 343.113495 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 345.540802 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 347.462555 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 348.859314 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 349.711639 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 350.000061 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 349.711639 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 348.859314 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 347.462555 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 345.540802 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 343.113495 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 340.200073 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 336.819977 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 332.992645 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 328.737549 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 324.074127 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 319.021820 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 313.600067 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 307.828278 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 301.726013 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 295.312561 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 288.607483 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 281.630157 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 274.400055 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 266.936646 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 259.259338 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 251.387543 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 243.340790 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 235.138458 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 226.800049 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 218.344955 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 209.792633 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 201.162552 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 192.474121 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 183.746796 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 175.000046 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 166.253296 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 157.525970 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 148.837540 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 140.207458 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 131.655136 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 123.200050 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 114.861633 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 106.659317 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 98.612556 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 90.740791 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 83.063492 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 75.600052 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 68.369949 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 61.392647 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 54.687553 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 48.274128 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 42.171814 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 36.400055 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 30.978291 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 25.925980 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 21.262554 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 17.007458 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 13.180144 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 9.800054 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 6.886628 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 4.459314 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 2.537553 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 1.140794 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.288479 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000 +593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000</float_array><technique_common><accessor source="#pPlane16-Matrix-animation-output-transform-array" count="241" stride="16"><param type="float4x4"/></accessor></technique_common></source><source id="pPlane16-Interpolations"><Name_array id="pPlane16-Interpolations-array" count="241"> + LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR LINEAR +LINEAR LINEAR</Name_array><technique_common><accessor source="#pPlane16-Interpolations-array" count="241"><param type="name"/></accessor></technique_common></source><sampler id="pPlane16-Matrix-animation-transform"><input semantic="INPUT" source="#pPlane16-Matrix-animation-input"/><input semantic="OUTPUT" source="#pPlane16-Matrix-animation-output-transform"/><input semantic="INTERPOLATION" source="#pPlane16-Interpolations"/></sampler><channel source="#pPlane16-Matrix-animation-transform" target="pPlane16/matrix"/></animation><animation><source id="pPlane16-visibility-animation-input"><float_array id="pPlane16-visibility-animation-input-array" count="5"> + +0.000000 2.500000 5.000000 7.500000 10.000000</float_array><technique_common><accessor source="#pPlane16-visibility-animation-input-array" count="5"><param name="TIME" type="float"/></accessor></technique_common></source><source id="pPlane16-visibility-animation-output"><float_array id="pPlane16-visibility-animation-output-array" count="5"> + +1.000000 1.000000 1.000000 1.000000 1.000000</float_array><technique_common><accessor source="#pPlane16-visibility-animation-output-array" count="5"><param type="float"/></accessor></technique_common></source><source id="pPlane16-visibility-animation-intan"><float_array id="pPlane16-visibility-animation-intan-array" count="5"> + +0.000000 0.000000 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pPlane16-visibility-animation-intan-array" count="5"><param type="float"/></accessor></technique_common></source><source id="pPlane16-visibility-animation-outtan"><float_array id="pPlane16-visibility-animation-outtan-array" count="5"> + +0.000000 0.000000 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pPlane16-visibility-animation-outtan-array" count="5"><param type="float"/></accessor></technique_common></source><source id="pPlane16-visibility-animation-interpolation"><Name_array id="pPlane16-visibility-animation-interpolation-array" count="5"> + STEP STEP STEP STEP BEZIER</Name_array><technique_common><accessor source="#pPlane16-visibility-animation-interpolation-array" count="5"><param type="name"/></accessor></technique_common></source><sampler id="pPlane16-visibility-animation"><input semantic="INPUT" source="#pPlane16-visibility-animation-input"/><input semantic="OUTPUT" source="#pPlane16-visibility-animation-output"/><input semantic="IN_TANGENT" source="#pPlane16-visibility-animation-intan"/><input semantic="OUT_TANGENT" source="#pPlane16-visibility-animation-outtan"/><input semantic="INTERPOLATION" source="#pPlane16-visibility-animation-interpolation"/></sampler><channel source="#pPlane16-visibility-animation" target="pPlane16/visibility"/></animation><animation><source id="pPlane16-lib-morph-weights-animation-inputWeight_0_0"><float_array id="pPlane16-lib-morph-weights-animation-inputWeight_0_0-array" count="5"> + +0.000000 2.500000 5.000000 7.500000 10.000000</float_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-inputWeight_0_0-array" count="5"><param name="TIME" type="float"/></accessor></technique_common></source><source id="pPlane16-lib-morph-weights-animation-outputWeight_0_0"><float_array id="pPlane16-lib-morph-weights-animation-outputWeight_0_0-array" count="5"> + +0.000000 1.000000 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-outputWeight_0_0-array" count="5"><param name="Weight_0_0" type="float"/></accessor></technique_common></source><source id="pPlane16-lib-morph-weights-animation-intanWeight_0_0"><float_array id="pPlane16-lib-morph-weights-animation-intanWeight_0_0-array" count="5"> + +0.000000 0.000000 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-intanWeight_0_0-array" count="5"><param name="Weight_0_0" type="float"/></accessor></technique_common></source><source id="pPlane16-lib-morph-weights-animation-outtanWeight_0_0"><float_array id="pPlane16-lib-morph-weights-animation-outtanWeight_0_0-array" count="5"> + +0.000000 0.000000 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-outtanWeight_0_0-array" count="5"><param name="Weight_0_0" type="float"/></accessor></technique_common></source><source id="pPlane16-lib-morph-weights-animation-interpolationWeight_0_0"><Name_array id="pPlane16-lib-morph-weights-animation-interpolationWeight_0_0-array" count="5"> + BEZIER BEZIER BEZIER BEZIER BEZIER</Name_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-interpolationWeight_0_0-array" count="5"><param type="name"/></accessor></technique_common></source><sampler id="pPlane16-lib-morph-weights-animationWeight_0_0"><input semantic="INPUT" source="#pPlane16-lib-morph-weights-animation-inputWeight_0_0"/><input semantic="OUTPUT" source="#pPlane16-lib-morph-weights-animation-outputWeight_0_0"/><input semantic="IN_TANGENT" source="#pPlane16-lib-morph-weights-animation-intanWeight_0_0"/><input semantic="OUT_TANGENT" source="#pPlane16-lib-morph-weights-animation-outtanWeight_0_0"/><input semantic="INTERPOLATION" source="#pPlane16-lib-morph-weights-animation-interpolationWeight_0_0"/></sampler><channel source="#pPlane16-lib-morph-weights-animationWeight_0_0" target="pPlane16-lib-morph-weights(Weight_0_0)"/></animation><animation><source id="pPlane16-lib-morph-weights-animation-inputWeight_0_1"><float_array id="pPlane16-lib-morph-weights-animation-inputWeight_0_1-array" count="4"> + +2.500000 5.000000 7.500000 10.000000</float_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-inputWeight_0_1-array" count="4"><param name="TIME" type="float"/></accessor></technique_common></source><source id="pPlane16-lib-morph-weights-animation-outputWeight_0_1"><float_array id="pPlane16-lib-morph-weights-animation-outputWeight_0_1-array" count="4"> + +0.000000 0.000000 1.000000 0.000000</float_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-outputWeight_0_1-array" count="4"><param name="Weight_0_1" type="float"/></accessor></technique_common></source><source id="pPlane16-lib-morph-weights-animation-intanWeight_0_1"><float_array id="pPlane16-lib-morph-weights-animation-intanWeight_0_1-array" count="4"> + +0.000000 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-intanWeight_0_1-array" count="4"><param name="Weight_0_1" type="float"/></accessor></technique_common></source><source id="pPlane16-lib-morph-weights-animation-outtanWeight_0_1"><float_array id="pPlane16-lib-morph-weights-animation-outtanWeight_0_1-array" count="4"> + +0.000000 0.000000 0.000000 0.000000</float_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-outtanWeight_0_1-array" count="4"><param name="Weight_0_1" type="float"/></accessor></technique_common></source><source id="pPlane16-lib-morph-weights-animation-interpolationWeight_0_1"><Name_array id="pPlane16-lib-morph-weights-animation-interpolationWeight_0_1-array" count="4"> + BEZIER BEZIER BEZIER BEZIER</Name_array><technique_common><accessor source="#pPlane16-lib-morph-weights-animation-interpolationWeight_0_1-array" count="4"><param type="name"/></accessor></technique_common></source><sampler id="pPlane16-lib-morph-weights-animationWeight_0_1"><input semantic="INPUT" source="#pPlane16-lib-morph-weights-animation-inputWeight_0_1"/><input semantic="OUTPUT" source="#pPlane16-lib-morph-weights-animation-outputWeight_0_1"/><input semantic="IN_TANGENT" source="#pPlane16-lib-morph-weights-animation-intanWeight_0_1"/><input semantic="OUT_TANGENT" source="#pPlane16-lib-morph-weights-animation-outtanWeight_0_1"/><input semantic="INTERPOLATION" source="#pPlane16-lib-morph-weights-animation-interpolationWeight_0_1"/></sampler><channel source="#pPlane16-lib-morph-weights-animationWeight_0_1" target="pPlane16-lib-morph-weights(Weight_0_1)"/></animation></animation> + </library_animations> + <library_visual_scenes> + <visual_scene id="blendshapeanimation" name="blendshapeanimation"> + <node name="pPlane16" id="pPlane16" sid="pPlane16"><matrix sid="matrix">593.587463 0.000000 0.000000 0.000053 0.000000 593.587463 0.000000 0.000000 0.000000 0.000000 597.200012 1684.046143 0.000000 0.000000 0.000000 1.000000</matrix><instance_controller url="#pPlane16-lib-morph"><bind_material><technique_common><instance_material symbol="lambert2" target="#lambert2"/></technique_common></bind_material></instance_controller><extra><technique profile="FCOLLADA"><visibility>1.000000</visibility></technique></extra></node> + <extra><technique profile="MAX3D"><frame_rate>24.000000</frame_rate></technique><technique profile="FCOLLADA"><start_time>0.041667</start_time><end_time>8.333333</end_time></technique></extra> + </visual_scene> + </library_visual_scenes> + <scene> + <instance_visual_scene url="#blendshapeanimation"></instance_visual_scene> + </scene> +</COLLADA> diff --git a/tests/manual/anim-viewer/assets/gears.dae b/tests/manual/anim-viewer/assets/gears.dae new file mode 100644 index 000000000..4d34983b7 --- /dev/null +++ b/tests/manual/anim-viewer/assets/gears.dae @@ -0,0 +1,873 @@ +<?xml version="1.0" encoding="utf-8"?> +<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1"> + <asset> + <contributor> + <author>Blender User</author> + <authoring_tool>Blender 2.77.0 commit date:2016-04-05, commit time:18:12, hash:abf6f08</authoring_tool> + </contributor> + <created>2016-09-21T14:50:51</created> + <modified>2016-09-21T14:50:51</modified> + <unit name="meter" meter="1"/> + <up_axis>Z_UP</up_axis> + </asset> + <library_images/> + <library_effects> + <effect id="Material_001-effect"> + <profile_COMMON> + <technique sid="common"> + <phong> + <emission> + <color sid="emission">0 0 0 1</color> + </emission> + <ambient> + <color sid="ambient">0.02197916 0.02197916 0.02197916 1</color> + </ambient> + <diffuse> + <color sid="diffuse">0.64 0.64 0.64 1</color> + </diffuse> + <specular> + <color sid="specular">0.5 0.5 0.5 1</color> + </specular> + <shininess> + <float sid="shininess">50</float> + </shininess> + <index_of_refraction> + <float sid="index_of_refraction">1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="Material_002-effect"> + <profile_COMMON> + <technique sid="common"> + <phong> + <emission> + <color sid="emission">0 0 0 1</color> + </emission> + <ambient> + <color sid="ambient">0.02197916 0.02197916 0.02197916 1</color> + </ambient> + <diffuse> + <color sid="diffuse">0.64 0.64 0.64 1</color> + </diffuse> + <specular> + <color sid="specular">0.5 0.5 0.5 1</color> + </specular> + <shininess> + <float sid="shininess">50</float> + </shininess> + <index_of_refraction> + <float sid="index_of_refraction">1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="Material-effect"> + <profile_COMMON> + <technique sid="common"> + <phong> + <emission> + <color sid="emission">0 0 0 1</color> + </emission> + <ambient> + <color sid="ambient">0.02197916 0.02197916 0.02197916 1</color> + </ambient> + <diffuse> + <color sid="diffuse">0.64 0.64 0.64 1</color> + </diffuse> + <specular> + <color sid="specular">0.5 0.5 0.5 1</color> + </specular> + <shininess> + <float sid="shininess">50</float> + </shininess> + <index_of_refraction> + <float sid="index_of_refraction">1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + </library_effects> + <library_materials> + <material id="Material_001-material" name="Material_001"> + <instance_effect url="#Material_001-effect"/> + </material> + <material id="Material_002-material" name="Material_002"> + <instance_effect url="#Material_002-effect"/> + </material> + <material id="Material-material" name="Material"> + <instance_effect url="#Material-effect"/> + </material> + </library_materials> + <library_geometries> + <geometry id="Cylinder_005-mesh" name="Cylinder.005"> + <mesh> + <source id="Cylinder_005-mesh-positions"> + <float_array id="Cylinder_005-mesh-positions-array" count="216">-0.6937502 0.7202157 -0.1465266 -0.117956 0.122456 0.1465266 -0.2406975 0.9706001 -0.1465266 -0.04092502 0.165028 0.1465266 0.2768501 0.9609132 -0.1465266 0.04707187 0.1633808 0.1465266 0.7202157 0.6937502 -0.1465266 0.122456 0.1179561 0.1465266 0.9706003 0.2406975 -0.1465266 0.165028 0.04092496 0.1465266 0.9609132 -0.2768499 -0.1465266 0.163381 -0.04707187 0.1465266 0.6937503 -0.7202156 -0.1465266 0.1179561 -0.1224558 0.1465266 0.2406976 -0.9706001 -0.1465266 0.04092496 -0.1650279 0.1465266 -0.2768496 -0.9609132 -0.1465266 -0.04707181 -0.163381 0.1465266 -0.7202154 -0.6937506 -0.1465266 -0.1224559 -0.1179561 0.1465266 -0.9706 -0.240698 -0.1465266 -0.165028 -0.04092508 0.1465266 -0.9609134 0.2768493 -0.1465266 -0.1633809 0.04707157 0.1465266 -1.161437 1.002034 -0.1465266 -1.161437 1.002034 0.1465266 -0.2304791 1.516537 0.1465266 -0.2304791 1.516537 -0.1465266 0.2870684 1.50685 -0.1465266 0.2870684 1.50685 0.1465266 1.19812 0.9578695 0.1465266 1.19812 0.9578695 -0.1465266 1.448505 0.5048167 -0.1465266 1.448505 0.5048167 0.1465266 1.4286 -0.5586678 0.1465266 1.4286 -0.5586678 -0.1465266 1.161437 -1.002034 -0.1465266 1.161437 -1.002034 0.1465266 0.2304794 -1.516537 0.1465266 0.2304794 -1.516537 -0.1465266 -0.2870679 -1.50685 -0.1465266 -0.2870679 -1.50685 0.1465266 -1.19812 -0.95787 0.1465266 -1.19812 -0.95787 -0.1465266 -1.448505 -0.5048175 -0.1465266 -1.448505 -0.5048175 0.1465266 -1.4286 0.5586673 0.1465266 -1.4286 0.5586673 -0.1465266 -0.2406975 0.9706001 0.1465266 -0.6937502 0.7202157 0.1465266 0.2768501 0.9609132 0.1465266 0.7202157 0.6937502 0.1465266 0.9706003 0.2406975 0.1465266 0.9609132 -0.2768499 0.1465266 0.6937503 -0.7202156 0.1465266 0.2406976 -0.9706001 0.1465266 -0.2768496 -0.9609132 0.1465266 -0.7202154 -0.6937506 0.1465266 -0.9706 -0.240698 0.1465266 -0.9609134 0.2768493 0.1465266 -0.04092502 0.165028 2.134743 -0.117956 0.122456 2.134743 0.04707187 0.1633808 2.134743 0.122456 0.1179561 2.134743 0.165028 0.04092496 2.134743 0.163381 -0.04707187 2.134743 0.1179561 -0.1224558 2.134743 0.04092496 -0.1650279 2.134743 -0.04707181 -0.163381 2.134743 -0.1224559 -0.1179561 2.134743 -0.165028 -0.04092508 2.134743 -0.1633809 0.04707157 2.134743</float_array> + <technique_common> + <accessor source="#Cylinder_005-mesh-positions-array" count="72" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cylinder_005-mesh-normals"> + <float_array id="Cylinder_005-mesh-normals-array" count="180">0.01019328 0.5446093 0.838628 -0.4665465 0.281112 -0.8386361 0.01019328 0.5446093 -0.838628 -0.1965123 0.7924888 0.5773599 0.4767377 0.2634708 0.8386324 0.4767377 0.2634708 -0.8386324 -0.4767377 -0.2634708 -0.8386324 -0.5880461 -0.5664384 0.5773643 -0.4767377 -0.2634708 0.8386324 0.4665465 -0.281112 0.8386361 0.4665465 -0.281112 -0.8386361 0.2260238 0.7845829 -0.5773588 -0.01019328 -0.5446093 0.838628 -0.01019328 -0.5446093 -0.838628 0.7924888 0.1965123 -0.5773599 0.1965123 -0.7924888 -0.5773599 0.5664384 -0.5880461 0.5773643 -0.6127917 0.1765526 0.7702699 -0.525269 0.5453203 0.6532368 -0.4424093 0.4592865 0.7702792 -0.4665465 0.281112 0.8386361 -0.7845829 0.2260238 0.5773588 -0.5664384 0.5880461 0.5773643 0.5880461 0.5664384 -0.5773643 -0.5664384 0.5880461 -0.5773643 0.2260238 0.7845829 0.5773588 0.7845829 -0.2260238 -0.5773588 0.7924888 0.1965123 0.5773599 -0.5880461 -0.5664384 -0.5773643 0.5664384 -0.5880461 -0.5773643 -0.2260238 -0.7845829 0.5773588 -0.7845829 0.2260238 -0.5773588 -0.2260238 -0.7845829 -0.5773588 -0.7924888 -0.1965123 0.5773599 -0.1965123 0.7924888 -0.5773599 -0.7924888 -0.1965123 -0.5773599 0.1965123 -0.7924888 0.5773599 0.7845829 -0.2260238 0.5773588 0.5880461 0.5664384 0.5773643 0.1765526 0.6127917 0.7702699 -0.1534789 0.6189819 0.7702634 0.4592865 0.4424093 0.7702792 0.6189819 0.1534789 0.7702634 0.6127917 -0.1765526 0.7702699 0.1534789 -0.6189819 0.7702634 0.4424093 -0.4592865 0.7702792 -0.1765526 -0.6127917 0.7702699 -0.4592865 -0.4424093 0.7702792 -0.6189819 -0.1534789 0.7702634 -0.7349014 -0.1822299 0.6532321 0.525269 -0.5453203 0.6532368 0.209604 0.7275715 0.6532273 -0.5453203 -0.525269 0.6532368 0.5453203 0.525269 0.6532368 0.1822299 -0.7349014 0.6532321 0.7349014 0.1822299 0.6532321 -0.7275715 0.209604 0.6532273 -0.1822299 0.7349014 0.6532321 -0.209604 -0.7275715 0.6532273 0.7275715 -0.209604 0.6532273</float_array> + <technique_common> + <accessor source="#Cylinder_005-mesh-normals-array" count="60" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="Cylinder_005-mesh-vertices"> + <input semantic="POSITION" source="#Cylinder_005-mesh-positions"/> + </vertices> + <polylist material="Material_001-material" count="140"> + <input semantic="VERTEX" source="#Cylinder_005-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#Cylinder_005-mesh-normals" offset="1"/> + <vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount> + <p>49 0 2 1 0 2 0 2 25 3 49 0 50 4 6 2 4 5 16 6 41 7 56 8 52 9 10 5 8 10 51 0 31 11 6 2 54 12 14 10 12 13 12 13 35 14 36 15 56 8 18 13 16 6 55 9 41 7 38 16 23 17 61 18 1 19 58 20 22 6 20 1 20 1 45 21 58 20 6 2 14 10 22 6 26 22 28 23 27 24 30 25 32 26 31 11 34 27 36 15 35 14 38 16 40 28 39 29 42 30 44 31 43 32 46 33 24 34 47 35 54 12 34 27 53 4 8 10 31 11 32 26 48 20 27 24 2 1 12 13 37 36 54 12 59 8 47 35 22 6 52 9 30 25 51 0 4 5 27 24 28 23 22 6 24 34 0 2 8 10 33 37 52 9 57 12 43 32 18 13 50 4 26 22 48 20 49 0 46 33 59 8 20 1 43 32 44 31 4 5 29 38 50 4 55 9 39 29 14 10 58 20 42 30 57 12 14 10 40 28 16 6 53 4 35 14 10 5 1 19 48 20 49 0 5 39 48 20 3 40 7 41 50 4 5 39 9 42 51 0 7 41 11 43 52 9 9 42 11 43 54 12 53 4 15 44 54 12 13 45 17 46 55 9 15 44 19 47 56 8 17 46 19 47 58 20 57 12 21 48 59 8 58 20 1 19 59 8 23 17 70 49 66 50 62 51 3 40 62 51 5 39 17 46 69 52 19 47 11 43 66 50 13 45 5 39 63 53 7 41 19 47 70 49 21 48 13 45 67 54 15 44 7 41 64 55 9 42 21 48 71 56 23 17 1 19 60 57 3 40 15 44 68 58 17 46 9 42 65 59 11 43 49 0 48 20 2 1 0 2 24 34 25 3 50 4 51 0 6 2 16 6 40 28 41 7 52 9 53 4 10 5 51 0 30 25 31 11 54 12 55 9 14 10 12 13 10 5 35 14 56 8 57 12 18 13 55 9 56 8 41 7 23 17 71 56 61 18 58 20 59 8 22 6 20 1 44 31 45 21 22 6 0 2 6 2 2 1 4 5 6 2 6 2 8 10 10 5 10 5 12 13 14 10 14 10 16 6 18 13 18 13 20 1 14 10 0 2 2 1 6 2 6 2 10 5 14 10 14 10 20 1 22 6 26 22 29 38 28 23 30 25 33 37 32 26 34 27 37 36 36 15 38 16 41 7 40 28 42 30 45 21 44 31 46 33 25 3 24 34 54 12 37 36 34 27 8 10 6 2 31 11 48 20 26 22 27 24 12 13 36 15 37 36 59 8 46 33 47 35 52 9 33 37 30 25 4 5 2 1 27 24 22 6 47 35 24 34 8 10 32 26 33 37 57 12 42 30 43 32 50 4 29 38 26 22 49 0 25 3 46 33 20 1 18 13 43 32 4 5 28 23 29 38 55 9 38 16 39 29 58 20 45 21 42 30 14 10 39 29 40 28 53 4 34 27 35 14 1 19 3 40 48 20 5 39 50 4 48 20 7 41 51 0 50 4 9 42 52 9 51 0 11 43 53 4 52 9 11 43 13 45 54 12 15 44 55 9 54 12 17 46 56 8 55 9 19 47 57 12 56 8 19 47 21 48 58 20 21 48 23 17 59 8 1 19 49 0 59 8 62 51 60 57 61 18 61 18 71 56 62 51 70 49 69 52 68 58 68 58 67 54 70 49 66 50 65 59 64 55 64 55 63 53 62 51 62 51 71 56 70 49 70 49 67 54 66 50 66 50 64 55 62 51 3 40 60 57 62 51 17 46 68 58 69 52 11 43 65 59 66 50 5 39 62 51 63 53 19 47 69 52 70 49 13 45 66 50 67 54 7 41 63 53 64 55 21 48 70 49 71 56 1 19 61 18 60 57 15 44 67 54 68 58 9 42 64 55 65 59</p> + </polylist> + </mesh> + </geometry> + <geometry id="Cylinder_001-mesh" name="Cylinder.001"> + <mesh> + <source id="Cylinder_001-mesh-positions"> + <float_array id="Cylinder_001-mesh-positions-array" count="216">-0.6937502 0.7202157 -0.1465266 -0.117956 0.122456 0.1465266 -0.2406975 0.9706001 -0.1465266 -0.04092502 0.165028 0.1465266 0.2768501 0.9609132 -0.1465266 0.04707187 0.1633808 0.1465266 0.7202157 0.6937502 -0.1465266 0.122456 0.1179561 0.1465266 0.9706003 0.2406975 -0.1465266 0.165028 0.04092496 0.1465266 0.9609132 -0.2768499 -0.1465266 0.163381 -0.04707187 0.1465266 0.6937503 -0.7202156 -0.1465266 0.1179561 -0.1224558 0.1465266 0.2406976 -0.9706001 -0.1465266 0.04092496 -0.1650279 0.1465266 -0.2768496 -0.9609132 -0.1465266 -0.04707181 -0.163381 0.1465266 -0.7202154 -0.6937506 -0.1465266 -0.1224559 -0.1179561 0.1465266 -0.9706 -0.240698 -0.1465266 -0.165028 -0.04092508 0.1465266 -0.9609134 0.2768493 -0.1465266 -0.1633809 0.04707157 0.1465266 -1.161437 1.002034 -0.1465266 -1.161437 1.002034 0.1465266 -0.2304791 1.516537 0.1465266 -0.2304791 1.516537 -0.1465266 0.2870684 1.50685 -0.1465266 0.2870684 1.50685 0.1465266 1.19812 0.9578695 0.1465266 1.19812 0.9578695 -0.1465266 1.448505 0.5048167 -0.1465266 1.448505 0.5048167 0.1465266 1.4286 -0.5586678 0.1465266 1.4286 -0.5586678 -0.1465266 1.161437 -1.002034 -0.1465266 1.161437 -1.002034 0.1465266 0.2304794 -1.516537 0.1465266 0.2304794 -1.516537 -0.1465266 -0.2870679 -1.50685 -0.1465266 -0.2870679 -1.50685 0.1465266 -1.19812 -0.95787 0.1465266 -1.19812 -0.95787 -0.1465266 -1.448505 -0.5048175 -0.1465266 -1.448505 -0.5048175 0.1465266 -1.4286 0.5586673 0.1465266 -1.4286 0.5586673 -0.1465266 -0.2406975 0.9706001 0.1465266 -0.6937502 0.7202157 0.1465266 0.2768501 0.9609132 0.1465266 0.7202157 0.6937502 0.1465266 0.9706003 0.2406975 0.1465266 0.9609132 -0.2768499 0.1465266 0.6937503 -0.7202156 0.1465266 0.2406976 -0.9706001 0.1465266 -0.2768496 -0.9609132 0.1465266 -0.7202154 -0.6937506 0.1465266 -0.9706 -0.240698 0.1465266 -0.9609134 0.2768493 0.1465266 -0.04092502 0.165028 2.134743 -0.117956 0.122456 2.134743 0.04707187 0.1633808 2.134743 0.122456 0.1179561 2.134743 0.165028 0.04092496 2.134743 0.163381 -0.04707187 2.134743 0.1179561 -0.1224558 2.134743 0.04092496 -0.1650279 2.134743 -0.04707181 -0.163381 2.134743 -0.1224559 -0.1179561 2.134743 -0.165028 -0.04092508 2.134743 -0.1633809 0.04707157 2.134743</float_array> + <technique_common> + <accessor source="#Cylinder_001-mesh-positions-array" count="72" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cylinder_001-mesh-normals"> + <float_array id="Cylinder_001-mesh-normals-array" count="180">0.01019328 0.5446093 0.838628 -0.4665465 0.281112 -0.8386361 0.01019328 0.5446093 -0.838628 -0.1965123 0.7924888 0.5773599 0.4767377 0.2634708 0.8386324 0.4767377 0.2634708 -0.8386324 -0.4767377 -0.2634708 -0.8386324 -0.5880461 -0.5664384 0.5773643 -0.4767377 -0.2634708 0.8386324 0.4665465 -0.281112 0.8386361 0.4665465 -0.281112 -0.8386361 0.2260238 0.7845829 -0.5773588 -0.01019328 -0.5446093 0.838628 -0.01019328 -0.5446093 -0.838628 0.7924888 0.1965123 -0.5773599 0.1965123 -0.7924888 -0.5773599 0.5664384 -0.5880461 0.5773643 -0.6127917 0.1765526 0.7702699 -0.525269 0.5453203 0.6532368 -0.4424093 0.4592865 0.7702792 -0.4665465 0.281112 0.8386361 -0.7845829 0.2260238 0.5773588 -0.5664384 0.5880461 0.5773643 0.5880461 0.5664384 -0.5773643 -0.5664384 0.5880461 -0.5773643 0.2260238 0.7845829 0.5773588 0.7845829 -0.2260238 -0.5773588 0.7924888 0.1965123 0.5773599 -0.5880461 -0.5664384 -0.5773643 0.5664384 -0.5880461 -0.5773643 -0.2260238 -0.7845829 0.5773588 -0.7845829 0.2260238 -0.5773588 -0.2260238 -0.7845829 -0.5773588 -0.7924888 -0.1965123 0.5773599 -0.1965123 0.7924888 -0.5773599 -0.7924888 -0.1965123 -0.5773599 0.1965123 -0.7924888 0.5773599 0.7845829 -0.2260238 0.5773588 0.5880461 0.5664384 0.5773643 0.1765526 0.6127917 0.7702699 -0.1534789 0.6189819 0.7702634 0.4592865 0.4424093 0.7702792 0.6189819 0.1534789 0.7702634 0.6127917 -0.1765526 0.7702699 0.1534789 -0.6189819 0.7702634 0.4424093 -0.4592865 0.7702792 -0.1765526 -0.6127917 0.7702699 -0.4592865 -0.4424093 0.7702792 -0.6189819 -0.1534789 0.7702634 -0.7349014 -0.1822299 0.6532321 0.525269 -0.5453203 0.6532368 0.209604 0.7275715 0.6532273 -0.5453203 -0.525269 0.6532368 0.5453203 0.525269 0.6532368 0.1822299 -0.7349014 0.6532321 0.7349014 0.1822299 0.6532321 -0.7275715 0.209604 0.6532273 -0.1822299 0.7349014 0.6532321 -0.209604 -0.7275715 0.6532273 0.7275715 -0.209604 0.6532273</float_array> + <technique_common> + <accessor source="#Cylinder_001-mesh-normals-array" count="60" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="Cylinder_001-mesh-vertices"> + <input semantic="POSITION" source="#Cylinder_001-mesh-positions"/> + </vertices> + <polylist material="Material_001-material" count="140"> + <input semantic="VERTEX" source="#Cylinder_001-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#Cylinder_001-mesh-normals" offset="1"/> + <vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount> + <p>49 0 2 1 0 2 0 2 25 3 49 0 50 4 6 2 4 5 16 6 41 7 56 8 52 9 10 5 8 10 51 0 31 11 6 2 54 12 14 10 12 13 12 13 35 14 36 15 56 8 18 13 16 6 55 9 41 7 38 16 23 17 61 18 1 19 58 20 22 6 20 1 20 1 45 21 58 20 6 2 14 10 22 6 26 22 28 23 27 24 30 25 32 26 31 11 34 27 36 15 35 14 38 16 40 28 39 29 42 30 44 31 43 32 46 33 24 34 47 35 54 12 34 27 53 4 8 10 31 11 32 26 48 20 27 24 2 1 12 13 37 36 54 12 59 8 47 35 22 6 52 9 30 25 51 0 4 5 27 24 28 23 22 6 24 34 0 2 8 10 33 37 52 9 57 12 43 32 18 13 50 4 26 22 48 20 49 0 46 33 59 8 20 1 43 32 44 31 4 5 29 38 50 4 55 9 39 29 14 10 58 20 42 30 57 12 14 10 40 28 16 6 53 4 35 14 10 5 1 19 48 20 49 0 5 39 48 20 3 40 7 41 50 4 5 39 9 42 51 0 7 41 11 43 52 9 9 42 11 43 54 12 53 4 15 44 54 12 13 45 17 46 55 9 15 44 19 47 56 8 17 46 19 47 58 20 57 12 21 48 59 8 58 20 1 19 59 8 23 17 70 49 66 50 62 51 3 40 62 51 5 39 17 46 69 52 19 47 11 43 66 50 13 45 5 39 63 53 7 41 19 47 70 49 21 48 13 45 67 54 15 44 7 41 64 55 9 42 21 48 71 56 23 17 1 19 60 57 3 40 15 44 68 58 17 46 9 42 65 59 11 43 49 0 48 20 2 1 0 2 24 34 25 3 50 4 51 0 6 2 16 6 40 28 41 7 52 9 53 4 10 5 51 0 30 25 31 11 54 12 55 9 14 10 12 13 10 5 35 14 56 8 57 12 18 13 55 9 56 8 41 7 23 17 71 56 61 18 58 20 59 8 22 6 20 1 44 31 45 21 22 6 0 2 6 2 2 1 4 5 6 2 6 2 8 10 10 5 10 5 12 13 14 10 14 10 16 6 18 13 18 13 20 1 14 10 0 2 2 1 6 2 6 2 10 5 14 10 14 10 20 1 22 6 26 22 29 38 28 23 30 25 33 37 32 26 34 27 37 36 36 15 38 16 41 7 40 28 42 30 45 21 44 31 46 33 25 3 24 34 54 12 37 36 34 27 8 10 6 2 31 11 48 20 26 22 27 24 12 13 36 15 37 36 59 8 46 33 47 35 52 9 33 37 30 25 4 5 2 1 27 24 22 6 47 35 24 34 8 10 32 26 33 37 57 12 42 30 43 32 50 4 29 38 26 22 49 0 25 3 46 33 20 1 18 13 43 32 4 5 28 23 29 38 55 9 38 16 39 29 58 20 45 21 42 30 14 10 39 29 40 28 53 4 34 27 35 14 1 19 3 40 48 20 5 39 50 4 48 20 7 41 51 0 50 4 9 42 52 9 51 0 11 43 53 4 52 9 11 43 13 45 54 12 15 44 55 9 54 12 17 46 56 8 55 9 19 47 57 12 56 8 19 47 21 48 58 20 21 48 23 17 59 8 1 19 49 0 59 8 62 51 60 57 61 18 61 18 71 56 62 51 70 49 69 52 68 58 68 58 67 54 70 49 66 50 65 59 64 55 64 55 63 53 62 51 62 51 71 56 70 49 70 49 67 54 66 50 66 50 64 55 62 51 3 40 60 57 62 51 17 46 68 58 69 52 11 43 65 59 66 50 5 39 62 51 63 53 19 47 69 52 70 49 13 45 66 50 67 54 7 41 63 53 64 55 21 48 70 49 71 56 1 19 61 18 60 57 15 44 67 54 68 58 9 42 64 55 65 59</p> + </polylist> + </mesh> + </geometry> + <geometry id="Cylinder_003-mesh" name="Cylinder.003"> + <mesh> + <source id="Cylinder_003-mesh-positions"> + <float_array id="Cylinder_003-mesh-positions-array" count="216">0.1465264 -0.9675643 0.252625 -0.1465267 -0.1645117 0.04295283 0.1465264 -0.9642478 -0.2650024 -0.1465267 -0.1639478 -0.04505747 0.1465265 -0.7025618 -0.7116228 -0.1465267 -0.1194542 -0.1209948 0.1465266 -0.2526249 -0.9675642 -0.1465267 -0.04295289 -0.1645118 0.1465267 0.2650024 -0.9642477 -0.1465266 0.04505759 -0.1639479 0.1465268 0.7116226 -0.7025619 -0.1465266 0.1209949 -0.1194544 0.1465269 0.9675641 -0.2526252 -0.1465266 0.1645117 -0.04295301 0.1465269 0.9642477 0.2650023 -0.1465266 0.1639478 0.04505747 0.1465269 0.7025619 0.7116225 -0.1465266 0.1194544 0.1209949 0.1465268 0.2526254 0.9675642 -0.1465266 0.04295307 0.1645118 0.1465266 -0.2650019 0.9642478 -0.1465266 -0.04505741 0.163948 0.1465265 -0.7116223 0.7025623 -0.1465267 -0.1209946 0.1194544 0.1465263 -1.442182 0.5226061 -0.146527 -1.442182 0.5226061 -0.1465271 -1.435367 -0.541043 0.1465263 -1.435367 -0.541043 0.1465263 -1.173681 -0.9876634 -0.146527 -1.173681 -0.9876634 -0.1465268 -0.2491264 -1.513586 0.1465265 -0.2491265 -1.513586 0.1465267 0.2685009 -1.510269 -0.1465266 0.268501 -1.510269 -0.1465264 1.186241 -0.972543 0.1465269 1.186241 -0.972543 0.146527 1.442182 -0.5226063 -0.1465263 1.442182 -0.5226063 -0.1465263 1.435367 0.5410427 0.1465271 1.435367 0.5410427 0.146527 1.173681 0.9876629 -0.1465263 1.173681 0.9876629 -0.1465265 0.2491272 1.513586 0.1465268 0.2491272 1.513586 0.1465266 -0.2685002 1.510269 -0.1465267 -0.2685002 1.510269 -0.1465269 -1.18624 0.9725435 0.1465264 -1.18624 0.9725435 -0.1465269 -0.9642477 -0.2650024 -0.1465269 -0.9675642 0.252625 -0.1465269 -0.7025617 -0.7116228 -0.1465268 -0.2526249 -0.9675642 -0.1465266 0.2650025 -0.9642477 -0.1465265 0.7116227 -0.7025619 -0.1465264 0.9675642 -0.2526252 -0.1465264 0.9642478 0.2650023 -0.1465265 0.702562 0.7116225 -0.1465266 0.2526255 0.9675642 -0.1465267 -0.2650018 0.9642478 -0.1465268 -0.7116222 0.7025623 -2.134743 -0.1639474 -0.04505741 -2.134743 -0.1645112 0.04295295 -2.134743 -0.1194536 -0.1209948 -2.134743 -0.04295235 -0.1645117 -2.134743 0.04505807 -0.1639478 -2.134743 0.1209955 -0.1194543 -2.134743 0.1645123 -0.04295295 -2.134743 0.1639484 0.04505753 -2.134743 0.1194549 0.1209949 -2.134743 0.04295361 0.1645119 -2.134743 -0.04505687 0.1639481 -2.134743 -0.120994 0.1194545</float_array> + <technique_common> + <accessor source="#Cylinder_003-mesh-positions-array" count="72" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cylinder_003-mesh-normals"> + <float_array id="Cylinder_003-mesh-normals-array" count="180">-0.8386326 -0.4699627 -0.2753733 0.8386434 -0.4734479 0.2693035 0.8386326 -0.4699627 -0.2753733 -0.5773617 -0.7873031 -0.2163504 -0.8386386 0.003479182 -0.5446771 0.8386386 0.003479182 -0.5446771 0.8386386 -0.003479182 0.5446771 -0.5773573 0.206247 0.7900132 -0.8386386 -0.003479182 0.5446771 -0.8386434 0.4734479 -0.2693035 0.8386434 0.4734479 -0.2693035 0.5773628 -0.5736395 -0.5810251 0.8386326 0.4699627 0.2753733 0.5773617 0.2163504 -0.7873031 0.5773617 0.7873031 0.2163504 -0.5773573 0.7900132 -0.206247 -0.770264 -0.4538146 0.4480465 -0.6532273 -0.732607 0.1912621 -0.7702726 -0.6170361 0.16108 -0.8386434 -0.4734479 0.2693035 -0.5773627 -0.581025 0.5736394 0.5773573 -0.7900132 0.206247 -0.5773573 -0.206247 -0.7900132 0.5773573 -0.206247 -0.7900132 -0.5773628 -0.5736395 -0.5810251 0.5773627 0.581025 -0.5736394 -0.5773617 0.7873031 0.2163504 0.5773573 0.206247 0.7900132 0.5773573 0.7900132 -0.206247 0.5773628 0.5736395 0.5810251 0.5773627 -0.581025 0.5736394 -0.5773617 -0.2163504 0.7873031 0.5773617 -0.7873031 -0.2163504 0.5773617 -0.2163504 0.7873031 -0.8386326 0.4699627 0.2753733 -0.5773617 0.2163504 -0.7873031 -0.5773627 0.581025 -0.5736394 -0.5773573 -0.7900132 0.206247 -0.5773628 0.5736395 0.5810251 -0.770267 -0.6149257 -0.1689832 -0.7702641 -0.4480466 -0.4538146 -0.7702726 -0.16108 -0.6170361 -0.770267 0.1689832 -0.6149257 -0.770264 0.4538146 -0.4480465 -0.770267 0.6149257 0.1689832 -0.7702726 0.6170361 -0.16108 -0.7702641 0.4480466 0.4538146 -0.7702726 0.16108 0.6170361 -0.770267 -0.1689832 0.6149257 -0.6532381 -0.2006348 0.7300861 -0.6532273 0.732607 -0.1912621 -0.6532307 -0.5319478 -0.5388146 -0.6532381 -0.7300861 -0.2006348 -0.6532273 0.1912621 0.732607 -0.6532273 -0.1912621 -0.732607 -0.6532381 0.7300861 0.2006348 -0.6532381 0.2006348 -0.7300861 -0.6532307 -0.5388146 0.5319478 -0.6532307 0.5319478 0.5388146 -0.6532307 0.5388146 -0.5319478</float_array> + <technique_common> + <accessor source="#Cylinder_003-mesh-normals-array" count="60" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="Cylinder_003-mesh-vertices"> + <input semantic="POSITION" source="#Cylinder_003-mesh-positions"/> + </vertices> + <polylist material="Material_002-material" count="140"> + <input semantic="VERTEX" source="#Cylinder_003-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#Cylinder_003-mesh-normals" offset="1"/> + <vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount> + <p>49 0 2 1 0 2 0 2 25 3 49 0 50 4 6 2 4 5 16 6 41 7 56 8 52 9 10 5 8 10 51 0 31 11 6 2 12 12 55 9 14 10 12 12 35 13 36 14 56 8 18 12 16 6 55 9 41 7 38 15 23 16 61 17 1 18 58 19 22 6 20 1 20 1 45 20 58 19 6 2 18 12 22 6 27 21 29 22 28 23 30 24 32 25 31 11 35 13 37 26 36 14 38 15 40 27 39 28 43 29 45 20 44 30 46 31 24 32 47 33 54 34 34 35 53 4 6 2 32 25 8 10 48 19 27 21 2 1 12 12 37 26 54 34 59 8 47 33 22 6 52 9 30 24 51 0 4 5 27 21 28 23 22 6 24 32 0 2 8 10 33 36 52 9 57 34 43 29 18 12 48 19 29 22 26 37 49 0 46 31 59 8 20 1 43 29 44 30 4 5 29 22 50 4 14 10 38 15 39 28 58 19 42 38 57 34 14 10 40 27 16 6 53 4 35 13 10 5 3 39 49 0 1 18 5 40 48 19 3 39 7 41 50 4 5 40 9 42 51 0 7 41 11 43 52 9 9 42 11 43 54 34 53 4 15 44 54 34 13 45 17 46 55 9 15 44 19 47 56 8 17 46 19 47 58 19 57 34 21 48 59 8 58 19 1 18 59 8 23 16 70 49 66 50 62 51 5 40 60 52 62 51 17 46 69 53 19 47 11 43 66 50 13 45 5 40 63 54 7 41 19 47 70 49 21 48 15 44 66 50 67 55 9 42 63 54 64 56 21 48 71 57 23 16 1 18 60 52 3 39 15 44 68 58 17 46 11 43 64 56 65 59 49 0 48 19 2 1 0 2 24 32 25 3 50 4 51 0 6 2 16 6 40 27 41 7 52 9 53 4 10 5 51 0 30 24 31 11 12 12 54 34 55 9 12 12 10 5 35 13 56 8 57 34 18 12 55 9 56 8 41 7 23 16 71 57 61 17 58 19 59 8 22 6 20 1 44 30 45 20 22 6 0 2 2 1 2 1 4 5 6 2 6 2 8 10 10 5 10 5 12 12 6 2 14 10 16 6 18 12 18 12 20 1 22 6 22 6 2 1 6 2 6 2 12 12 14 10 14 10 18 12 6 2 27 21 26 37 29 22 30 24 33 36 32 25 35 13 34 35 37 26 38 15 41 7 40 27 43 29 42 38 45 20 46 31 25 3 24 32 54 34 37 26 34 35 6 2 31 11 32 25 48 19 26 37 27 21 12 12 36 14 37 26 59 8 46 31 47 33 52 9 33 36 30 24 4 5 2 1 27 21 22 6 47 33 24 32 8 10 32 25 33 36 57 34 42 38 43 29 48 19 50 4 29 22 49 0 25 3 46 31 20 1 18 12 43 29 4 5 28 23 29 22 14 10 55 9 38 15 58 19 45 20 42 38 14 10 39 28 40 27 53 4 34 35 35 13 3 39 48 19 49 0 5 40 50 4 48 19 7 41 51 0 50 4 9 42 52 9 51 0 11 43 53 4 52 9 11 43 13 45 54 34 15 44 55 9 54 34 17 46 56 8 55 9 19 47 57 34 56 8 19 47 21 48 58 19 21 48 23 16 59 8 1 18 49 0 59 8 62 51 60 52 61 17 61 17 71 57 62 51 70 49 69 53 68 58 68 58 67 55 70 49 66 50 65 59 64 56 64 56 63 54 62 51 62 51 71 57 70 49 70 49 67 55 66 50 66 50 64 56 62 51 5 40 3 39 60 52 17 46 68 58 69 53 11 43 65 59 66 50 5 40 62 51 63 54 19 47 69 53 70 49 15 44 13 45 66 50 9 42 7 41 63 54 21 48 70 49 71 57 1 18 61 17 60 52 15 44 67 55 68 58 11 43 9 42 64 56</p> + </polylist> + </mesh> + </geometry> + <geometry id="Cylinder_004-mesh" name="Cylinder.004"> + <mesh> + <source id="Cylinder_004-mesh-positions"> + <float_array id="Cylinder_004-mesh-positions-array" count="216">-0.1465266 0.9675642 0.252625 0.1465266 0.1645117 0.04295283 -0.1465266 0.9642477 -0.2650024 0.1465267 0.1639479 -0.04505747 -0.1465266 0.7025617 -0.7116228 0.1465267 0.1194542 -0.1209948 -0.1465266 0.2526249 -0.9675642 0.1465267 0.04295295 -0.1645118 -0.1465266 -0.2650025 -0.9642477 0.1465266 -0.04505753 -0.1639479 -0.1465267 -0.7116227 -0.7025619 0.1465266 -0.1209949 -0.1194544 -0.1465267 -0.9675642 -0.2526252 0.1465266 -0.1645117 -0.04295301 -0.1465267 -0.9642478 0.2650023 0.1465266 -0.1639478 0.04505747 -0.1465267 -0.702562 0.7116225 0.1465266 -0.1194543 0.1209949 -0.1465267 -0.2526254 0.9675642 0.1465266 -0.04295307 0.1645118 -0.1465267 0.2650019 0.9642478 0.1465266 0.04505747 0.163948 -0.1465266 0.7116222 0.7025623 0.1465266 0.1209946 0.1194544 -0.1465266 1.442182 0.5226061 0.1465267 1.442182 0.5226061 0.1465268 1.435367 -0.541043 -0.1465266 1.435367 -0.541043 -0.1465266 1.173681 -0.9876634 0.1465268 1.173681 -0.9876634 0.1465268 0.2491264 -1.513586 -0.1465266 0.2491265 -1.513586 -0.1465266 -0.2685009 -1.510269 0.1465267 -0.2685009 -1.510269 0.1465266 -1.186241 -0.972543 -0.1465267 -1.186241 -0.972543 -0.1465267 -1.442182 -0.5226063 0.1465266 -1.442182 -0.5226063 0.1465266 -1.435367 0.5410427 -0.1465268 -1.435367 0.5410427 -0.1465268 -1.173681 0.9876629 0.1465266 -1.173681 0.9876629 0.1465266 -0.2491272 1.513586 -0.1465268 -0.2491272 1.513586 -0.1465267 0.2685002 1.510269 0.1465266 0.2685002 1.510269 0.1465267 1.18624 0.9725435 -0.1465266 1.18624 0.9725435 0.1465267 0.9642477 -0.2650024 0.1465267 0.9675642 0.252625 0.1465267 0.7025617 -0.7116228 0.1465267 0.2526249 -0.9675642 0.1465267 -0.2650025 -0.9642477 0.1465266 -0.7116227 -0.7025619 0.1465266 -0.9675642 -0.2526252 0.1465266 -0.9642478 0.2650023 0.1465266 -0.702562 0.7116225 0.1465266 -0.2526254 0.9675642 0.1465266 0.2650019 0.9642478 0.1465267 0.7116222 0.7025623 2.134743 0.1639478 -0.04505741 2.134743 0.1645116 0.04295295 2.134743 0.1194541 -0.1209948 2.134743 0.04295283 -0.1645117 2.134743 -0.04505765 -0.1639478 2.134743 -0.1209951 -0.1194543 2.134743 -0.1645119 -0.04295295 2.134743 -0.1639479 0.04505753 2.134743 -0.1194545 0.1209949 2.134743 -0.04295319 0.1645119 2.134743 0.04505735 0.1639481 2.134743 0.1209945 0.1194545</float_array> + <technique_common> + <accessor source="#Cylinder_004-mesh-positions-array" count="72" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cylinder_004-mesh-normals"> + <float_array id="Cylinder_004-mesh-normals-array" count="180">0.8386326 0.4699627 -0.2753733 -0.8386434 0.4734479 0.2693035 -0.8386326 0.4699627 -0.2753733 0.5773617 0.7873031 -0.2163504 0.8386386 -0.003479182 -0.5446771 -0.8386386 -0.003479182 -0.5446771 -0.8386386 0.003479182 0.5446771 0.5773573 -0.206247 0.7900132 0.8386386 0.003479182 0.5446771 -0.8386434 -0.4734479 -0.2693035 -0.5773628 0.5736395 -0.5810251 0.8386326 -0.4699627 0.2753733 -0.8386326 -0.4699627 0.2753733 -0.5773617 -0.2163504 -0.7873031 -0.5773617 -0.7873031 0.2163504 0.8386434 -0.4734479 -0.2693035 0.5773573 -0.7900132 -0.206247 0.770264 0.4538146 0.4480465 0.6532273 0.732607 0.1912621 0.7702726 0.6170361 0.16108 0.8386434 0.4734479 0.2693035 0.5773627 0.581025 0.5736394 0.5773573 0.7900132 0.206247 -0.5773573 0.206247 -0.7900132 -0.5773573 0.7900132 0.206247 0.5773628 0.5736395 -0.5810251 -0.5773627 -0.581025 -0.5736394 0.5773617 -0.7873031 0.2163504 -0.5773573 -0.206247 0.7900132 -0.5773573 -0.7900132 -0.206247 -0.5773628 -0.5736395 0.5810251 -0.5773627 0.581025 0.5736394 0.5773617 0.2163504 0.7873031 -0.5773617 0.7873031 -0.2163504 -0.5773617 0.2163504 0.7873031 0.5773617 -0.2163504 -0.7873031 0.5773627 -0.581025 -0.5736394 0.5773628 -0.5736395 0.5810251 0.5773573 0.206247 -0.7900132 0.7702641 0.4480466 -0.4538146 0.770267 0.6149257 -0.1689832 0.770267 -0.1689832 -0.6149257 0.7702726 0.16108 -0.6170361 0.770264 -0.4538146 -0.4480465 0.770267 -0.6149257 0.1689832 0.7702726 -0.6170361 -0.16108 0.7702641 -0.4480466 0.4538146 0.7702726 -0.16108 0.6170361 0.770267 0.1689832 0.6149257 0.6532381 0.2006348 0.7300861 0.6532273 -0.732607 -0.1912621 0.6532307 0.5319478 -0.5388146 0.6532273 -0.1912621 0.732607 0.6532273 0.1912621 -0.732607 0.6532235 -0.7301003 0.2006303 0.6532381 -0.2006348 -0.7300861 0.6532307 0.5388146 0.5319478 0.6532381 0.7300861 -0.2006348 0.6532307 -0.5319478 0.5388146 0.6532307 -0.5388146 -0.5319478</float_array> + <technique_common> + <accessor source="#Cylinder_004-mesh-normals-array" count="60" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="Cylinder_004-mesh-vertices"> + <input semantic="POSITION" source="#Cylinder_004-mesh-positions"/> + </vertices> + <polylist material="Material-material" count="140"> + <input semantic="VERTEX" source="#Cylinder_004-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#Cylinder_004-mesh-normals" offset="1"/> + <vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount> + <p>49 0 2 1 0 2 0 2 25 3 49 0 50 4 6 2 4 5 16 6 41 7 56 8 8 9 53 4 10 5 51 0 31 10 6 2 54 11 14 9 12 12 12 12 35 13 36 14 56 8 18 12 16 6 55 15 41 7 38 16 23 17 61 18 1 19 58 20 22 6 20 1 20 1 45 21 58 20 6 2 18 12 22 6 26 22 28 23 27 24 30 25 32 26 31 10 35 13 37 27 36 14 38 16 40 28 39 29 43 30 45 21 44 31 46 32 24 33 47 34 54 11 34 35 53 4 6 2 32 26 8 9 48 20 27 24 2 1 12 12 37 27 54 11 59 8 47 34 22 6 52 15 30 25 51 0 2 1 28 23 4 5 22 6 24 33 0 2 52 15 32 26 33 36 18 12 42 37 43 30 50 4 26 22 48 20 49 0 46 32 59 8 20 1 43 30 44 31 50 4 28 23 29 38 14 9 38 16 39 29 58 20 42 37 57 11 14 9 40 28 16 6 53 4 35 13 10 5 1 19 48 20 49 0 5 39 48 20 3 40 5 39 51 0 50 4 9 41 51 0 7 42 11 43 52 15 9 41 11 43 54 11 53 4 15 44 54 11 13 45 17 46 55 15 15 44 19 47 56 8 17 46 19 47 58 20 57 11 23 17 58 20 21 48 1 19 59 8 23 17 70 49 66 50 62 51 3 40 62 51 5 39 17 46 69 52 19 47 11 43 66 50 13 45 5 39 63 53 7 42 19 47 70 49 21 48 15 44 66 50 67 54 9 41 63 53 64 55 21 48 71 56 23 17 1 19 60 57 3 40 15 44 68 58 17 46 9 41 65 59 11 43 49 0 48 20 2 1 0 2 24 33 25 3 50 4 51 0 6 2 16 6 40 28 41 7 8 9 52 15 53 4 51 0 30 25 31 10 54 11 55 15 14 9 12 12 10 5 35 13 56 8 57 11 18 12 55 15 56 8 41 7 23 17 71 56 61 18 58 20 59 8 22 6 20 1 44 31 45 21 22 6 0 2 2 1 2 1 4 5 6 2 6 2 8 9 10 5 10 5 12 12 6 2 14 9 16 6 18 12 18 12 20 1 22 6 22 6 2 1 6 2 6 2 12 12 14 9 14 9 18 12 6 2 26 22 29 38 28 23 30 25 33 36 32 26 35 13 34 35 37 27 38 16 41 7 40 28 43 30 42 37 45 21 46 32 25 3 24 33 54 11 37 27 34 35 6 2 31 10 32 26 48 20 26 22 27 24 12 12 36 14 37 27 59 8 46 32 47 34 52 15 33 36 30 25 2 1 27 24 28 23 22 6 47 34 24 33 52 15 8 9 32 26 18 12 57 11 42 37 50 4 29 38 26 22 49 0 25 3 46 32 20 1 18 12 43 30 50 4 4 5 28 23 14 9 55 15 38 16 58 20 45 21 42 37 14 9 39 29 40 28 53 4 34 35 35 13 1 19 3 40 48 20 5 39 50 4 48 20 5 39 7 42 51 0 9 41 52 15 51 0 11 43 53 4 52 15 11 43 13 45 54 11 15 44 55 15 54 11 17 46 56 8 55 15 19 47 57 11 56 8 19 47 21 48 58 20 23 17 59 8 58 20 1 19 49 0 59 8 62 51 60 57 61 18 61 18 71 56 62 51 70 49 69 52 66 50 68 58 67 54 66 50 66 50 65 59 64 55 64 55 63 53 62 51 62 51 71 56 70 49 69 52 68 58 66 50 66 50 64 55 62 51 3 40 60 57 62 51 17 46 68 58 69 52 11 43 65 59 66 50 5 39 62 51 63 53 19 47 69 52 70 49 15 44 13 45 66 50 9 41 7 42 63 53 21 48 70 49 71 56 1 19 61 18 60 57 15 44 67 54 68 58 9 41 64 55 65 59</p> + </polylist> + </mesh> + </geometry> + <geometry id="Cylinder_006-mesh" name="Cylinder.006"> + <mesh> + <source id="Cylinder_006-mesh-positions"> + <float_array id="Cylinder_006-mesh-positions-array" count="216">-0.6937502 0.7202157 -0.1465266 -0.117956 0.122456 0.1465266 -0.2406975 0.9706001 -0.1465266 -0.04092502 0.165028 0.1465266 0.2768501 0.9609132 -0.1465266 0.04707187 0.1633808 0.1465266 0.7202157 0.6937502 -0.1465266 0.122456 0.1179561 0.1465266 0.9706003 0.2406975 -0.1465266 0.165028 0.04092496 0.1465266 0.9609132 -0.2768499 -0.1465266 0.163381 -0.04707187 0.1465266 0.6937503 -0.7202156 -0.1465266 0.1179561 -0.1224558 0.1465266 0.2406976 -0.9706001 -0.1465266 0.04092496 -0.1650279 0.1465266 -0.2768496 -0.9609132 -0.1465266 -0.04707181 -0.163381 0.1465266 -0.7202154 -0.6937506 -0.1465266 -0.1224559 -0.1179561 0.1465266 -0.9706 -0.240698 -0.1465266 -0.165028 -0.04092508 0.1465266 -0.9609134 0.2768493 -0.1465266 -0.1633809 0.04707157 0.1465266 -1.161437 1.002034 -0.1465266 -1.161437 1.002034 0.1465266 -0.2304791 1.516537 0.1465266 -0.2304791 1.516537 -0.1465266 0.2870684 1.50685 -0.1465266 0.2870684 1.50685 0.1465266 1.19812 0.9578695 0.1465266 1.19812 0.9578695 -0.1465266 1.448505 0.5048167 -0.1465266 1.448505 0.5048167 0.1465266 1.4286 -0.5586678 0.1465266 1.4286 -0.5586678 -0.1465266 1.161437 -1.002034 -0.1465266 1.161437 -1.002034 0.1465266 0.2304794 -1.516537 0.1465266 0.2304794 -1.516537 -0.1465266 -0.2870679 -1.50685 -0.1465266 -0.2870679 -1.50685 0.1465266 -1.19812 -0.95787 0.1465266 -1.19812 -0.95787 -0.1465266 -1.448505 -0.5048175 -0.1465266 -1.448505 -0.5048175 0.1465266 -1.4286 0.5586673 0.1465266 -1.4286 0.5586673 -0.1465266 -0.2406975 0.9706001 0.1465266 -0.6937502 0.7202157 0.1465266 0.2768501 0.9609132 0.1465266 0.7202157 0.6937502 0.1465266 0.9706003 0.2406975 0.1465266 0.9609132 -0.2768499 0.1465266 0.6937503 -0.7202156 0.1465266 0.2406976 -0.9706001 0.1465266 -0.2768496 -0.9609132 0.1465266 -0.7202154 -0.6937506 0.1465266 -0.9706 -0.240698 0.1465266 -0.9609134 0.2768493 0.1465266 -0.04092502 0.165028 4.503279 -0.117956 0.122456 4.503279 0.04707187 0.1633808 4.503279 0.122456 0.1179561 4.503279 0.165028 0.04092496 4.503279 0.163381 -0.04707187 4.503279 0.1179561 -0.1224558 4.503279 0.04092496 -0.1650279 4.503279 -0.04707181 -0.163381 4.503279 -0.1224559 -0.1179561 4.503279 -0.165028 -0.04092508 4.503279 -0.1633809 0.04707157 4.503279</float_array> + <technique_common> + <accessor source="#Cylinder_006-mesh-positions-array" count="72" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cylinder_006-mesh-normals"> + <float_array id="Cylinder_006-mesh-normals-array" count="180">0.01019328 0.5446093 0.838628 -0.4665465 0.281112 -0.8386361 0.01019328 0.5446093 -0.838628 -0.1965123 0.7924888 0.5773599 0.4767377 0.2634708 0.8386324 0.4767377 0.2634708 -0.8386324 -0.4767377 -0.2634708 -0.8386324 -0.5880461 -0.5664384 0.5773643 -0.4767377 -0.2634708 0.8386324 0.4665465 -0.281112 0.8386361 0.4665465 -0.281112 -0.8386361 0.2260238 0.7845829 -0.5773588 -0.01019328 -0.5446093 0.838628 -0.01019328 -0.5446093 -0.838628 0.7924888 0.1965123 -0.5773599 0.1965123 -0.7924888 -0.5773599 0.5664384 -0.5880461 0.5773643 -0.6127917 0.1765526 0.7702699 -0.525269 0.5453203 0.6532368 -0.4424093 0.4592865 0.7702792 -0.4665465 0.281112 0.8386361 -0.7845829 0.2260238 0.5773588 -0.5664384 0.5880461 0.5773643 0.5880461 0.5664384 -0.5773643 -0.5664384 0.5880461 -0.5773643 0.2260238 0.7845829 0.5773588 0.7845829 -0.2260238 -0.5773588 0.7924888 0.1965123 0.5773599 -0.5880461 -0.5664384 -0.5773643 0.5664384 -0.5880461 -0.5773643 -0.2260238 -0.7845829 0.5773588 -0.7845829 0.2260238 -0.5773588 -0.2260238 -0.7845829 -0.5773588 -0.7924888 -0.1965123 0.5773599 -0.1965123 0.7924888 -0.5773599 -0.7924888 -0.1965123 -0.5773599 0.1965123 -0.7924888 0.5773599 0.7845829 -0.2260238 0.5773588 0.5880461 0.5664384 0.5773643 0.1765526 0.6127917 0.7702699 -0.1534789 0.6189819 0.7702634 0.4592865 0.4424093 0.7702792 0.6189819 0.1534789 0.7702634 0.6127917 -0.1765526 0.7702699 0.1534789 -0.6189819 0.7702634 0.4424093 -0.4592865 0.7702792 -0.1765526 -0.6127917 0.7702699 -0.4592865 -0.4424093 0.7702792 -0.6189819 -0.1534789 0.7702634 -0.7349014 -0.1822299 0.6532321 0.525269 -0.5453203 0.6532368 0.209604 0.7275715 0.6532273 -0.5453203 -0.525269 0.6532368 0.5453203 0.525269 0.6532368 0.1822299 -0.7349014 0.6532321 0.7349014 0.1822299 0.6532321 -0.7275715 0.209604 0.6532273 -0.1822299 0.7349014 0.6532321 -0.209604 -0.7275715 0.6532273 0.7275571 -0.2096087 0.6532418</float_array> + <technique_common> + <accessor source="#Cylinder_006-mesh-normals-array" count="60" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="Cylinder_006-mesh-vertices"> + <input semantic="POSITION" source="#Cylinder_006-mesh-positions"/> + </vertices> + <polylist material="Material_001-material" count="140"> + <input semantic="VERTEX" source="#Cylinder_006-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#Cylinder_006-mesh-normals" offset="1"/> + <vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount> + <p>49 0 2 1 0 2 0 2 25 3 49 0 50 4 6 2 4 5 16 6 41 7 56 8 52 9 10 5 8 10 51 0 31 11 6 2 54 12 14 10 12 13 12 13 35 14 36 15 56 8 18 13 16 6 55 9 41 7 38 16 23 17 61 18 1 19 58 20 22 6 20 1 20 1 45 21 58 20 6 2 14 10 22 6 26 22 28 23 27 24 30 25 32 26 31 11 34 27 36 15 35 14 38 16 40 28 39 29 42 30 44 31 43 32 46 33 24 34 47 35 54 12 34 27 53 4 8 10 31 11 32 26 48 20 27 24 2 1 12 13 37 36 54 12 59 8 47 35 22 6 52 9 30 25 51 0 4 5 27 24 28 23 22 6 24 34 0 2 8 10 33 37 52 9 57 12 43 32 18 13 50 4 26 22 48 20 49 0 46 33 59 8 20 1 43 32 44 31 4 5 29 38 50 4 55 9 39 29 14 10 58 20 42 30 57 12 14 10 40 28 16 6 53 4 35 14 10 5 1 19 48 20 49 0 5 39 48 20 3 40 7 41 50 4 5 39 9 42 51 0 7 41 11 43 52 9 9 42 11 43 54 12 53 4 15 44 54 12 13 45 17 46 55 9 15 44 19 47 56 8 17 46 19 47 58 20 57 12 21 48 59 8 58 20 1 19 59 8 23 17 70 49 66 50 62 51 3 40 62 51 5 39 17 46 69 52 19 47 11 43 66 50 13 45 5 39 63 53 7 41 19 47 70 49 21 48 13 45 67 54 15 44 7 41 64 55 9 42 21 48 71 56 23 17 1 19 60 57 3 40 15 44 68 58 17 46 9 42 65 59 11 43 49 0 48 20 2 1 0 2 24 34 25 3 50 4 51 0 6 2 16 6 40 28 41 7 52 9 53 4 10 5 51 0 30 25 31 11 54 12 55 9 14 10 12 13 10 5 35 14 56 8 57 12 18 13 55 9 56 8 41 7 23 17 71 56 61 18 58 20 59 8 22 6 20 1 44 31 45 21 22 6 0 2 6 2 2 1 4 5 6 2 6 2 8 10 10 5 10 5 12 13 14 10 14 10 16 6 18 13 18 13 20 1 14 10 0 2 2 1 6 2 6 2 10 5 14 10 14 10 20 1 22 6 26 22 29 38 28 23 30 25 33 37 32 26 34 27 37 36 36 15 38 16 41 7 40 28 42 30 45 21 44 31 46 33 25 3 24 34 54 12 37 36 34 27 8 10 6 2 31 11 48 20 26 22 27 24 12 13 36 15 37 36 59 8 46 33 47 35 52 9 33 37 30 25 4 5 2 1 27 24 22 6 47 35 24 34 8 10 32 26 33 37 57 12 42 30 43 32 50 4 29 38 26 22 49 0 25 3 46 33 20 1 18 13 43 32 4 5 28 23 29 38 55 9 38 16 39 29 58 20 45 21 42 30 14 10 39 29 40 28 53 4 34 27 35 14 1 19 3 40 48 20 5 39 50 4 48 20 7 41 51 0 50 4 9 42 52 9 51 0 11 43 53 4 52 9 11 43 13 45 54 12 15 44 55 9 54 12 17 46 56 8 55 9 19 47 57 12 56 8 19 47 21 48 58 20 21 48 23 17 59 8 1 19 49 0 59 8 62 51 60 57 61 18 61 18 71 56 62 51 70 49 69 52 68 58 68 58 67 54 70 49 66 50 65 59 64 55 64 55 63 53 62 51 62 51 71 56 70 49 70 49 67 54 66 50 66 50 64 55 62 51 3 40 60 57 62 51 17 46 68 58 69 52 11 43 65 59 66 50 5 39 62 51 63 53 19 47 69 52 70 49 13 45 66 50 67 54 7 41 63 53 64 55 21 48 70 49 71 56 1 19 61 18 60 57 15 44 67 54 68 58 9 42 64 55 65 59</p> + </polylist> + </mesh> + </geometry> + <geometry id="Cube-mesh" name="Cube"> + <mesh> + <source id="Cube-mesh-positions"> + <float_array id="Cube-mesh-positions-array" count="24">-0.4649617 -2.207998 2.663758 -0.4649617 -2.207998 3.004 -2.199902 4.454042 2.663758 -2.199902 4.454042 3.004 1.470484 -1.703966 2.663758 1.470484 -1.703966 3.004 -0.2644557 4.958074 2.663758 -0.2644557 4.958074 3.004</float_array> + <technique_common> + <accessor source="#Cube-mesh-positions-array" count="8" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cube-mesh-normals"> + <float_array id="Cube-mesh-normals-array" count="33">-0.967723 -0.2520163 0 -0.252016 0.9677231 0 0.9677231 0.2520161 0 0.2520161 -0.9677231 0 0 0 -1 2.7706e-7 0 1 -0.9677231 -0.2520158 0 -0.252016 0.9677231 0 0.2520164 -0.967723 0 0 0 -1 0 0 1</float_array> + <technique_common> + <accessor source="#Cube-mesh-normals-array" count="11" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="Cube-mesh-vertices"> + <input semantic="POSITION" source="#Cube-mesh-positions"/> + </vertices> + <polylist count="12"> + <input semantic="VERTEX" source="#Cube-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#Cube-mesh-normals" offset="1"/> + <vcount>3 3 3 3 3 3 3 3 3 3 3 3 </vcount> + <p>3 0 0 0 1 0 7 1 2 1 3 1 5 2 6 2 7 2 1 3 4 3 5 3 2 4 4 4 0 4 5 5 3 5 1 5 3 6 2 6 0 6 7 7 6 7 2 7 5 2 4 2 6 2 1 8 0 8 4 8 2 9 6 9 4 9 5 10 7 10 3 10</p> + </polylist> + </mesh> + </geometry> + </library_geometries> + <library_animations> + <animation id="GearTop_rotation_euler_X"> + <source id="GearTop_rotation_euler_X-input"> + <float_array id="GearTop_rotation_euler_X-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_X-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_rotation_euler_X-output"> + <float_array id="GearTop_rotation_euler_X-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_X-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_rotation_euler_X-interpolation"> + <Name_array id="GearTop_rotation_euler_X-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_X-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearTop_rotation_euler_X-sampler"> + <input semantic="INPUT" source="#GearTop_rotation_euler_X-input"/> + <input semantic="OUTPUT" source="#GearTop_rotation_euler_X-output"/> + <input semantic="INTERPOLATION" source="#GearTop_rotation_euler_X-interpolation"/> + </sampler> + <channel source="#GearTop_rotation_euler_X-sampler" target="GearTop/rotationX.ANGLE"/> + </animation> + <animation id="GearTop_rotation_euler_Y"> + <source id="GearTop_rotation_euler_Y-input"> + <float_array id="GearTop_rotation_euler_Y-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_Y-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_rotation_euler_Y-output"> + <float_array id="GearTop_rotation_euler_Y-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_Y-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_rotation_euler_Y-interpolation"> + <Name_array id="GearTop_rotation_euler_Y-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_Y-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearTop_rotation_euler_Y-sampler"> + <input semantic="INPUT" source="#GearTop_rotation_euler_Y-input"/> + <input semantic="OUTPUT" source="#GearTop_rotation_euler_Y-output"/> + <input semantic="INTERPOLATION" source="#GearTop_rotation_euler_Y-interpolation"/> + </sampler> + <channel source="#GearTop_rotation_euler_Y-sampler" target="GearTop/rotationY.ANGLE"/> + </animation> + <animation id="GearTop_rotation_euler_Z"> + <source id="GearTop_rotation_euler_Z-input"> + <float_array id="GearTop_rotation_euler_Z-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_Z-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_rotation_euler_Z-output"> + <float_array id="GearTop_rotation_euler_Z-output-array" count="4">0 -120 -240 -360</float_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_Z-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_rotation_euler_Z-interpolation"> + <Name_array id="GearTop_rotation_euler_Z-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearTop_rotation_euler_Z-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearTop_rotation_euler_Z-sampler"> + <input semantic="INPUT" source="#GearTop_rotation_euler_Z-input"/> + <input semantic="OUTPUT" source="#GearTop_rotation_euler_Z-output"/> + <input semantic="INTERPOLATION" source="#GearTop_rotation_euler_Z-interpolation"/> + </sampler> + <channel source="#GearTop_rotation_euler_Z-sampler" target="GearTop/rotationZ.ANGLE"/> + </animation> + <animation id="GearLeft_rotation_euler_X"> + <source id="GearLeft_rotation_euler_X-input"> + <float_array id="GearLeft_rotation_euler_X-input-array" count="4">0 0.8333333 1.666667 2.458333</float_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_X-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearLeft_rotation_euler_X-output"> + <float_array id="GearLeft_rotation_euler_X-output-array" count="4">0 -122.0339 -244.0678 -360</float_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_X-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearLeft_rotation_euler_X-interpolation"> + <Name_array id="GearLeft_rotation_euler_X-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_X-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearLeft_rotation_euler_X-sampler"> + <input semantic="INPUT" source="#GearLeft_rotation_euler_X-input"/> + <input semantic="OUTPUT" source="#GearLeft_rotation_euler_X-output"/> + <input semantic="INTERPOLATION" source="#GearLeft_rotation_euler_X-interpolation"/> + </sampler> + <channel source="#GearLeft_rotation_euler_X-sampler" target="GearLeft/rotationX.ANGLE"/> + </animation> + <animation id="GearLeft_rotation_euler_Y"> + <source id="GearLeft_rotation_euler_Y-input"> + <float_array id="GearLeft_rotation_euler_Y-input-array" count="4">0 0.8333333 1.666667 2.458333</float_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_Y-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearLeft_rotation_euler_Y-output"> + <float_array id="GearLeft_rotation_euler_Y-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_Y-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearLeft_rotation_euler_Y-interpolation"> + <Name_array id="GearLeft_rotation_euler_Y-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_Y-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearLeft_rotation_euler_Y-sampler"> + <input semantic="INPUT" source="#GearLeft_rotation_euler_Y-input"/> + <input semantic="OUTPUT" source="#GearLeft_rotation_euler_Y-output"/> + <input semantic="INTERPOLATION" source="#GearLeft_rotation_euler_Y-interpolation"/> + </sampler> + <channel source="#GearLeft_rotation_euler_Y-sampler" target="GearLeft/rotationY.ANGLE"/> + </animation> + <animation id="GearLeft_rotation_euler_Z"> + <source id="GearLeft_rotation_euler_Z-input"> + <float_array id="GearLeft_rotation_euler_Z-input-array" count="4">0 0.8333333 1.666667 2.458333</float_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_Z-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearLeft_rotation_euler_Z-output"> + <float_array id="GearLeft_rotation_euler_Z-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_Z-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearLeft_rotation_euler_Z-interpolation"> + <Name_array id="GearLeft_rotation_euler_Z-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearLeft_rotation_euler_Z-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearLeft_rotation_euler_Z-sampler"> + <input semantic="INPUT" source="#GearLeft_rotation_euler_Z-input"/> + <input semantic="OUTPUT" source="#GearLeft_rotation_euler_Z-output"/> + <input semantic="INTERPOLATION" source="#GearLeft_rotation_euler_Z-interpolation"/> + </sampler> + <channel source="#GearLeft_rotation_euler_Z-sampler" target="GearLeft/rotationZ.ANGLE"/> + </animation> + <animation id="GearRight_rotation_euler_X"> + <source id="GearRight_rotation_euler_X-input"> + <float_array id="GearRight_rotation_euler_X-input-array" count="4">0.04166662 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_X-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearRight_rotation_euler_X-output"> + <float_array id="GearRight_rotation_euler_X-output-array" count="4">0 115.9322 237.9661 360</float_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_X-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearRight_rotation_euler_X-interpolation"> + <Name_array id="GearRight_rotation_euler_X-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_X-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearRight_rotation_euler_X-sampler"> + <input semantic="INPUT" source="#GearRight_rotation_euler_X-input"/> + <input semantic="OUTPUT" source="#GearRight_rotation_euler_X-output"/> + <input semantic="INTERPOLATION" source="#GearRight_rotation_euler_X-interpolation"/> + </sampler> + <channel source="#GearRight_rotation_euler_X-sampler" target="GearRight/rotationX.ANGLE"/> + </animation> + <animation id="GearRight_rotation_euler_Y"> + <source id="GearRight_rotation_euler_Y-input"> + <float_array id="GearRight_rotation_euler_Y-input-array" count="4">0.04166662 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_Y-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearRight_rotation_euler_Y-output"> + <float_array id="GearRight_rotation_euler_Y-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_Y-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearRight_rotation_euler_Y-interpolation"> + <Name_array id="GearRight_rotation_euler_Y-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_Y-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearRight_rotation_euler_Y-sampler"> + <input semantic="INPUT" source="#GearRight_rotation_euler_Y-input"/> + <input semantic="OUTPUT" source="#GearRight_rotation_euler_Y-output"/> + <input semantic="INTERPOLATION" source="#GearRight_rotation_euler_Y-interpolation"/> + </sampler> + <channel source="#GearRight_rotation_euler_Y-sampler" target="GearRight/rotationY.ANGLE"/> + </animation> + <animation id="GearRight_rotation_euler_Z"> + <source id="GearRight_rotation_euler_Z-input"> + <float_array id="GearRight_rotation_euler_Z-input-array" count="4">0.04166662 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_Z-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearRight_rotation_euler_Z-output"> + <float_array id="GearRight_rotation_euler_Z-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_Z-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearRight_rotation_euler_Z-interpolation"> + <Name_array id="GearRight_rotation_euler_Z-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearRight_rotation_euler_Z-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearRight_rotation_euler_Z-sampler"> + <input semantic="INPUT" source="#GearRight_rotation_euler_Z-input"/> + <input semantic="OUTPUT" source="#GearRight_rotation_euler_Z-output"/> + <input semantic="INTERPOLATION" source="#GearRight_rotation_euler_Z-interpolation"/> + </sampler> + <channel source="#GearRight_rotation_euler_Z-sampler" target="GearRight/rotationZ.ANGLE"/> + </animation> + <animation id="GearTop_001_rotation_euler_X"> + <source id="GearTop_001_rotation_euler_X-input"> + <float_array id="GearTop_001_rotation_euler_X-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_X-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_001_rotation_euler_X-output"> + <float_array id="GearTop_001_rotation_euler_X-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_X-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_001_rotation_euler_X-interpolation"> + <Name_array id="GearTop_001_rotation_euler_X-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_X-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearTop_001_rotation_euler_X-sampler"> + <input semantic="INPUT" source="#GearTop_001_rotation_euler_X-input"/> + <input semantic="OUTPUT" source="#GearTop_001_rotation_euler_X-output"/> + <input semantic="INTERPOLATION" source="#GearTop_001_rotation_euler_X-interpolation"/> + </sampler> + <channel source="#GearTop_001_rotation_euler_X-sampler" target="GearTop_001/rotationX.ANGLE"/> + </animation> + <animation id="GearTop_001_rotation_euler_Y"> + <source id="GearTop_001_rotation_euler_Y-input"> + <float_array id="GearTop_001_rotation_euler_Y-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_Y-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_001_rotation_euler_Y-output"> + <float_array id="GearTop_001_rotation_euler_Y-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_Y-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_001_rotation_euler_Y-interpolation"> + <Name_array id="GearTop_001_rotation_euler_Y-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_Y-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearTop_001_rotation_euler_Y-sampler"> + <input semantic="INPUT" source="#GearTop_001_rotation_euler_Y-input"/> + <input semantic="OUTPUT" source="#GearTop_001_rotation_euler_Y-output"/> + <input semantic="INTERPOLATION" source="#GearTop_001_rotation_euler_Y-interpolation"/> + </sampler> + <channel source="#GearTop_001_rotation_euler_Y-sampler" target="GearTop_001/rotationY.ANGLE"/> + </animation> + <animation id="GearTop_001_rotation_euler_Z"> + <source id="GearTop_001_rotation_euler_Z-input"> + <float_array id="GearTop_001_rotation_euler_Z-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_Z-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_001_rotation_euler_Z-output"> + <float_array id="GearTop_001_rotation_euler_Z-output-array" count="4">0 -120 -240 -360</float_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_Z-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="GearTop_001_rotation_euler_Z-interpolation"> + <Name_array id="GearTop_001_rotation_euler_Z-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#GearTop_001_rotation_euler_Z-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="GearTop_001_rotation_euler_Z-sampler"> + <input semantic="INPUT" source="#GearTop_001_rotation_euler_Z-input"/> + <input semantic="OUTPUT" source="#GearTop_001_rotation_euler_Z-output"/> + <input semantic="INTERPOLATION" source="#GearTop_001_rotation_euler_Z-interpolation"/> + </sampler> + <channel source="#GearTop_001_rotation_euler_Z-sampler" target="GearTop_001/rotationZ.ANGLE"/> + </animation> + <animation id="Cube_rotation_euler_X"> + <source id="Cube_rotation_euler_X-input"> + <float_array id="Cube_rotation_euler_X-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#Cube_rotation_euler_X-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cube_rotation_euler_X-output"> + <float_array id="Cube_rotation_euler_X-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#Cube_rotation_euler_X-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cube_rotation_euler_X-interpolation"> + <Name_array id="Cube_rotation_euler_X-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#Cube_rotation_euler_X-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="Cube_rotation_euler_X-sampler"> + <input semantic="INPUT" source="#Cube_rotation_euler_X-input"/> + <input semantic="OUTPUT" source="#Cube_rotation_euler_X-output"/> + <input semantic="INTERPOLATION" source="#Cube_rotation_euler_X-interpolation"/> + </sampler> + <channel source="#Cube_rotation_euler_X-sampler" target="Cube/rotationX.ANGLE"/> + </animation> + <animation id="Cube_rotation_euler_Y"> + <source id="Cube_rotation_euler_Y-input"> + <float_array id="Cube_rotation_euler_Y-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#Cube_rotation_euler_Y-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cube_rotation_euler_Y-output"> + <float_array id="Cube_rotation_euler_Y-output-array" count="4">0 0 0 0</float_array> + <technique_common> + <accessor source="#Cube_rotation_euler_Y-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cube_rotation_euler_Y-interpolation"> + <Name_array id="Cube_rotation_euler_Y-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#Cube_rotation_euler_Y-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="Cube_rotation_euler_Y-sampler"> + <input semantic="INPUT" source="#Cube_rotation_euler_Y-input"/> + <input semantic="OUTPUT" source="#Cube_rotation_euler_Y-output"/> + <input semantic="INTERPOLATION" source="#Cube_rotation_euler_Y-interpolation"/> + </sampler> + <channel source="#Cube_rotation_euler_Y-sampler" target="Cube/rotationY.ANGLE"/> + </animation> + <animation id="Cube_rotation_euler_Z"> + <source id="Cube_rotation_euler_Z-input"> + <float_array id="Cube_rotation_euler_Z-input-array" count="4">0 0.8333333 1.666667 2.5</float_array> + <technique_common> + <accessor source="#Cube_rotation_euler_Z-input-array" count="4" stride="1"> + <param name="TIME" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cube_rotation_euler_Z-output"> + <float_array id="Cube_rotation_euler_Z-output-array" count="4">0 -120 -240 -360</float_array> + <technique_common> + <accessor source="#Cube_rotation_euler_Z-output-array" count="4" stride="1"> + <param name="ANGLE" type="float"/> + </accessor> + </technique_common> + </source> + <source id="Cube_rotation_euler_Z-interpolation"> + <Name_array id="Cube_rotation_euler_Z-interpolation-array" count="4">LINEAR LINEAR LINEAR LINEAR</Name_array> + <technique_common> + <accessor source="#Cube_rotation_euler_Z-interpolation-array" count="4" stride="1"> + <param name="INTERPOLATION" type="name"/> + </accessor> + </technique_common> + </source> + <sampler id="Cube_rotation_euler_Z-sampler"> + <input semantic="INPUT" source="#Cube_rotation_euler_Z-input"/> + <input semantic="OUTPUT" source="#Cube_rotation_euler_Z-output"/> + <input semantic="INTERPOLATION" source="#Cube_rotation_euler_Z-interpolation"/> + </sampler> + <channel source="#Cube_rotation_euler_Z-sampler" target="Cube/rotationZ.ANGLE"/> + </animation> + </library_animations> + <library_controllers/> + <library_visual_scenes> + <visual_scene id="Scene" name="Scene"> + <node id="GearBottom" name="GearBottom" type="NODE"> + <translate sid="location">0 0 2.19514</translate> + <rotate sid="rotationZ">0 0 1 0</rotate> + <rotate sid="rotationY">0 1 0 0</rotate> + <rotate sid="rotationX">1 0 0 180</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#Cylinder_005-mesh" name="GearBottom"> + <bind_material> + <technique_common> + <instance_material symbol="Material_001-material" target="#Material_001-material"/> + </technique_common> + </bind_material> + </instance_geometry> + </node> + <node id="Cube" name="Cube" type="NODE"> + <translate sid="location">0 0 3.419647</translate> + <rotate sid="rotationZ">0 0 1 0</rotate> + <rotate sid="rotationY">0 1 0 0</rotate> + <rotate sid="rotationX">1 0 0 0</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#Cube-mesh" name="Cube"/> + <node id="GearTop" name="GearTop" type="NODE"> + <translate sid="location">0 0 1.179928</translate> + <rotate sid="rotationZ">0 0 1 0</rotate> + <rotate sid="rotationY">0 1 0 0</rotate> + <rotate sid="rotationX">1 0 0 0</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#Cylinder_001-mesh" name="GearTop"> + <bind_material> + <technique_common> + <instance_material symbol="Material_001-material" target="#Material_001-material"/> + </technique_common> + </bind_material> + </instance_geometry> + </node> + <node id="GearLeft" name="GearLeft" type="NODE"> + <translate sid="location">-1.1934 0 -0.01806307</translate> + <rotate sid="rotationZ">0 0 1 0</rotate> + <rotate sid="rotationY">0 1 0 0</rotate> + <rotate sid="rotationX">1 0 0 0</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#Cylinder_003-mesh" name="GearLeft"> + <bind_material> + <technique_common> + <instance_material symbol="Material_002-material" target="#Material_002-material"/> + </technique_common> + </bind_material> + </instance_geometry> + </node> + <node id="GearRight" name="GearRight" type="NODE"> + <translate sid="location">1.176492 0 -0.01806307</translate> + <rotate sid="rotationZ">0 0 1 0</rotate> + <rotate sid="rotationY">0 1 0 0</rotate> + <rotate sid="rotationX">1 0 0 0</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#Cylinder_004-mesh" name="GearRight"> + <bind_material> + <technique_common> + <instance_material symbol="Material-material" target="#Material-material"/> + </technique_common> + </bind_material> + </instance_geometry> + </node> + <node id="GearTop_001" name="GearTop_001" type="NODE"> + <translate sid="location">-0.6745979 2.553027 -1.187106</translate> + <rotate sid="rotationZ">0 0 1 0</rotate> + <rotate sid="rotationY">0 1 0 0</rotate> + <rotate sid="rotationX">1 0 0 0</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#Cylinder_006-mesh" name="GearTop_001"> + <bind_material> + <technique_common> + <instance_material symbol="Material_001-material" target="#Material_001-material"/> + </technique_common> + </bind_material> + </instance_geometry> + </node> + </node> + </visual_scene> + </library_visual_scenes> + <scene> + <instance_visual_scene url="#Scene"/> + </scene> +</COLLADA>
\ No newline at end of file diff --git a/tests/manual/anim-viewer/main.cpp b/tests/manual/anim-viewer/main.cpp new file mode 100644 index 000000000..4110cca0f --- /dev/null +++ b/tests/manual/anim-viewer/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <Qt3DQuickExtras/qt3dquickwindow.h> + +#include <QGuiApplication> +#include <QQuickView> + +int main(int argc, char* argv[]) +{ + QGuiApplication app(argc, argv); + QQuickView view; + + view.setSource(QUrl("qrc:/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/anim-viewer/main.qml b/tests/manual/anim-viewer/main.qml new file mode 100644 index 000000000..95a4900e3 --- /dev/null +++ b/tests/manual/anim-viewer/main.qml @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 as Quick +import QtQuick.Layouts 1.3 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 + +import Qt3D.Core 2.0 +import Qt3D.Render 2.0 +import Qt3D.Input 2.0 +import Qt3D.Extras 2.2 +import QtQuick.Scene3D 2.0 + + +Quick.Item { + + width: 1250 + height: 900 + + ColumnLayout { + + anchors.fill: parent + anchors.margins: 0 + + Quick.Rectangle { + id: background + width: 1250 + height: 700 + + color: "red" + + Scene3D { + + anchors.fill: parent + multisample: true + focus: true + + aspects: ["input", "logic"] + + Entity { + components: [ + RenderSettings { + activeFrameGraph: ForwardRenderer { + clearColor: Qt.rgba(0, 0.5, 1, 1) + camera: camera + } + }, + // Event Source will be set by the Qt3DQuickWindow + InputSettings { } + ] + + Camera { + id: camera + projectionType: CameraLens.PerspectiveProjection + fieldOfView: 45 + aspectRatio: 16/9 + nearPlane : 0.1 + farPlane : 1000.0 + position: Qt.vector3d( 0.0, 1.0, 10.0 ) + upVector: Qt.vector3d( 0.0, 1.0, 0.0 ) + viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 ) + } + + FirstPersonCameraController { + camera: camera + } + + Entity { + id: scene2 + components: [ + Transform { + scale: 0.2 + translation: Qt.vector3d(0.0, 0.0, 0.0) + }, + SceneLoader { + id: animEntity + source: "qrc:/assets/gears.dae" + + AnimationController { + id: animator + property bool initialized : false + onPositionChanged: { + slider.value = position + } + } + Quick.PropertyAnimation { + id: animPosition + target: animator + property: "position" + loops: Quick.Animation.Infinite + from: 0.0 + } + onStatusChanged: { + console.log(status) + if (status === SceneLoader.Ready) { + + animator.entity = null + animator.entity = scene2 + animator.activeAnimationGroup = 0 + var group = animator.getGroup(0) + animPosition.to = group.duration + animPosition.duration = group.duration * 1000 + slider.maximumValue = group.duration + + var animList = [] + var groups = animator.animationGroups + for (var i = 0; i < groups.length; i++) { + if (groups[i].name === "") + groups[i].name = "UnnamedAnim" + i; + animList.push(groups[i].name) + } + comboBox.model = animList + + animator.initialized = true + comboBox.currentIndex = 0 + } + } + } + ] + } + } + } + } + + ComboBox { + id: animationSelector + anchors.topMargin: 10 + anchors.top: background.bottom + implicitWidth: 400 + model: [ "Gears", "Blend Shape" ] + onCurrentIndexChanged: { + + if (animPosition.running) { + animPosition.stop() + animator.position = 0 + slider.value = 0 + } + + if (currentText === "Gears" && animEntity.source !== "qrc:/assets/gears.dae") + animEntity.source = "qrc:/assets/gears.dae" + else if (currentText === "Blend Shape" + && animEntity.source !== "qrc:/assets/blendshapeanimation.dae") { + animEntity.source = "qrc:/assets/blendshapeanimation.dae" + } + } + } + + ComboBox { + id: comboBox + anchors.topMargin: 10 + anchors.top: animationSelector.bottom + implicitWidth: 400 + onCurrentIndexChanged: { + if (animator.initialized) { + animator.activeAnimationGroup = currentIndex + var group = animator.getGroup(currentIndex) + animPosition.to = group.duration + animPosition.duration = group.duration * 1000 + slider.maximumValue = group.duration + } + } + } + + RowLayout { + anchors.left: parent.left + + Button { + text: "play" + onClicked: { + if (!animPosition.running || animPosition.paused) + animPosition.start() + } + } + Button { + text: "stop" + onClicked: { + if (animPosition.running) { + animPosition.stop() + animator.position = 0 + slider.value = 0 + } + } + } + Button { + text: "pause" + onClicked: { + if (!animPosition.paused && animPosition.running) + animPosition.pause() + } + } + } + Slider { + id: slider + anchors.bottomMargin: 10 + anchors.left: parent.left + anchors.right: parent.right + value: 0.0 + onValueChanged: { + if (pressed) { + animPosition.stop() + animator.position = value + } + } + } + } +} diff --git a/tests/manual/anim-viewer/qml.qrc b/tests/manual/anim-viewer/qml.qrc new file mode 100644 index 000000000..d6fe69605 --- /dev/null +++ b/tests/manual/anim-viewer/qml.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>assets/gears.dae</file> + <file>assets/blendshapeanimation.dae</file> + </qresource> +</RCC> diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index a2ca61758..0c42b72f0 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -38,7 +38,9 @@ SUBDIRS += \ rendercapture-qml \ additional-attributes-qml \ dynamic-model-loader-qml \ - animation-keyframe-simple + animation-keyframe-simple \ + mesh-morphing \ + anim-viewer qtHaveModule(widgets): { SUBDIRS += \ diff --git a/tests/manual/mesh-morphing/main.cpp b/tests/manual/mesh-morphing/main.cpp new file mode 100644 index 000000000..4ae791181 --- /dev/null +++ b/tests/manual/mesh-morphing/main.cpp @@ -0,0 +1,180 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt3D module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QPropertyAnimation> + +#include <Qt3DInput/QInputAspect> + +#include <Qt3DRender/qcamera.h> +#include <Qt3DExtras/qcylindermesh.h> +#include <Qt3DExtras/QPhongMaterial> +#include <Qt3DExtras/QMorphPhongMaterial> +#include <Qt3DExtras/QVertexBlendAnimation> +#include <Qt3DExtras/QMorphTarget> +#include <Qt3DExtras/QCylinderGeometry> + +#include <Qt3DCore/qentity.h> +#include <Qt3DCore/qtransform.h> +#include <Qt3DCore/qaspectengine.h> + +#include <Qt3DExtras/qt3dwindow.h> +#include <Qt3DExtras/QForwardRenderer> +#include <Qt3DExtras/qfirstpersoncameracontroller.h> + +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + Qt3DExtras::Qt3DWindow view; + + // Root entity + Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); + + // Camera + Qt3DRender::QCamera *camera = view.camera(); + camera->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f); + camera->setPosition(QVector3D(0, 2, 20.0f)); + camera->setUpVector(QVector3D(0, 1, 0)); + camera->setViewCenter(QVector3D(0, 0, 0)); + + // For camera controls + Qt3DExtras::QFirstPersonCameraController *cameraController + = new Qt3DExtras::QFirstPersonCameraController(rootEntity); + cameraController->setCamera(camera); + + view.defaultFrameGraph()->setCamera(camera); + view.defaultFrameGraph()->setClearColor(Qt::gray); + + // Transform for mesh + Qt3DCore::QTransform *transform = new Qt3DCore::QTransform; + transform->setTranslation(QVector3D(0,-1,-1)); + + // Base mesh to morph + Qt3DExtras::QCylinderMesh *mesh = new Qt3DExtras::QCylinderMesh(rootEntity); + mesh->setRings(6); + mesh->setSlices(20); + + // create morh targets from geometry + Qt3DExtras::QCylinderGeometry *cylinder1 = new Qt3DExtras::QCylinderGeometry(rootEntity); + Qt3DExtras::QCylinderGeometry *cylinder2 = new Qt3DExtras::QCylinderGeometry(rootEntity); + Qt3DExtras::QCylinderGeometry *cylinder3 = new Qt3DExtras::QCylinderGeometry(rootEntity); + + cylinder1->setRings(6); + cylinder1->setSlices(20); + cylinder1->setLength(2.0f); + cylinder1->setRadius(1.0f); + + cylinder2->setRings(6); + cylinder2->setSlices(20); + cylinder2->setLength(1.0f); + cylinder2->setRadius(5.0f); + + cylinder3->setRings(6); + cylinder3->setSlices(20); + cylinder3->setLength(9.0f); + cylinder3->setRadius(1.0f); + + QStringList attributes; + attributes.push_back(Qt3DRender::QAttribute::defaultPositionAttributeName()); + attributes.push_back(Qt3DRender::QAttribute::defaultNormalAttributeName()); + + QVector<Qt3DExtras::QMorphTarget*> morphTargets; + morphTargets.push_back(Qt3DExtras::QMorphTarget::fromGeometry(cylinder1, attributes)); + morphTargets.push_back(Qt3DExtras::QMorphTarget::fromGeometry(cylinder2, attributes)); + morphTargets.push_back(Qt3DExtras::QMorphTarget::fromGeometry(cylinder3, attributes)); + morphTargets.push_back(morphTargets.first()); + + Qt3DExtras::QVertexBlendAnimation *animation = new Qt3DExtras::QVertexBlendAnimation; + QVector<float> times; + times.push_back(0.0f); + times.push_back(5.0f); + times.push_back(8.0f); + times.push_back(12.0f); + + animation->setTargetPositions(times); + animation->setTarget(mesh); + animation->setMorphTargets(morphTargets); + + // Material + Qt3DExtras::QMorphPhongMaterial *material = new Qt3DExtras::QMorphPhongMaterial(rootEntity); + material->setDiffuse(Qt::red); + + QObject::connect(animation, &Qt3DExtras::QVertexBlendAnimation::interpolatorChanged, + material, &Qt3DExtras::QMorphPhongMaterial::setInterpolator); + + // Cylinder + Qt3DCore::QEntity *morphingEntity = new Qt3DCore::QEntity(rootEntity); + morphingEntity->addComponent(mesh); + morphingEntity->addComponent(transform); + morphingEntity->addComponent(material); + + // Cylinder shape data + Qt3DExtras::QCylinderMesh *cylinderMesh = new Qt3DExtras::QCylinderMesh(); + cylinderMesh->setRadius(1); + cylinderMesh->setLength(3); + cylinderMesh->setRings(100); + cylinderMesh->setSlices(20); + + // Transform for cylinder + Qt3DCore::QTransform *cylinderTransform = new Qt3DCore::QTransform; + cylinderTransform->setScale(0.5f); + cylinderTransform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 45.0f)); + + // Material + Qt3DExtras::QPhongMaterial *cylinderMaterial = new Qt3DExtras::QPhongMaterial(rootEntity); + cylinderMaterial->setDiffuse(Qt::red); + + // Cylinder + Qt3DCore::QEntity *cylinder = new Qt3DCore::QEntity(rootEntity); + cylinder->addComponent(cylinderMesh); + cylinder->addComponent(cylinderTransform); + cylinder->addComponent(cylinderMaterial); + + QPropertyAnimation* anim = new QPropertyAnimation(animation); + anim->setDuration(5000); + anim->setEndValue(QVariant::fromValue(12.0f)); + anim->setStartValue(QVariant::fromValue(0.0f)); + anim->setLoopCount(-1); + anim->setTargetObject(animation); + anim->setPropertyName("position"); + anim->start(); + + // Set root object of the scene + view.setRootEntity(rootEntity); + view.show(); + + return app.exec(); +} diff --git a/tests/manual/mesh-morphing/mesh-morphing.pro b/tests/manual/mesh-morphing/mesh-morphing.pro new file mode 100644 index 000000000..ad2a31b8b --- /dev/null +++ b/tests/manual/mesh-morphing/mesh-morphing.pro @@ -0,0 +1,10 @@ +!include( ../manual.pri ) { + error( "Couldn't find the manual.pri file!" ) +} + +QT += 3dcore 3drender 3dquick 3dinput quick qml 3dextras 3dquickextras + +SOURCES += \ + main.cpp + +RESOURCES += diff --git a/tests/manual/mesh-morphing/mesh-morphing.qrc b/tests/manual/mesh-morphing/mesh-morphing.qrc new file mode 100644 index 000000000..7646d2b36 --- /dev/null +++ b/tests/manual/mesh-morphing/mesh-morphing.qrc @@ -0,0 +1 @@ +<RCC/> |