svn merge -r 13452:14721 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / gameengine / Ketsji / KX_SG_NodeRelationships.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL 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.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU 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 Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include "KX_SG_NodeRelationships.h"
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 /**
36  * Implementation of classes defined in KX_SG_NodeRelationships.h
37  */
38
39 /** 
40  * first of all KX_NormalParentRelation
41  */
42
43         KX_NormalParentRelation *
44 KX_NormalParentRelation::
45 New(
46 ) {
47         return new KX_NormalParentRelation();
48 }               
49
50         bool
51 KX_NormalParentRelation::
52 UpdateChildCoordinates(
53         SG_Spatial * child,
54         const SG_Spatial * parent
55 ){
56         MT_assert(child != NULL);
57
58         // This way of accessing child coordinates is a bit cumbersome
59         // be nice to have non constant reference access to these values.
60
61         const MT_Vector3 & child_scale = child->GetLocalScale();
62         const MT_Point3 & child_pos = child->GetLocalPosition();
63         const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
64
65         // the childs world locations which we will update.     
66         
67         MT_Vector3 child_w_scale;
68         MT_Point3 child_w_pos;
69         MT_Matrix3x3 child_w_rotation;
70                 
71         if (parent) {
72
73                 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
74                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
75                 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
76
77                 child_w_scale = p_world_scale * child_scale;
78                 child_w_rotation = p_world_rotation * child_rotation;
79
80                 child_w_pos = p_world_pos + p_world_scale * 
81                         (p_world_rotation * child_pos);
82                 
83         } else {
84
85                 child_w_scale = child_scale;
86                 child_w_pos = child_pos;
87                 child_w_rotation = child_rotation;
88         }
89
90         child->SetWorldScale(child_w_scale);
91         child->SetWorldPosition(child_w_pos);
92         child->SetWorldOrientation(child_w_rotation);
93         
94         return parent != NULL;
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         bool
134 KX_VertexParentRelation::
135 UpdateChildCoordinates(
136         SG_Spatial * child,
137         const SG_Spatial * parent
138 ){
139
140         MT_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(); /*unused*/
158                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
159                 // const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); /*unused*/
160
161                 child_w_scale = child_scale;
162                 child_w_rotation = child_rotation;
163                 child_w_pos = p_world_pos + child_pos;
164         } else {
165
166                 child_w_scale = child_scale;
167                 child_w_pos = child_pos;
168                 child_w_rotation = child_rotation;
169         }
170
171         child->SetWorldScale(child_w_scale);
172         child->SetWorldPosition(child_w_pos);
173         child->SetWorldOrientation(child_w_rotation);
174         
175         return parent != NULL;
176 }
177
178 /** 
179  * Method inherited from KX_ParentRelation
180  */
181
182         SG_ParentRelation *
183 KX_VertexParentRelation::
184 NewCopy(
185 ){
186         return new KX_VertexParentRelation();
187 };
188
189 KX_VertexParentRelation::
190 ~KX_VertexParentRelation(
191 ){
192         //nothing to do
193 }
194
195
196 KX_VertexParentRelation::
197 KX_VertexParentRelation(
198 ){
199         //nothing to do
200 }
201
202
203 /**
204  * Slow parent relationship
205  */
206
207         KX_SlowParentRelation *
208 KX_SlowParentRelation::
209 New(
210         MT_Scalar relaxation
211 ){
212         return new      KX_SlowParentRelation(relaxation);
213 }       
214
215 /** 
216  * Method inherited from KX_ParentRelation
217  */
218
219         bool
220 KX_SlowParentRelation::
221 UpdateChildCoordinates(
222         SG_Spatial * child,
223         const SG_Spatial * parent
224 ){
225         MT_assert(child != NULL);
226
227         const MT_Vector3 & child_scale = child->GetLocalScale();
228         const MT_Point3 & child_pos = child->GetLocalPosition();
229         const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
230
231         // the childs world locations which we will update.     
232         
233         MT_Vector3 child_w_scale;
234         MT_Point3 child_w_pos;
235         MT_Matrix3x3 child_w_rotation;
236                 
237         if (parent) {
238
239                 // This is a slow parent relation
240                 // first compute the normal child world coordinates.
241
242                 MT_Vector3 child_n_scale;
243                 MT_Point3 child_n_pos;
244                 MT_Matrix3x3 child_n_rotation;
245
246                 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
247                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
248                 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
249
250                 child_n_scale = p_world_scale * child_scale;
251                 child_n_rotation = p_world_rotation * child_rotation;
252
253                 child_n_pos = p_world_pos + p_world_scale * 
254                         (p_world_rotation * child_pos);
255
256
257                 if (m_initialized) {
258
259                         // get the current world positions
260
261                         child_w_scale = child->GetWorldScaling();
262                         child_w_pos = child->GetWorldPosition();
263                         child_w_rotation = child->GetWorldOrientation();        
264
265                         // now 'interpolate' the normal coordinates with the last 
266                         // world coordinates to get the new world coordinates.
267
268                         // problem 1:
269                         // The child world scale needs to be initialized in some way for this 
270                         // to make sense
271                         // problem 2:
272                         // This is way of doing interpolation is nonsense
273
274                         int i;
275
276                         MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
277                         for (i=0;i <3 ;i++) {
278                                 child_w_scale[i] = (m_relax * child_w_scale[i] + child_n_scale[i]) * weight;
279                                 child_w_pos[i] = (m_relax * child_w_pos[i] + child_n_pos[i]) * weight;
280                                 child_w_rotation[0][i] = (m_relax * child_w_rotation[0][i] + child_n_rotation[0][i]) * weight;
281                                 child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight;
282                                 child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight;
283                         }
284                         
285                         //FIXME: update physics controller.
286                 } else {
287                         child_w_scale = child_n_scale;
288                         child_w_pos = child_n_pos;
289                         child_w_rotation = child_n_rotation;
290                         m_initialized = true;
291                 }
292                         
293         } else {
294
295                 child_w_scale = child_scale;
296                 child_w_pos = child_pos;
297                 child_w_rotation = child_rotation;
298         }
299
300         child->SetWorldScale(child_w_scale);
301         child->SetWorldPosition(child_w_pos);
302         child->SetWorldOrientation(child_w_rotation);
303         
304         return parent != NULL;
305 }
306
307 /** 
308  * Method inherited from KX_ParentRelation
309  */
310
311         SG_ParentRelation *
312 KX_SlowParentRelation::
313 NewCopy(
314 ){
315         return new      KX_SlowParentRelation(m_relax);
316 }
317
318 KX_SlowParentRelation::
319 KX_SlowParentRelation(
320         MT_Scalar relaxation
321 ):
322         m_relax(relaxation),
323         m_initialized(false)
324 {
325         //nothing to do
326 }
327
328 KX_SlowParentRelation::
329 ~KX_SlowParentRelation(
330 ){
331         //nothing to do
332 }
333
334
335
336