3 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
19 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20 * All rights reserved.
22 * The Original Code is: all of this file.
24 * Contributor(s): none yet.
26 * ***** END GPL LICENSE BLOCK *****
29 #include "KX_SG_NodeRelationships.h"
36 * Implementation of classes defined in KX_SG_NodeRelationships.h
40 * first of all KX_NormalParentRelation
43 KX_NormalParentRelation *
44 KX_NormalParentRelation::
47 return new KX_NormalParentRelation();
51 KX_NormalParentRelation::
52 UpdateChildCoordinates(
54 const SG_Spatial * parent,
57 MT_assert(child != NULL);
59 if (!parentUpdated && !child->IsModified())
64 if (parent==NULL) { /* Simple case */
65 child->SetWorldFromLocalTransform();
66 child->SetModified(false);
70 // the childs world locations which we will update.
71 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
72 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
73 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
75 child->SetWorldScale(p_world_scale * child->GetLocalScale());
76 child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation());
77 child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition()));
78 child->SetModified(false);
84 KX_NormalParentRelation::
87 return new KX_NormalParentRelation();
90 KX_NormalParentRelation::
91 ~KX_NormalParentRelation(
97 KX_NormalParentRelation::
98 KX_NormalParentRelation(
104 * Next KX_VertexParentRelation
108 KX_VertexParentRelation *
109 KX_VertexParentRelation::
112 return new KX_VertexParentRelation();
116 * Method inherited from KX_ParentRelation
120 KX_VertexParentRelation::
121 UpdateChildCoordinates(
123 const SG_Spatial * parent,
127 MT_assert(child != NULL);
129 if (!parentUpdated && !child->IsModified())
132 child->SetWorldScale(child->GetLocalScale());
135 child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition());
137 child->SetWorldPosition(child->GetLocalPosition());
139 child->SetWorldOrientation(child->GetLocalOrientation());
140 child->SetModified(false);
141 return true; //parent != NULL;
145 * Method inherited from KX_ParentRelation
149 KX_VertexParentRelation::
152 return new KX_VertexParentRelation();
155 KX_VertexParentRelation::
156 ~KX_VertexParentRelation(
162 KX_VertexParentRelation::
163 KX_VertexParentRelation(
170 * Slow parent relationship
173 KX_SlowParentRelation *
174 KX_SlowParentRelation::
178 return new KX_SlowParentRelation(relaxation);
182 * Method inherited from KX_ParentRelation
186 KX_SlowParentRelation::
187 UpdateChildCoordinates(
189 const SG_Spatial * parent,
192 MT_assert(child != NULL);
194 // the child will move even if the parent is not
195 parentUpdated = true;
197 const MT_Vector3 & child_scale = child->GetLocalScale();
198 const MT_Point3 & child_pos = child->GetLocalPosition();
199 const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
201 // the childs world locations which we will update.
203 MT_Vector3 child_w_scale;
204 MT_Point3 child_w_pos;
205 MT_Matrix3x3 child_w_rotation;
209 // This is a slow parent relation
210 // first compute the normal child world coordinates.
212 MT_Vector3 child_n_scale;
213 MT_Point3 child_n_pos;
214 MT_Matrix3x3 child_n_rotation;
216 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
217 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
218 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
220 child_n_scale = p_world_scale * child_scale;
221 child_n_rotation = p_world_rotation * child_rotation;
223 child_n_pos = p_world_pos + p_world_scale *
224 (p_world_rotation * child_pos);
229 // get the current world positions
231 child_w_scale = child->GetWorldScaling();
232 child_w_pos = child->GetWorldPosition();
233 child_w_rotation = child->GetWorldOrientation();
235 // now 'interpolate' the normal coordinates with the last
236 // world coordinates to get the new world coordinates.
239 // The child world scale needs to be initialized in some way for this
242 // This is way of doing interpolation is nonsense
246 MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
247 for (i=0;i <3 ;i++) {
248 child_w_scale[i] = (m_relax * child_w_scale[i] + child_n_scale[i]) * weight;
249 child_w_pos[i] = (m_relax * child_w_pos[i] + child_n_pos[i]) * weight;
250 child_w_rotation[0][i] = (m_relax * child_w_rotation[0][i] + child_n_rotation[0][i]) * weight;
251 child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight;
252 child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight;
255 //FIXME: update physics controller.
257 child_w_scale = child_n_scale;
258 child_w_pos = child_n_pos;
259 child_w_rotation = child_n_rotation;
260 m_initialized = true;
265 child_w_scale = child_scale;
266 child_w_pos = child_pos;
267 child_w_rotation = child_rotation;
270 child->SetWorldScale(child_w_scale);
271 child->SetWorldPosition(child_w_pos);
272 child->SetWorldOrientation(child_w_rotation);
273 child->SetModified(false);
275 return true; //parent != NULL;
279 * Method inherited from KX_ParentRelation
283 KX_SlowParentRelation::
286 return new KX_SlowParentRelation(m_relax);
289 KX_SlowParentRelation::
290 KX_SlowParentRelation(
299 KX_SlowParentRelation::
300 ~KX_SlowParentRelation(