Initial revision
[blender.git] / source / gameengine / SceneGraph / SG_Spatial.cpp
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include "SG_Node.h"
34 #include "SG_Spatial.h"
35 #include "SG_Controller.h"
36 #include "SG_ParentRelation.h"
37
38 SG_Spatial::
39 SG_Spatial(
40         void* clientobj,
41         void* clientinfo,
42         SG_Callbacks callbacks
43 ): 
44
45         SG_IObject(clientobj,clientinfo,callbacks),
46         m_localPosition(MT_Point3(0,0,0)),
47         m_localScaling(MT_Vector3(1.f,1.f,1.f)),
48         m_localRotation(1,0,0,0,1,0,0,0,1),
49         m_parent_relation (NULL),
50
51         m_worldPosition(MT_Point3(0,0,0)),
52         m_worldScaling(MT_Vector3(1.f,1.f,1.f)),
53         m_worldRotation(0,0,0,0,0,0,0,0,0)
54
55 {
56 }
57
58 SG_Spatial::
59 SG_Spatial(
60         const SG_Spatial& other
61 ) : 
62         SG_IObject(other),
63         m_localPosition(other.m_localPosition),
64         m_localScaling(other.m_localScaling),
65         m_localRotation(other.m_localRotation),
66         m_parent_relation(NULL),
67         m_worldPosition(other.m_worldPosition),
68         m_worldScaling(other.m_worldScaling),
69         m_worldRotation(other.m_worldRotation)
70 {
71         // duplicate the parent relation for this object
72         m_parent_relation = other.m_parent_relation->NewCopy();
73 }
74         
75 SG_Spatial::
76 ~SG_Spatial()
77 {
78         delete (m_parent_relation);
79 }
80
81         void
82 SG_Spatial::
83 SetParentRelation(
84         SG_ParentRelation *relation
85 ){
86         delete (m_parent_relation);
87         m_parent_relation = relation;
88 }
89
90
91 /**
92  * Update Spatial Data.
93  * Calculates WorldTransform., (either doing itsself or using the linked SGControllers)
94  */
95
96
97         void 
98 SG_Spatial::
99 UpdateSpatialData(
100         const SG_Spatial *parent,
101         double time
102 ){
103
104     bool bComputesWorldTransform = false;
105
106         // update spatial controllers
107         
108         SGControllerList::iterator cit = GetSGControllerList().begin();
109         SGControllerList::const_iterator c_end = GetSGControllerList().end();
110
111         for (;cit!=c_end;++cit)
112         {
113                 bComputesWorldTransform = bComputesWorldTransform || (*cit)->Update(time);
114         }
115
116         // If none of the objects updated our values then we ask the
117         // parent_relation object owned by this class to update 
118         // our world coordinates.
119
120         if (!bComputesWorldTransform)
121     {
122                 ComputeWorldTransforms(parent);
123     }
124 }
125
126 void    SG_Spatial::ComputeWorldTransforms(const SG_Spatial *parent)
127 {
128         m_parent_relation->UpdateChildCoordinates(this,parent);
129 }
130
131
132 /**
133  * Position and translation methods
134  */
135
136
137         void 
138 SG_Spatial::
139 RelativeTranslate(
140         const MT_Vector3& trans,
141         const SG_Spatial *parent,
142         bool local
143 ){
144         if (local) {
145                         m_localPosition += m_localRotation * trans;
146         } else {
147                 if (parent) {
148                         m_localPosition += trans * parent->GetWorldOrientation();
149                 } else {
150                         m_localPosition += trans;
151                 }
152         }
153 }       
154         
155         void 
156 SG_Spatial::
157 SetLocalPosition(
158         const MT_Point3& trans
159 ){
160         m_localPosition = trans;
161 }
162
163         void                            
164 SG_Spatial::
165 SetWorldPosition(
166         const MT_Point3& trans
167 ) {
168         m_worldPosition = trans;
169 }
170
171 /**
172  * Scaling methods.
173  */ 
174
175         void 
176 SG_Spatial::
177 RelativeScale(
178         const MT_Vector3& scale
179 ){
180         m_localScaling = m_localScaling * scale;
181 }
182
183         void 
184 SG_Spatial::
185 SetLocalScale(
186         const MT_Vector3& scale
187 ){
188         m_localScaling = scale;
189 }
190
191
192         void                            
193 SG_Spatial::
194 SetWorldScale(
195         const MT_Vector3& scale
196 ){ 
197         m_worldScaling = scale;
198 }
199
200 /**
201  * Orientation and rotation methods.
202  */
203
204
205         void 
206 SG_Spatial::
207 RelativeRotate(
208         const MT_Matrix3x3& rot,
209         bool local
210 ){
211         m_localRotation = m_localRotation * (
212         local ? 
213                 rot 
214         :
215         (GetWorldOrientation().inverse() * rot * GetWorldOrientation()));
216 }
217
218         void 
219 SG_Spatial::
220 SetLocalOrientation(const MT_Matrix3x3& rot)
221 {
222         m_localRotation = rot;
223 }
224
225
226
227         void                            
228 SG_Spatial::
229 SetWorldOrientation(
230         const MT_Matrix3x3& rot
231 ) {
232         m_worldRotation = rot;
233 }
234
235 const 
236         MT_Point3&
237 SG_Spatial::
238 GetLocalPosition(
239 ) const {
240          return m_localPosition;
241 }
242
243 const 
244         MT_Matrix3x3&
245 SG_Spatial::
246 GetLocalOrientation(
247 ) const {
248         return m_localRotation;
249 }
250
251 const 
252         MT_Vector3&     
253 SG_Spatial::
254 GetLocalScale(
255 ) const{
256         return m_localScaling;
257 }
258
259
260 const 
261         MT_Point3&
262 SG_Spatial::
263 GetWorldPosition(
264 ) const {
265         return m_worldPosition;
266 }
267
268 const 
269         MT_Matrix3x3&   
270 SG_Spatial::
271 GetWorldOrientation(
272 ) const {
273         return m_worldRotation;
274 }
275
276 const 
277         MT_Vector3&     
278 SG_Spatial::
279 GetWorldScaling(
280 ) const {
281         return m_worldScaling;
282 }
283