Revision: 15702
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15702
Author:   ben2610
Date:     2008-07-23 01:05:06 +0200 (Wed, 23 Jul 2008)

Log Message:
-----------
BGE patch: Add min/max parameters to orientation constraint actuator

The min/max parameters define a minimum/maximum angle
that the object axis can have with the reference 
direction without being constrainted. The angle is 
expressed in degree and is limited to 0-180 range. 
The min/max parameters define a conical free zone
around the reference direction.

If the object axis is outside that free zone, the
actuator will tend to put it back using as a temporary
reference direction the vector that is exactly at
min or max degree of the reference direction 
(depending if the axis angle is below the minimum 
or above the maximum) and is located in the plane 
formed by the axis and the reference direction.

With a low damping value, this is equivalent to 
clamping the axis orientation within min/max degree
of the reference direction.

Backward compatibility corresponds to the absence
of free zone: min = max = 0.

Modified Paths:
--------------
    trunk/blender/source/blender/src/buttons_logic.c
    trunk/blender/source/gameengine/Converter/KX_ConvertActuators.cpp
    trunk/blender/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
    trunk/blender/source/gameengine/Ketsji/KX_ConstraintActuator.h

Modified: trunk/blender/source/blender/src/buttons_logic.c
===================================================================
--- trunk/blender/source/blender/src/buttons_logic.c    2008-07-22 18:48:28 UTC 
(rev 15701)
+++ trunk/blender/source/blender/src/buttons_logic.c    2008-07-22 23:05:06 UTC 
(rev 15702)
@@ -2062,7 +2062,7 @@
                        coa->time = 0;
                        uiDefButS(block, MENU, 1, str,          xco+10, yco-65, 
70, 19, &coa->flag, 0.0, 0.0, 0, 0, "");
                
-                       uiDefButS(block, NUM,           0, "Damp:",     xco+10, 
yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+                       uiDefButS(block, NUM,           0, "damp",      xco+10, 
yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant 
(in frame) of low pass filter");
                        uiDefBut(block, LABEL,                  0, "Min",       
xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
                        uiDefBut(block, LABEL,                  0, "Max",       
xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
 
@@ -2084,7 +2084,7 @@
                        str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z 
axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32";
                        uiDefButS(block, MENU, B_REDR, str,             xco+10, 
yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray");
                
-                       uiDefButS(block, NUM,           0, "Damp:",     xco+10, 
yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+                       uiDefButS(block, NUM,           0, "damp",      xco+10, 
yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant 
(in frame) of low pass filter");
                        uiDefBut(block, LABEL,                  0, "Range",     
xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum 
length of ray");
                        uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, 
"Dist",    xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 
0.0, 0, 0, "Force distance of object to point of impact of ray");
 
@@ -2124,7 +2124,7 @@
                        str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z 
axis %x4";
                        uiDefButS(block, MENU, B_REDR, str,             xco+10, 
yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned 
along the reference direction");
                
-                       uiDefButS(block, NUM,           0, "Damp:",     xco+10, 
yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+                       uiDefButS(block, NUM,           0, "damp",      xco+10, 
yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant 
(in frame) of low pass filter");
                        uiDefBut(block, LABEL,                  0, "X", xco+80, 
yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
                        uiDefBut(block, LABEL,                  0, "Y", 
xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
                        uiDefBut(block, LABEL,                  0, "Z", 
xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
@@ -2133,7 +2133,9 @@
                        uiDefButF(block, NUM, 0, "",            
xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 
2000.0, 10, 0, "Y component of reference direction");
                        uiDefButF(block, NUM, 0, "",            
xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 
2000.0, 10, 0, "Z component of reference direction");
 
-                       uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 
70+(width-115)/3, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time 
in frame, 0 for unlimited");
+                       uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 
19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for 
unlimited");
+                       uiDefButF(block, NUM, 0, "min", xco+80, yco-84, 
(width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in 
degree) to maintain with target direction. No correction is done if angle with 
target direction is between min and max");
+                       uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, 
yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle 
(in degree) allowed with target direction. No correction is done if angle with 
target direction is between min and max");
                }
                str= "Constraint Type %t|Location %x0|Distance %x1|Orientation 
%x2";
                but = uiDefButS(block, MENU, B_REDR, str,               xco+40, 
yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, "");

Modified: trunk/blender/source/gameengine/Converter/KX_ConvertActuators.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/KX_ConvertActuators.cpp   
2008-07-22 18:48:28 UTC (rev 15701)
+++ trunk/blender/source/gameengine/Converter/KX_ConvertActuators.cpp   
2008-07-22 23:05:06 UTC (rev 15702)
@@ -628,6 +628,8 @@
                                /* convert settings... degrees in the ui become 
radians  */ 
                                /* internally                                   
         */ 
                                if (conact->type == ACT_CONST_TYPE_ORI) {
+                                       min = (MT_2_PI * 
conact->minloc[0])/360.0;
+                                       max = (MT_2_PI * 
conact->maxloc[0])/360.0;
                                        switch (conact->mode) {
                                        case ACT_CONST_DIRPX:
                                                locrot = 
KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX;

Modified: trunk/blender/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_ConstraintActuator.cpp    
2008-07-22 18:48:28 UTC (rev 15701)
+++ trunk/blender/source/gameengine/Ketsji/KX_ConstraintActuator.cpp    
2008-07-22 23:05:06 UTC (rev 15702)
@@ -88,11 +88,17 @@
                        } else {
                                m_refDirection /= len;
                        }
+                       m_minimumBound = cos(minBound);
+                       m_maximumBound = cos(maxBound);
+                       m_minimumSine = sin(minBound);
+                       m_maximumSine = sin(maxBound);
                }
                break;
        default:
                m_minimumBound = minBound;
                m_maximumBound = maxBound;
+               m_minimumSine = 0.f;
+               m_maximumSine = 0.f;
                break;
        }
 
@@ -153,9 +159,9 @@
                KX_GameObject  *obj = (KX_GameObject*) GetParent();
                MT_Point3    position = obj->NodeGetWorldPosition();
                MT_Point3    newposition;
-               MT_Vector3   direction;
+               MT_Vector3   direction, refDirection;
                MT_Matrix3x3 rotation = obj->NodeGetWorldOrientation();
-               MT_Scalar    filter, newdistance;
+               MT_Scalar    filter, newdistance, cosangle;
                int axis, sign;
 
                if (m_posDampTime) {
@@ -185,11 +191,45 @@
                                axis = 2;
                                break;
                        }
+                       if ((m_maximumBound < (1.0f-FLT_EPSILON)) || 
(m_minimumBound < (1.0f-FLT_EPSILON))) {
+                               // reference direction needs to be evaluated
+                               // 1. get the cosine between current direction 
and target
+                               cosangle = direction.dot(m_refDirection);
+                               if (cosangle >= (m_maximumBound-FLT_EPSILON) && 
cosangle <= (m_minimumBound+FLT_EPSILON)) {
+                                       // no change to do
+                                       result = true;
+                                       goto CHECK_TIME;
+                               }
+                               // 2. define a new reference direction
+                               //    compute local axis with reference 
direction as X and
+                               //    Y in direction X refDirection plane
+                               MT_Vector3 zaxis = 
m_refDirection.cross(direction);
+                               if (MT_fuzzyZero2(zaxis.length2())) {
+                                       // direction and refDirection are 
identical,
+                                       // choose any other direction to define 
plane
+                                       if (direction[0] < 0.9999)
+                                               zaxis = 
m_refDirection.cross(MT_Vector3(1.0,0.0,0.0));
+                                       else
+                                               zaxis = 
m_refDirection.cross(MT_Vector3(0.0,1.0,0.0));
+                               }
+                               MT_Vector3 yaxis = zaxis.cross(m_refDirection);
+                               yaxis.normalize();
+                               if (cosangle > m_minimumBound) {
+                                       // angle is too close to reference 
direction,
+                                       // choose a new reference that is 
exactly at minimum angle
+                                       refDirection = m_minimumBound * 
m_refDirection + m_minimumSine * yaxis;
+                               } else {
+                                       // angle is too large, choose new 
reference direction at maximum angle
+                                       refDirection = m_maximumBound * 
m_refDirection + m_maximumSine * yaxis;
+                               }
+                       } else {
+                               refDirection = m_refDirection;
+                       }
                        if (m_posDampTime) {
                                // apply damping on the direction
-                               direction = filter*direction + 
(1.0-filter)*m_refDirection;
+                               direction = filter*direction + 
(1.0-filter)*refDirection;
                        } else {
-                               direction = m_refDirection;
+                               direction = refDirection;
                        }
                        obj->AlignAxisToVect(direction, axis);
                        result = true;

Modified: trunk/blender/source/gameengine/Ketsji/KX_ConstraintActuator.h
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_ConstraintActuator.h      
2008-07-22 18:48:28 UTC (rev 15701)
+++ trunk/blender/source/gameengine/Ketsji/KX_ConstraintActuator.h      
2008-07-22 23:05:06 UTC (rev 15702)
@@ -48,6 +48,10 @@
        float m_minimumBound;
        // max (float)
        float m_maximumBound;
+       // sinus of minimum angle
+       float m_minimumSine;
+       // sinus of maximum angle
+       float m_maximumSine;
        // reference direction
        MT_Vector3 m_refDirection;
        // locrotxyz choice (pick one): only one choice allowed at a time!


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to