Blender  V2.59
KX_SG_NodeRelationships.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: KX_SG_NodeRelationships.cpp 35171 2011-02-25 13:35:59Z jesterking $
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include "KX_SG_NodeRelationships.h"
00035 
00044         KX_NormalParentRelation *
00045 KX_NormalParentRelation::
00046 New(
00047 ) {
00048         return new KX_NormalParentRelation();
00049 }               
00050 
00051         bool
00052 KX_NormalParentRelation::
00053 UpdateChildCoordinates(
00054         SG_Spatial * child,
00055         const SG_Spatial * parent,
00056         bool& parentUpdated     
00057 ){
00058         MT_assert(child != NULL);
00059 
00060         if (!parentUpdated && !child->IsModified())
00061                 return false;
00062 
00063         parentUpdated = true;
00064 
00065         if (parent==NULL) { /* Simple case */
00066                 child->SetWorldFromLocalTransform();
00067                 child->ClearModified();
00068                 return true; //false;
00069         }
00070         else {
00071                 // the childs world locations which we will update.     
00072                 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
00073                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
00074                 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
00075 
00076                 child->SetWorldScale(p_world_scale * child->GetLocalScale());
00077                 child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation());
00078                 child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition()));
00079                 child->ClearModified();
00080                 return true;
00081         }
00082 }
00083 
00084         SG_ParentRelation *
00085 KX_NormalParentRelation::
00086 NewCopy(
00087 ){
00088         return new KX_NormalParentRelation();
00089 }
00090 
00091 KX_NormalParentRelation::
00092 ~KX_NormalParentRelation(
00093 ){
00094         //nothing to do
00095 }
00096 
00097 
00098 KX_NormalParentRelation::
00099 KX_NormalParentRelation(
00100 ){
00101         // nothing to do
00102 }
00103 
00109         KX_VertexParentRelation *
00110 KX_VertexParentRelation::
00111 New(
00112 ){
00113         return new KX_VertexParentRelation();
00114 }
00115                 
00120         bool
00121 KX_VertexParentRelation::
00122 UpdateChildCoordinates(
00123         SG_Spatial * child,
00124         const SG_Spatial * parent,
00125         bool& parentUpdated     
00126 ){
00127 
00128         MT_assert(child != NULL);
00129 
00130         if (!parentUpdated && !child->IsModified())
00131                 return false;
00132 
00133         child->SetWorldScale(child->GetLocalScale());
00134         
00135         if (parent)
00136                 child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition());
00137         else
00138                 child->SetWorldPosition(child->GetLocalPosition());
00139         
00140         child->SetWorldOrientation(child->GetLocalOrientation());
00141         child->ClearModified();
00142         return true; //parent != NULL;
00143 }
00144 
00149         SG_ParentRelation *
00150 KX_VertexParentRelation::
00151 NewCopy(
00152 ){
00153         return new KX_VertexParentRelation();
00154 };
00155 
00156 KX_VertexParentRelation::
00157 ~KX_VertexParentRelation(
00158 ){
00159         //nothing to do
00160 }
00161 
00162 
00163 KX_VertexParentRelation::
00164 KX_VertexParentRelation(
00165 ){
00166         //nothing to do
00167 }
00168 
00169 
00174         KX_SlowParentRelation *
00175 KX_SlowParentRelation::
00176 New(
00177         MT_Scalar relaxation
00178 ){
00179         return new      KX_SlowParentRelation(relaxation);
00180 }       
00181 
00186         bool
00187 KX_SlowParentRelation::
00188 UpdateChildCoordinates(
00189         SG_Spatial * child,
00190         const SG_Spatial * parent,
00191         bool& parentUpdated     
00192 ){
00193         MT_assert(child != NULL);
00194 
00195         // the child will move even if the parent is not
00196         parentUpdated = true;
00197 
00198         const MT_Vector3 & child_scale = child->GetLocalScale();
00199         const MT_Point3 & child_pos = child->GetLocalPosition();
00200         const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
00201 
00202         // the childs world locations which we will update.     
00203         
00204         MT_Vector3 child_w_scale;
00205         MT_Point3 child_w_pos;
00206         MT_Matrix3x3 child_w_rotation;
00207                 
00208         if (parent) {
00209 
00210                 // This is a slow parent relation
00211                 // first compute the normal child world coordinates.
00212 
00213                 MT_Vector3 child_n_scale;
00214                 MT_Point3 child_n_pos;
00215                 MT_Matrix3x3 child_n_rotation;
00216 
00217                 const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
00218                 const MT_Point3 & p_world_pos = parent->GetWorldPosition();
00219                 const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
00220 
00221                 child_n_scale = p_world_scale * child_scale;
00222                 child_n_rotation = p_world_rotation * child_rotation;
00223 
00224                 child_n_pos = p_world_pos + p_world_scale * 
00225                         (p_world_rotation * child_pos);
00226 
00227 
00228                 if (m_initialized) {
00229 
00230                         // get the current world positions
00231 
00232                         child_w_scale = child->GetWorldScaling();
00233                         child_w_pos = child->GetWorldPosition();
00234                         child_w_rotation = child->GetWorldOrientation();        
00235 
00236                         // now 'interpolate' the normal coordinates with the last 
00237                         // world coordinates to get the new world coordinates.
00238 
00239                         MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
00240                         child_w_scale = (m_relax * child_w_scale + child_n_scale) * weight;
00241                         child_w_pos = (m_relax * child_w_pos + child_n_pos) * weight;
00242                         // for rotation we must go through quaternion
00243                         MT_Quaternion child_w_quat = child_w_rotation.getRotation().slerp(child_n_rotation.getRotation(), weight);
00244                         child_w_rotation.setRotation(child_w_quat);
00245                         //FIXME: update physics controller.
00246                 } else {
00247                         child_w_scale = child_n_scale;
00248                         child_w_pos = child_n_pos;
00249                         child_w_rotation = child_n_rotation;
00250                         m_initialized = true;
00251                 }
00252                         
00253         } else {
00254 
00255                 child_w_scale = child_scale;
00256                 child_w_pos = child_pos;
00257                 child_w_rotation = child_rotation;
00258         }
00259 
00260         child->SetWorldScale(child_w_scale);
00261         child->SetWorldPosition(child_w_pos);
00262         child->SetWorldOrientation(child_w_rotation);
00263         child->ClearModified();
00264         // this node must always be updated, so reschedule it for next time
00265         child->ActivateRecheduleUpdateCallback();
00266         
00267         return true; //parent != NULL;
00268 }
00269 
00274         SG_ParentRelation *
00275 KX_SlowParentRelation::
00276 NewCopy(
00277 ){
00278         return new      KX_SlowParentRelation(m_relax);
00279 }
00280 
00281 KX_SlowParentRelation::
00282 KX_SlowParentRelation(
00283         MT_Scalar relaxation
00284 ):
00285         m_relax(relaxation),
00286         m_initialized(false)
00287 {
00288         //nothing to do
00289 }
00290 
00291 KX_SlowParentRelation::
00292 ~KX_SlowParentRelation(
00293 ){
00294         //nothing to do
00295 }
00296 
00297 
00298 
00299