Last of the config.h mods...
[blender.git] / source / gameengine / Ketsji / KX_SG_NodeRelationships.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31
32 #include "KX_SG_NodeRelationships.h"
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 /**
39  * Implementation of classes defined in KX_SG_NodeRelationships.h
40  */
41
42 /** 
43  * first of all KX_NormalParentRelation
44  */
45
46         KX_NormalParentRelation *
47 KX_NormalParentRelation::
48 New(
49 ) {
50         return new KX_NormalParentRelation();
51 }               
52
53         void
54 KX_NormalParentRelation::
55 UpdateChildCoordinates(
56         SG_Spatial * child,
57         const SG_Spatial * parent
58 ){
59         assert(child != NULL);
60
61         // This way of accessing child coordinates is a bit cumbersome
62         // be nice to have non constant reference access to these values.
63
64         const MT_Vector3 & child_scale = child->GetLocalScale();
65         const MT_Point3 & child_pos = child->GetLocalPosition();
66         const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
67
68         // the childs world locations which we will update.     
69         
70         MT_Vector3 child_w_scale;
71         MT_Point3 child_w_pos;
72         MT_Matrix3x3 child_w_rotation;
73                 
74         if (parent) {
75
76                 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
77                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
78                 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
79
80                 child_w_scale = p_world_scale * child_scale;
81                 child_w_rotation = p_world_rotation * child_rotation;
82
83                 child_w_pos = p_world_pos + p_world_scale * 
84                         (p_world_rotation * child_pos);
85         } else {
86
87                 child_w_scale = child_scale;
88                 child_w_pos = child_pos;
89                 child_w_rotation = child_rotation;
90         }
91
92         child->SetWorldScale(child_w_scale);
93         child->SetWorldPosition(child_w_pos);
94         child->SetWorldOrientation(child_w_rotation);
95 }
96
97         SG_ParentRelation *
98 KX_NormalParentRelation::
99 NewCopy(
100 ){
101         return new KX_NormalParentRelation();
102 }
103
104 KX_NormalParentRelation::
105 ~KX_NormalParentRelation(
106 ){
107         //nothing to do
108 }
109
110
111 KX_NormalParentRelation::
112 KX_NormalParentRelation(
113 ){
114         // nothing to do
115 }
116
117 /** 
118  * Next KX_VertexParentRelation
119  */
120
121
122         KX_VertexParentRelation *
123 KX_VertexParentRelation::
124 New(
125 ){
126         return new KX_VertexParentRelation();
127 }
128                 
129 /** 
130  * Method inherited from KX_ParentRelation
131  */
132
133         void
134 KX_VertexParentRelation::
135 UpdateChildCoordinates(
136         SG_Spatial * child,
137         const SG_Spatial * parent
138 ){
139
140         assert(child != NULL);
141
142         const MT_Vector3 & child_scale = child->GetLocalScale();
143         const MT_Point3 & child_pos = child->GetLocalPosition();
144         const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
145
146         // the childs world locations which we will update.     
147         
148         MT_Vector3 child_w_scale;
149         MT_Point3 child_w_pos;
150         MT_Matrix3x3 child_w_rotation;
151                 
152         if (parent) {
153
154                 // This is a vertex parent so we do not inherit orientation 
155                 // information.
156
157                 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
158                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
159                 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
160
161                 child_w_scale = child_scale;
162                 child_w_rotation = child_rotation;
163                 child_w_pos = p_world_pos + child_pos;
164
165         } else {
166
167                 child_w_scale = child_scale;
168                 child_w_pos = child_pos;
169                 child_w_rotation = child_rotation;
170         }
171
172         child->SetWorldScale(child_w_scale);
173         child->SetWorldPosition(child_w_pos);
174         child->SetWorldOrientation(child_w_rotation);
175 }
176
177 /** 
178  * Method inherited from KX_ParentRelation
179  */
180
181         SG_ParentRelation *
182 KX_VertexParentRelation::
183 NewCopy(
184 ){
185         return new KX_VertexParentRelation();
186 };
187
188 KX_VertexParentRelation::
189 ~KX_VertexParentRelation(
190 ){
191         //nothing to do
192 }
193
194
195 KX_VertexParentRelation::
196 KX_VertexParentRelation(
197 ){
198         //nothing to do
199 }
200
201
202 /**
203  * Slow parent relationship
204  */
205
206         KX_SlowParentRelation *
207 KX_SlowParentRelation::
208 New(
209         MT_Scalar relaxation
210 ){
211         return new      KX_SlowParentRelation(relaxation);
212 }       
213
214 /** 
215  * Method inherited from KX_ParentRelation
216  */
217
218         void
219 KX_SlowParentRelation::
220 UpdateChildCoordinates(
221         SG_Spatial * child,
222         const SG_Spatial * parent
223 ){
224         assert(child != NULL);
225
226         const MT_Vector3 & child_scale = child->GetLocalScale();
227         const MT_Point3 & child_pos = child->GetLocalPosition();
228         const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
229
230         // the childs world locations which we will update.     
231         
232         MT_Vector3 child_w_scale;
233         MT_Point3 child_w_pos;
234         MT_Matrix3x3 child_w_rotation;
235                 
236         if (parent) {
237
238                 // This is a slow parent relation
239                 // first compute the normal child world coordinates.
240
241                 MT_Vector3 child_n_scale;
242                 MT_Point3 child_n_pos;
243                 MT_Matrix3x3 child_n_rotation;
244
245                 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
246                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
247                 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
248
249                 child_n_scale = p_world_scale * child_scale;
250                 child_n_rotation = p_world_rotation * child_rotation;
251
252                 child_n_pos = p_world_pos + p_world_scale * 
253                         (p_world_rotation * child_pos);
254
255
256                 if (m_initialized) {
257
258                         // get the current world positions
259
260                         child_w_scale = child->GetWorldScaling();
261                         child_w_pos = child->GetWorldPosition();
262                         child_w_rotation = child->GetWorldOrientation();        
263
264                         // now 'interpolate' the normal coordinates with the last 
265                         // world coordinates to get the new world coordinates.
266
267                         // problem 1:
268                         // The child world scale needs to be initialized in some way for this 
269                         // to make sense
270                         // problem 2:
271                         // This is way of doing interpolation is nonsense
272
273                         int i;
274
275                         MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
276                         for (i=0;i <3 ;i++) {
277                                 child_w_scale[i] = (m_relax * child_w_scale[i] + child_n_scale[i]) * weight;
278                                 child_w_pos[i] = (m_relax * child_w_pos[i] + child_n_pos[i]) * weight;
279                                 child_w_rotation[0][i] = (m_relax * child_w_rotation[0][i] + child_n_rotation[0][i]) * weight;
280                                 child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight;
281                                 child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight;
282                         }
283                 } else {
284                         child_w_scale = child_n_scale;
285                         child_w_pos = child_n_pos;
286                         child_w_rotation = child_n_rotation;
287                         m_initialized = true;
288                 }
289                         
290         } else {
291
292                 child_w_scale = child_scale;
293                 child_w_pos = child_pos;
294                 child_w_rotation = child_rotation;
295         }
296
297         child->SetWorldScale(child_w_scale);
298         child->SetWorldPosition(child_w_pos);
299         child->SetWorldOrientation(child_w_rotation);
300 }
301
302 /** 
303  * Method inherited from KX_ParentRelation
304  */
305
306         SG_ParentRelation *
307 KX_SlowParentRelation::
308 NewCopy(
309 ){
310         return new      KX_SlowParentRelation(m_relax);
311 }
312
313 KX_SlowParentRelation::
314 KX_SlowParentRelation(
315         MT_Scalar relaxation
316 ):
317         m_relax(relaxation),
318         m_initialized(false)
319 {
320         //nothing to do
321 }
322
323 KX_SlowParentRelation::
324 ~KX_SlowParentRelation(
325 ){
326         //nothing to do
327 }
328
329
330
331