]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/placementtrans.cxx
14d8491b1c1f3d39e9f737a1b5259f33cc2ff9ab
[simgear.git] / simgear / scene / model / placementtrans.cxx
1 // placementtrans.hxx -- class for carrying transforms for placing models in the world
2 //
3 // Written by Mathias Froehlich, started April 2005.
4 //
5 // Copyright (C) 2005 Mathias Froehlich
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21
22 #ifdef HAVE_CONFIG_H
23 #  include <simgear_config.h>
24 #endif
25
26 #ifndef __cplusplus
27 # error This library requires C++
28 #endif
29
30 #include <osgDB/Registry>
31 #include <osgDB/Input>
32 #include <osgDB/Output>
33
34 #include <simgear/compiler.h>
35 #include <simgear/constants.h>
36
37 #include "placementtrans.hxx"
38
39 SGPlacementTransform::SGPlacementTransform(void) :
40   _placement_offset(0, 0, 0),
41   _rotation(SGQuatd::unit())
42 {
43 }
44
45 SGPlacementTransform::SGPlacementTransform(const SGPlacementTransform& trans,
46                                            const osg::CopyOp& copyop):
47   osg::Transform(trans, copyop),
48   _placement_offset(trans._placement_offset),
49   _rotation(trans._rotation)
50 {
51   
52 }
53
54 SGPlacementTransform::~SGPlacementTransform(void)
55 {
56 }
57
58 bool
59 SGPlacementTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
60                                                 osg::NodeVisitor*) const
61 {
62   if (_referenceFrame == RELATIVE_RF) {
63     matrix.preMultTranslate(_placement_offset.osg());
64     matrix.preMultRotate(_rotation.osg());
65   } else {
66     matrix.makeRotate(_rotation.osg());
67     matrix.postMultTranslate(_placement_offset.osg());
68   }
69   return true;
70 }
71
72 bool
73 SGPlacementTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
74                                                 osg::NodeVisitor*) const
75 {
76   if (_referenceFrame == RELATIVE_RF) {
77     matrix.postMultTranslate(-_placement_offset.osg());
78     matrix.postMultRotate(inverse(_rotation).osg());
79   } else {
80     matrix.makeRotate(inverse(_rotation).osg());
81     matrix.preMultTranslate(-_placement_offset.osg());
82   }
83   return true;
84 }
85
86 // Functions to read / write SGPlacementTrans from / to a .osg file,
87 // mostly for debugging purposes.
88
89 namespace {
90
91 bool PlacementTrans_readLocalData(osg::Object& obj, osgDB::Input& fr)
92 {
93     SGPlacementTransform& trans = static_cast<SGPlacementTransform&>(obj);
94     SGQuatd rotation = SGQuatd::unit();
95     SGVec3d placementOffset(0, 0, 0);
96     
97     if (fr[0].matchWord("rotation")) {
98         ++fr;
99         osg::Vec4d vec4;
100         if (fr.readSequence(vec4)) {
101             rotation = SGQuatd(vec4[0], vec4[1], vec4[2], vec4[3]);
102             fr += 4;
103         } else
104             return false;
105     }
106     if (fr[0].matchWord("placement")) {
107         ++fr;
108         if (fr.readSequence(placementOffset.osg()))
109             fr += 3;
110         else
111             return false;
112     }
113     trans.setTransform(placementOffset, rotation);
114     return true;
115 }
116
117 bool PlacementTrans_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
118 {
119     const SGPlacementTransform& trans
120         = static_cast<const SGPlacementTransform&>(obj);
121     const SGQuatd& rotation = trans.getRotation();
122     const SGVec3d& placement = trans.getGlobalPos();
123     
124     fw.indent() << "rotation ";
125     for (int i = 0; i < 4; i++) {
126         fw << rotation(i) << " ";
127     }
128     fw << std::endl;
129     int prec = fw.precision();
130     fw.precision(15);
131     fw.indent() << "placement ";
132     for (int i = 0; i < 3; i++) {
133         fw << placement(i) << " ";
134     }
135     fw << std::endl;
136     fw.precision(prec);
137     return true;
138 }
139 }
140
141 osgDB::RegisterDotOsgWrapperProxy g_SGPlacementTransProxy
142 (
143     new SGPlacementTransform,
144     "SGPlacementTransform",
145     "Object Node Transform SGPlacementTransform Group",
146     &PlacementTrans_readLocalData,
147     &PlacementTrans_writeLocalData
148 );