1 /* -*-c++-*-
2  *
3  * Copyright (C) 2006-2007 Mathias Froehlich
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #  include <simgear_config.h>
24 #endif
25 
26 #include <osgDB/Registry>
27 #include <osgDB/Input>
28 #include <osgDB/Output>
29 
30 #include "SGOffsetTransform.hxx"
31 
SGOffsetTransform(double scaleFactor)32 SGOffsetTransform::SGOffsetTransform(double scaleFactor) :
33   _scaleFactor(scaleFactor),
34   _rScaleFactor(1/scaleFactor)
35 {
36 }
37 
SGOffsetTransform(const SGOffsetTransform & offset,const osg::CopyOp & copyop)38 SGOffsetTransform::SGOffsetTransform(const SGOffsetTransform& offset,
39                                      const osg::CopyOp& copyop) :
40     osg::Transform(offset, copyop),
41     _scaleFactor(offset._scaleFactor),
42     _rScaleFactor(offset._rScaleFactor)
43 {
44 }
45 
46 bool
computeLocalToWorldMatrix(osg::Matrix & matrix,osg::NodeVisitor * nv) const47 SGOffsetTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
48                                              osg::NodeVisitor* nv) const
49 {
50   if (nv && nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR) {
51     osg::Vec3 center = nv->getEyePoint();
52     osg::Matrix transform;
53     transform(0,0) = _scaleFactor;
54     transform(1,1) = _scaleFactor;
55     transform(2,2) = _scaleFactor;
56     transform(3,0) = center[0]*(1 - _scaleFactor);
57     transform(3,1) = center[1]*(1 - _scaleFactor);
58     transform(3,2) = center[2]*(1 - _scaleFactor);
59     matrix.preMult(transform);
60   }
61   return true;
62 }
63 
64 bool
computeWorldToLocalMatrix(osg::Matrix & matrix,osg::NodeVisitor * nv) const65 SGOffsetTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
66                                              osg::NodeVisitor* nv) const
67 {
68   if (nv && nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR) {
69     osg::Vec3 center = nv->getEyePoint();
70     osg::Matrix transform;
71     transform(0,0) = _rScaleFactor;
72     transform(1,1) = _rScaleFactor;
73     transform(2,2) = _rScaleFactor;
74     transform(3,0) = center[0]*(1 - _rScaleFactor);
75     transform(3,1) = center[1]*(1 - _rScaleFactor);
76     transform(3,2) = center[2]*(1 - _rScaleFactor);
77     matrix.postMult(transform);
78   }
79   return true;
80 }
81 
82 namespace {
83 
OffsetTransform_readLocalData(osg::Object & obj,osgDB::Input & fr)84 bool OffsetTransform_readLocalData(osg::Object& obj, osgDB::Input& fr)
85 {
86     SGOffsetTransform& offset = static_cast<SGOffsetTransform&>(obj);
87     if (fr[0].matchWord("scaleFactor")) {
88         ++fr;
89         double scaleFactor;
90         if (fr[0].getFloat(scaleFactor))
91             ++fr;
92         else
93             return false;
94         offset.setScaleFactor(scaleFactor);
95     }
96     return true;
97 }
98 
OffsetTransform_writeLocalData(const osg::Object & obj,osgDB::Output & fw)99 bool OffsetTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
100 {
101     const SGOffsetTransform& offset
102         = static_cast<const SGOffsetTransform&>(obj);
103     fw.indent() << "scaleFactor " << offset.getScaleFactor() << std::endl;
104     return true;
105 }
106 
107 }
108 
109 osgDB::RegisterDotOsgWrapperProxy g_SGOffsetTransformProxy
110 (
111     new SGOffsetTransform,
112     "SGOffsetTransform",
113     "Object Node Transform SGOffsetTransform Group",
114     &OffsetTransform_readLocalData,
115     &OffsetTransform_writeLocalData
116 );
117