Big patches:
[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         bool
54 KX_NormalParentRelation::
55 UpdateChildCoordinates(
56         SG_Spatial * child,
57         const SG_Spatial * parent
58 ){
59         MT_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                 
86         } else {
87
88                 child_w_scale = child_scale;
89                 child_w_pos = child_pos;
90                 child_w_rotation = child_rotation;
91         }
92
93         child->SetWorldScale(child_w_scale);
94         child->SetWorldPosition(child_w_pos);
95         child->SetWorldOrientation(child_w_rotation);
96         
97         return parent != NULL;
98 }
99
100         SG_ParentRelation *
101 KX_NormalParentRelation::
102 NewCopy(
103 ){
104         return new KX_NormalParentRelation();
105 }
106
107 KX_NormalParentRelation::
108 ~KX_NormalParentRelation(
109 ){
110         //nothing to do
111 }
112
113
114 KX_NormalParentRelation::
115 KX_NormalParentRelation(
116 ){
117         // nothing to do
118 }
119
120 /** 
121  * Next KX_VertexParentRelation
122  */
123
124
125         KX_VertexParentRelation *
126 KX_VertexParentRelation::
127 New(
128 ){
129         return new KX_VertexParentRelation();
130 }
131                 
132 /** 
133  * Method inherited from KX_ParentRelation
134  */
135
136         bool
137 KX_VertexParentRelation::
138 UpdateChildCoordinates(
139         SG_Spatial * child,
140         const SG_Spatial * parent
141 ){
142
143         MT_assert(child != NULL);
144
145         const MT_Vector3 & child_scale = child->GetLocalScale();
146         const MT_Point3 & child_pos = child->GetLocalPosition();
147         const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
148
149         // the childs world locations which we will update.     
150         
151         MT_Vector3 child_w_scale;
152         MT_Point3 child_w_pos;
153         MT_Matrix3x3 child_w_rotation;
154                 
155         if (parent) {
156
157                 // This is a vertex parent so we do not inherit orientation 
158                 // information.
159
160                 // const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); /*unused*/
161                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
162                 // const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); /*unused*/
163
164                 child_w_scale = child_scale;
165                 child_w_rotation = child_rotation;
166                 child_w_pos = p_world_pos + child_pos;
167         } else {
168
169                 child_w_scale = child_scale;
170                 child_w_pos = child_pos;
171                 child_w_rotation = child_rotation;
172         }
173
174         child->SetWorldScale(child_w_scale);
175         child->SetWorldPosition(child_w_pos);
176         child->SetWorldOrientation(child_w_rotation);
177         
178         return parent != NULL;
179 }
180
181 /** 
182  * Method inherited from KX_ParentRelation
183  */
184
185         SG_ParentRelation *
186 KX_VertexParentRelation::
187 NewCopy(
188 ){
189         return new KX_VertexParentRelation();
190 };
191
192 KX_VertexParentRelation::
193 ~KX_VertexParentRelation(
194 ){
195         //nothing to do
196 }
197
198
199 KX_VertexParentRelation::
200 KX_VertexParentRelation(
201 ){
202         //nothing to do
203 }
204
205
206 /**
207  * Slow parent relationship
208  */
209
210         KX_SlowParentRelation *
211 KX_SlowParentRelation::
212 New(
213         MT_Scalar relaxation
214 ){
215         return new      KX_SlowParentRelation(relaxation);
216 }       
217
218 /** 
219  * Method inherited from KX_ParentRelation
220  */
221
222         bool
223 KX_SlowParentRelation::
224 UpdateChildCoordinates(
225         SG_Spatial * child,
226         const SG_Spatial * parent
227 ){
228         MT_assert(child != NULL);
229
230         const MT_Vector3 & child_scale = child->GetLocalScale();
231         const MT_Point3 & child_pos = child->GetLocalPosition();
232         const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
233
234         // the childs world locations which we will update.     
235         
236         MT_Vector3 child_w_scale;
237         MT_Point3 child_w_pos;
238         MT_Matrix3x3 child_w_rotation;
239                 
240         if (parent) {
241
242                 // This is a slow parent relation
243                 // first compute the normal child world coordinates.
244
245                 MT_Vector3 child_n_scale;
246                 MT_Point3 child_n_pos;
247                 MT_Matrix3x3 child_n_rotation;
248
249                 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
250                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
251                 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
252
253                 child_n_scale = p_world_scale * child_scale;
254                 child_n_rotation = p_world_rotation * child_rotation;
255
256                 child_n_pos = p_world_pos + p_world_scale * 
257                         (p_world_rotation * child_pos);
258
259
260                 if (m_initialized) {
261
262                         // get the current world positions
263
264                         child_w_scale = child->GetWorldScaling();
265                         child_w_pos = child->GetWorldPosition();
266                         child_w_rotation = child->GetWorldOrientation();        
267
268                         // now 'interpolate' the normal coordinates with the last 
269                         // world coordinates to get the new world coordinates.
270
271                         // problem 1:
272                         // The child world scale needs to be initialized in some way for this 
273                         // to make sense
274                         // problem 2:
275                         // This is way of doing interpolation is nonsense
276
277                         int i;
278
279                         MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
280                         for (i=0;i <3 ;i++) {
281                                 child_w_scale[i] = (m_relax * child_w_scale[i] + child_n_scale[i]) * weight;
282                                 child_w_pos[i] = (m_relax * child_w_pos[i] + child_n_pos[i]) * weight;
283                                 child_w_rotation[0][i] = (m_relax * child_w_rotation[0][i] + child_n_rotation[0][i]) * weight;
284                                 child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight;
285                                 child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight;
286                         }
287                         
288                         //FIXME: update physics controller.
289                 } else {
290                         child_w_scale = child_n_scale;
291                         child_w_pos = child_n_pos;
292                         child_w_rotation = child_n_rotation;
293                         m_initialized = true;
294                 }
295                         
296         } else {
297
298                 child_w_scale = child_scale;
299                 child_w_pos = child_pos;
300                 child_w_rotation = child_rotation;
301         }
302
303         child->SetWorldScale(child_w_scale);
304         child->SetWorldPosition(child_w_pos);
305         child->SetWorldOrientation(child_w_rotation);
306         
307         return parent != NULL;
308 }
309
310 /** 
311  * Method inherited from KX_ParentRelation
312  */
313
314         SG_ParentRelation *
315 KX_SlowParentRelation::
316 NewCopy(
317 ){
318         return new      KX_SlowParentRelation(m_relax);
319 }
320
321 KX_SlowParentRelation::
322 KX_SlowParentRelation(
323         MT_Scalar relaxation
324 ):
325         m_relax(relaxation),
326         m_initialized(false)
327 {
328         //nothing to do
329 }
330
331 KX_SlowParentRelation::
332 ~KX_SlowParentRelation(
333 ){
334         //nothing to do
335 }
336
337
338
339