From 5850464ba735bd13f2b1ba55d95a6a1d9c042f63 Mon Sep 17 00:00:00 2001 From: frohlich Date: Mon, 22 Jun 2009 18:39:44 +0000 Subject: [PATCH] Move the carrier interactive geometry configuration into the model files. Modified Files: Makefile.am animation.cxx Added Files: SGInteractionAnimation.hxx SGInteractionAnimation.cxx --- simgear/scene/model/Makefile.am | 2 + .../scene/model/SGInteractionAnimation.cxx | 151 ++++++++++++++++++ .../scene/model/SGInteractionAnimation.hxx | 32 ++++ simgear/scene/model/animation.cxx | 4 + 4 files changed, 189 insertions(+) create mode 100644 simgear/scene/model/SGInteractionAnimation.cxx create mode 100644 simgear/scene/model/SGInteractionAnimation.hxx diff --git a/simgear/scene/model/Makefile.am b/simgear/scene/model/Makefile.am index 3bf59ff0..77845fe4 100644 --- a/simgear/scene/model/Makefile.am +++ b/simgear/scene/model/Makefile.am @@ -14,6 +14,7 @@ include_HEADERS = \ placement.hxx \ CheckSceneryVisitor.hxx \ SGClipGroup.hxx \ + SGInteractionAnimation.hxx \ SGMaterialAnimation.hxx \ SGOffsetTransform.hxx \ SGPagedLOD.hxx \ @@ -34,6 +35,7 @@ libsgmodel_a_SOURCES = \ shadanim.cxx \ CheckSceneryVisitor.cxx \ SGClipGroup.cxx \ + SGInteractionAnimation.cxx \ SGMaterialAnimation.cxx \ SGOffsetTransform.cxx \ SGPagedLOD.cxx \ diff --git a/simgear/scene/model/SGInteractionAnimation.cxx b/simgear/scene/model/SGInteractionAnimation.cxx new file mode 100644 index 00000000..de96c1e4 --- /dev/null +++ b/simgear/scene/model/SGInteractionAnimation.cxx @@ -0,0 +1,151 @@ +// Copyright (C) 2004-2007 Vivian Meazza +// Copyright (C) 2004-2009 Mathias Froehlich - Mathias.Froehlich@web.de +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#include "SGInteractionAnimation.hxx" + +#include +#include +#include + +#include +#include +#include + +class SGInteractionAnimation::LineCollector : public osg::NodeVisitor { + struct LinePrimitiveFunctor { + LinePrimitiveFunctor() : _lineCollector(0) + { } + void operator() (const osg::Vec3&, bool) + { } + void operator() (const osg::Vec3& v1, const osg::Vec3& v2, bool) + { if (_lineCollector) _lineCollector->addLine(v1, v2); } + void operator() (const osg::Vec3&, const osg::Vec3&, const osg::Vec3&, + bool) + { } + void operator() (const osg::Vec3&, const osg::Vec3&, const osg::Vec3&, + const osg::Vec3&, bool) + { } + LineCollector* _lineCollector; + }; + +public: + LineCollector() : + osg::NodeVisitor(osg::NodeVisitor::NODE_VISITOR, + osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) + { } + virtual void apply(osg::Geode& geode) + { + osg::TemplatePrimitiveFunctor pf; + pf._lineCollector = this; + for (unsigned i = 0; i < geode.getNumDrawables(); ++i) { + geode.getDrawable(i)->accept(pf); + } + } + virtual void apply(osg::Node& node) + { + traverse(node); + } + virtual void apply(osg::Transform& transform) + { + osg::Matrix matrix = _matrix; + if (transform.computeLocalToWorldMatrix(_matrix, this)) + traverse(transform); + _matrix = matrix; + } + + const std::vector& getLineSegments() const + { return _lineSegments; } + + void addLine(const osg::Vec3& v1, const osg::Vec3& v2) + { + // Trick to get the ends in the right order. + // Use the x axis in the original coordinate system. Choose the + // most negative x-axis as the one pointing forward + SGVec3f tv1(_matrix.preMult(v1)); + SGVec3f tv2(_matrix.preMult(v2)); + if (tv1[0] > tv2[0]) + _lineSegments.push_back(SGLineSegmentf(tv1, tv2)); + else + _lineSegments.push_back(SGLineSegmentf(tv2, tv1)); + } + + void addBVHElements(osg::Node& node, simgear::BVHLineGeometry::Type type) + { + if (_lineSegments.empty()) + return; + + SGSceneUserData* userData; + userData = SGSceneUserData::getOrCreateSceneUserData(&node); + + simgear::BVHNode* bvNode = userData->getBVHNode(); + if (!bvNode && _lineSegments.size() == 1) { + simgear::BVHLineGeometry* bvLine; + bvLine = new simgear::BVHLineGeometry(_lineSegments.front(), type); + userData->setBVHNode(bvLine); + return; + } + + simgear::BVHGroup* group = new simgear::BVHGroup; + if (bvNode) + group->addChild(bvNode); + + for (unsigned i = 0; i < _lineSegments.size(); ++i) { + simgear::BVHLineGeometry* bvLine; + bvLine = new simgear::BVHLineGeometry(_lineSegments[i], type); + group->addChild(bvLine); + } + userData->setBVHNode(group); + } + +private: + osg::Matrix _matrix; + std::vector _lineSegments; +}; + +SGInteractionAnimation::SGInteractionAnimation(const SGPropertyNode* configNode, + SGPropertyNode* modelRoot) : + SGAnimation(configNode, modelRoot) +{ +} + +void +SGInteractionAnimation::install(osg::Node& node) +{ + SGAnimation::install(node); + + if (!getConfig()->hasChild("type")) + return; + std::string interactionType; + interactionType = getConfig()->getStringValue("interaction-type", ""); + + LineCollector lineCollector; + node.accept(lineCollector); + + if (interactionType == "carrier-catapult") { + lineCollector.addBVHElements(node, + simgear::BVHLineGeometry::CarrierCatapult); + } else if (interactionType == "carrier-wire") { + lineCollector.addBVHElements(node, + simgear::BVHLineGeometry::CarrierWire); + } else { + SG_LOG(SG_IO, SG_ALERT, "Unknown interaction animation " + "interaction-type \"" << interactionType << "\". Ignoring!"); + } +} + + diff --git a/simgear/scene/model/SGInteractionAnimation.hxx b/simgear/scene/model/SGInteractionAnimation.hxx new file mode 100644 index 00000000..3b3ab6ec --- /dev/null +++ b/simgear/scene/model/SGInteractionAnimation.hxx @@ -0,0 +1,32 @@ +// Copyright (C) 2009 Mathias Froehlich - Mathias.Froehlich@web.de +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#ifndef _SG_SGINTERACTIONANIMATION_HXX +#define _SG_SGINTERACTIONANIMATION_HXX 1 + +#include "animation.hxx" + +class SGInteractionAnimation : public SGAnimation { +public: + SGInteractionAnimation(const SGPropertyNode* configNode, + SGPropertyNode* modelRoot); + virtual void install(osg::Node& node); +private: + class LineCollector; +}; + +#endif diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index cb5b0eee..10b1b66d 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -46,6 +46,7 @@ #include "SGMaterialAnimation.hxx" #include "SGRotateTransform.hxx" #include "SGScaleTransform.hxx" +#include "SGInteractionAnimation.hxx" using OpenThreads::Mutex; using OpenThreads::ReentrantMutex; @@ -401,6 +402,9 @@ SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode, } else if (type == "flash") { SGFlashAnimation animInst(configNode, modelRoot); animInst.apply(node); + } else if (type == "interaction") { + SGInteractionAnimation animInst(configNode, modelRoot); + animInst.apply(node); } else if (type == "material") { SGMaterialAnimation animInst(configNode, modelRoot, options); animInst.apply(node); -- 2.39.5