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