Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp309
1 files changed, 128 insertions, 181 deletions
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
index e80de76861e..160654c26f1 100644
--- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
@@ -32,267 +32,214 @@
#include "KX_SG_NodeRelationships.h"
-/**
- * Implementation of classes defined in KX_SG_NodeRelationships.h
- */
/**
- * first of all KX_NormalParentRelation
+ * KX_NormalParentRelation - a regular parent/child relation, the child's coordinates are relative to the parent
*/
- KX_NormalParentRelation *
-KX_NormalParentRelation::
-New(
-) {
+KX_NormalParentRelation* KX_NormalParentRelation::New()
+{
return new KX_NormalParentRelation();
}
- bool
-KX_NormalParentRelation::
-UpdateChildCoordinates(
- SG_Spatial * child,
- const SG_Spatial * parent,
- bool& parentUpdated
-) {
+bool KX_NormalParentRelation::UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated)
+{
MT_assert(child != NULL);
+ /* If nothing changed in the parent or child, there is nothing to do here */
if (!parentUpdated && !child->IsModified())
return false;
- parentUpdated = true;
-
- if (parent==NULL) { /* Simple case */
+ /* The child has no parent, it is a root object.
+ * The world and local coordinates should be the same and applied directly. */
+ if (parent==NULL) {
child->SetWorldFromLocalTransform();
- child->ClearModified();
- return true; //false;
}
+ /* The child has a parent. The child's coordinates are defined relative to the parent's.
+ * The parent's coordinates should be applied to the child's local ones to calculate the real world position. */
else {
- // the childs world locations which we will update.
- const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
- const MT_Point3 & p_world_pos = parent->GetWorldPosition();
- const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
-
- 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;
+ const MT_Vector3 & parent_world_scale = parent->GetWorldScaling();
+ const MT_Point3 & parent_world_pos = parent->GetWorldPosition();
+ const MT_Matrix3x3 & parent_world_ori = parent->GetWorldOrientation();
+ const MT_Vector3 & child_local_scale = child->GetLocalScale();
+ const MT_Point3 & child_local_pos = child->GetLocalPosition();
+ const MT_Matrix3x3 & child_local_ori = child->GetLocalOrientation();
+
+ const MT_Vector3 & new_world_scale = parent_world_scale * child_local_scale;
+ const MT_Matrix3x3 & new_world_ori = parent_world_ori * child_local_ori;
+ const MT_Point3 & new_world_pos = parent_world_pos + (new_world_scale * (new_world_ori * child_local_pos));
+
+ child->SetWorldScale(new_world_scale);
+ child->SetWorldOrientation(new_world_ori);
+ child->SetWorldPosition(new_world_pos);
}
+
+ parentUpdated = true; //this variable is going to be used to update the children of this child
+ child->ClearModified();
+ return true;
}
- SG_ParentRelation *
-KX_NormalParentRelation::
-NewCopy(
-) {
+SG_ParentRelation* KX_NormalParentRelation::NewCopy()
+{
return new KX_NormalParentRelation();
}
-KX_NormalParentRelation::
-~KX_NormalParentRelation(
-) {
+KX_NormalParentRelation::~KX_NormalParentRelation()
+{
//nothing to do
}
-
-KX_NormalParentRelation::
-KX_NormalParentRelation(
-) {
+KX_NormalParentRelation::KX_NormalParentRelation()
+{
// nothing to do
}
-/**
- * Next KX_VertexParentRelation
- */
- KX_VertexParentRelation *
-KX_VertexParentRelation::
-New(
-) {
- return new KX_VertexParentRelation();
-}
-
-/**
- * Method inherited from KX_ParentRelation
+
+
+/**
+ * KX_VertexParentRelation - the child only inherits the position, not the orientation or scale
*/
- bool
-KX_VertexParentRelation::
-UpdateChildCoordinates(
- SG_Spatial * child,
- const SG_Spatial * parent,
- bool& parentUpdated
-) {
+KX_VertexParentRelation* KX_VertexParentRelation::New()
+{
+ return new KX_VertexParentRelation();
+}
+bool KX_VertexParentRelation::UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated)
+{
MT_assert(child != NULL);
+ /* If nothing changed in the parent or child, there is nothing to do here */
if (!parentUpdated && !child->IsModified())
return false;
- child->SetWorldScale(child->GetLocalScale());
-
- if (parent)
- child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition());
- else
+ /* The parent (if existing) is a vertex, so only position should be applied
+ * to the child's local coordinates to calculate the real world position. */
+
+ if (parent==NULL)
child->SetWorldPosition(child->GetLocalPosition());
-
+ else
+ child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition());
+
+ child->SetWorldScale(child->GetLocalScale());
child->SetWorldOrientation(child->GetLocalOrientation());
+
+ parentUpdated = true; //this variable is going to be used to update the children of this child
child->ClearModified();
- return true; //parent != NULL;
+ return true;
}
-/**
- * Method inherited from KX_ParentRelation
- */
-
- SG_ParentRelation *
-KX_VertexParentRelation::
-NewCopy(
-) {
+SG_ParentRelation* KX_VertexParentRelation::NewCopy()
+{
return new KX_VertexParentRelation();
-};
+}
-KX_VertexParentRelation::
-~KX_VertexParentRelation(
-) {
+KX_VertexParentRelation::~KX_VertexParentRelation()
+{
//nothing to do
}
-
-KX_VertexParentRelation::
-KX_VertexParentRelation(
-) {
+KX_VertexParentRelation::KX_VertexParentRelation()
+{
//nothing to do
}
+
+
+
/**
- * Slow parent relationship
+ * KX_SlowParentRelation - the child only inherits the position, not the orientation or scale
*/
- KX_SlowParentRelation *
-KX_SlowParentRelation::
-New(
- MT_Scalar relaxation
-) {
- return new KX_SlowParentRelation(relaxation);
+KX_SlowParentRelation* KX_SlowParentRelation::New(MT_Scalar relaxation)
+{
+ return new KX_SlowParentRelation(relaxation);
}
-/**
- * Method inherited from KX_ParentRelation
- */
-
- bool
-KX_SlowParentRelation::
-UpdateChildCoordinates(
- SG_Spatial * child,
- const SG_Spatial * parent,
- bool& parentUpdated
-) {
+bool KX_SlowParentRelation::UpdateChildCoordinates(SG_Spatial *child, 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();
-
- // the childs world locations which we will update.
-
- MT_Vector3 child_w_scale;
- MT_Point3 child_w_pos;
- MT_Matrix3x3 child_w_rotation;
-
- if (parent) {
-
- // This is a slow parent relation
- // first compute the normal child world coordinates.
-
- MT_Vector3 child_n_scale;
- MT_Point3 child_n_pos;
- MT_Matrix3x3 child_n_rotation;
-
- const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
- const MT_Point3 & p_world_pos = parent->GetWorldPosition();
- const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
-
- child_n_scale = p_world_scale * child_scale;
- child_n_rotation = p_world_rotation * child_rotation;
-
- child_n_pos = p_world_pos + p_world_scale *
- (p_world_rotation * child_pos);
-
+ /* The child has no parent, it is a root object.
+ * The world and local coordinates should be the same and applied directly. */
+ if (parent==NULL) {
+ child->SetWorldFromLocalTransform();
+ }
+ /* The child's coordinates get linearly interpolated with the parent's */
+ else {
+ const MT_Vector3 & parent_world_scale = parent->GetWorldScaling();
+ const MT_Point3 & parent_world_pos = parent->GetWorldPosition();
+ const MT_Matrix3x3 & parent_world_ori = parent->GetWorldOrientation();
+ const MT_Vector3 & child_local_scale = child->GetLocalScale();
+ const MT_Point3 & child_local_pos = child->GetLocalPosition();
+ const MT_Matrix3x3 & child_local_ori = child->GetLocalOrientation();
+
+ /* Compute the normal world coordinates, where the child would be if it was a normal parent relation */
+ const MT_Vector3 & normal_world_scale = parent_world_scale * child_local_scale;
+ const MT_Matrix3x3 & normal_world_ori = parent_world_ori * child_local_ori;
+ const MT_Point3 & normal_world_pos = parent_world_pos + (normal_world_scale * (normal_world_ori * child_local_pos));
+
+ MT_Vector3 new_world_scale;
+ MT_Point3 new_world_pos;
+ MT_Matrix3x3 new_world_ori;
if (m_initialized) {
- // get the current world positions
+ /* Get the current world positions */
+ const MT_Vector3 & current_world_scale = child->GetWorldScaling();
+ const MT_Matrix3x3 & current_world_ori = child->GetWorldOrientation();
+ const MT_Point3 & current_world_pos = child->GetWorldPosition();
- child_w_scale = child->GetWorldScaling();
- child_w_pos = child->GetWorldPosition();
- child_w_rotation = child->GetWorldOrientation();
+ /* Interpolate between the current world coordinates and the normal ones according to the weight.
+ * a bigger relax parameter, is a smaller weight,
+ * meaning that the child follows its normal position in smaller steps*/
+ /* XXX - this design has problems as it does not consider elapsed time between last update */
+ new_world_ori.setRotation(current_world_ori.getRotation().slerp(normal_world_ori.getRotation(), m_weight));
+ new_world_pos = current_world_pos + ( (normal_world_pos - current_world_pos) * m_weight);
+ new_world_scale = current_world_scale + ( (normal_world_scale - current_world_scale) * m_weight);
- // now 'interpolate' the normal coordinates with the last
- // world coordinates to get the new world coordinates.
-
- MT_Scalar weight = MT_Scalar(1)/(m_relax + 1);
- 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;
- child_w_pos = child_n_pos;
- child_w_rotation = child_n_rotation;
+ /**
+ * We need to compute valid world coordinates the first
+ * time we update spatial data of the child. This is done
+ * by just doing a normal parent relation the first time.
+ */
+ new_world_scale = normal_world_scale;
+ new_world_ori = normal_world_ori;
+ new_world_pos = normal_world_pos;
m_initialized = true;
}
-
- } else {
- child_w_scale = child_scale;
- child_w_pos = child_pos;
- child_w_rotation = child_rotation;
+ child->SetWorldScale(new_world_scale);
+ child->SetWorldOrientation(new_world_ori);
+ child->SetWorldPosition(new_world_pos);
}
- child->SetWorldScale(child_w_scale);
- child->SetWorldPosition(child_w_pos);
- child->SetWorldOrientation(child_w_rotation);
+ parentUpdated = true; //this variable is going to be used to update the children of this child
child->ClearModified();
// this node must always be updated, so reschedule it for next time
child->ActivateRecheduleUpdateCallback();
-
- return true; //parent != NULL;
+ return true;
}
-/**
- * Method inherited from KX_ParentRelation
- */
-
- SG_ParentRelation *
-KX_SlowParentRelation::
-NewCopy(
-) {
+SG_ParentRelation* KX_SlowParentRelation::NewCopy()
+{
return new KX_SlowParentRelation(m_relax);
}
-KX_SlowParentRelation::
-KX_SlowParentRelation(
- MT_Scalar relaxation
-):
- m_relax(relaxation),
- m_initialized(false)
+KX_SlowParentRelation::KX_SlowParentRelation(MT_Scalar relaxation)
+ :m_initialized(false)
{
- //nothing to do
+ m_relax = fabs(relaxation);
+ m_weight = MT_Scalar(1)/(m_relax + 1);
}
-KX_SlowParentRelation::
-~KX_SlowParentRelation(
-) {
+KX_SlowParentRelation::~KX_SlowParentRelation()
+{
//nothing to do
}
-
-
-
-