synched with trunk at revision 32129
[blender.git] / source / gameengine / Ketsji / KX_SG_NodeRelationships.cpp
index 0729ec8a9025badf3d9f6a3202533ce41ad70865..ccdaac8edb75045e7bf7c84ec94e126f12a2404d 100644 (file)
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
 
 #include "KX_SG_NodeRelationships.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 /**
  * Implementation of classes defined in KX_SG_NodeRelationships.h
  */
@@ -51,13 +47,20 @@ New(
 KX_NormalParentRelation::
 UpdateChildCoordinates(
        SG_Spatial * child,
-       const SG_Spatial * parent
+       const SG_Spatial * parent,
+       bool& parentUpdated     
 ){
        MT_assert(child != NULL);
 
+       if (!parentUpdated && !child->IsModified())
+               return false;
+
+       parentUpdated = true;
+
        if (parent==NULL) { /* Simple case */
                child->SetWorldFromLocalTransform();
-               return false;
+               child->ClearModified();
+               return true; //false;
        }
        else {
                // the childs world locations which we will update.     
@@ -68,6 +71,7 @@ UpdateChildCoordinates(
                child->SetWorldScale(p_world_scale * child->GetLocalScale());
                child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation());
                child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition()));
+               child->ClearModified();
                return true;
        }
 }
@@ -112,10 +116,15 @@ New(
 KX_VertexParentRelation::
 UpdateChildCoordinates(
        SG_Spatial * child,
-       const SG_Spatial * parent
+       const SG_Spatial * parent,
+       bool& parentUpdated     
 ){
 
        MT_assert(child != NULL);
+
+       if (!parentUpdated && !child->IsModified())
+               return false;
+
        child->SetWorldScale(child->GetLocalScale());
        
        if (parent)
@@ -124,7 +133,8 @@ UpdateChildCoordinates(
                child->SetWorldPosition(child->GetLocalPosition());
        
        child->SetWorldOrientation(child->GetLocalOrientation());
-       return parent != NULL;
+       child->ClearModified();
+       return true; //parent != NULL;
 }
 
 /** 
@@ -172,10 +182,14 @@ New(
 KX_SlowParentRelation::
 UpdateChildCoordinates(
        SG_Spatial * child,
-       const SG_Spatial * parent
+       const SG_Spatial * parent,
+       bool& parentUpdated     
 ){
        MT_assert(child != NULL);
 
+       // the child will move even if the parent is not
+       parentUpdated = true;
+
        const MT_Vector3 & child_scale = child->GetLocalScale();
        const MT_Point3 & child_pos = child->GetLocalPosition();
        const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
@@ -217,23 +231,12 @@ UpdateChildCoordinates(
                        // now 'interpolate' the normal coordinates with the last 
                        // world coordinates to get the new world coordinates.
 
-                       // problem 1:
-                       // The child world scale needs to be initialized in some way for this 
-                       // to make sense
-                       // problem 2:
-                       // This is way of doing interpolation is nonsense
-
-                       int i;
-
                        MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
-                       for (i=0;i <3 ;i++) {
-                               child_w_scale[i] = (m_relax * child_w_scale[i] + child_n_scale[i]) * weight;
-                               child_w_pos[i] = (m_relax * child_w_pos[i] + child_n_pos[i]) * weight;
-                               child_w_rotation[0][i] = (m_relax * child_w_rotation[0][i] + child_n_rotation[0][i]) * weight;
-                               child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight;
-                               child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight;
-                       }
-                       
+                       child_w_scale = (m_relax * child_w_scale + child_n_scale) * weight;
+                       child_w_pos = (m_relax * child_w_pos + child_n_pos) * weight;
+                       // for rotation we must go through quaternion
+                       MT_Quaternion child_w_quat = child_w_rotation.getRotation().slerp(child_n_rotation.getRotation(), weight);
+                       child_w_rotation.setRotation(child_w_quat);
                        //FIXME: update physics controller.
                } else {
                        child_w_scale = child_n_scale;
@@ -252,8 +255,11 @@ UpdateChildCoordinates(
        child->SetWorldScale(child_w_scale);
        child->SetWorldPosition(child_w_pos);
        child->SetWorldOrientation(child_w_rotation);
+       child->ClearModified();
+       // this node must always be updated, so reschedule it for next time
+       child->ActivateRecheduleUpdateCallback();
        
-       return parent != NULL;
+       return true; //parent != NULL;
 }
 
 /**