Revision: 31355
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=31355
Author:   nicks
Date:     2010-08-15 19:40:57 +0200 (Sun, 15 Aug 2010)

Log Message:
-----------
added option to set "up" vector of the actor orientation using navmesh normal 
(steering actuator)

Modified Paths:
--------------
    branches/soc-2010-nicks/source/blender/editors/space_logic/logic_window.c
    branches/soc-2010-nicks/source/blender/makesdna/DNA_actuator_types.h
    branches/soc-2010-nicks/source/blender/makesrna/intern/rna_actuator.c
    branches/soc-2010-nicks/source/gameengine/Converter/KX_ConvertActuators.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp
    branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.h

Modified: 
branches/soc-2010-nicks/source/blender/editors/space_logic/logic_window.c
===================================================================
--- branches/soc-2010-nicks/source/blender/editors/space_logic/logic_window.c   
2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/blender/editors/space_logic/logic_window.c   
2010-08-15 17:40:57 UTC (rev 31355)
@@ -4351,8 +4351,12 @@
        uiItemR(row, ptr, "facing", 0, NULL, 0);
        if (RNA_boolean_get(ptr, "facing"))
        {
-               uiItemR(row, ptr, "facingaxis", 0, NULL, 0);    
+               uiItemR(row, ptr, "facingaxis", 0, NULL, 0);
        }
+       if (RNA_pointer_get(ptr, "navmesh").data)
+       {
+               uiItemR(row, ptr, "normalup", 0, NULL, 0);              
+       }
        row = uiLayoutRow(layout, 0);
        uiItemR(row, ptr, "selfterminated", 0, NULL, 0);
        if (RNA_enum_get(ptr, "mode")==ACT_STEERING_PATHFOLLOWING)

Modified: branches/soc-2010-nicks/source/blender/makesdna/DNA_actuator_types.h
===================================================================
--- branches/soc-2010-nicks/source/blender/makesdna/DNA_actuator_types.h        
2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/blender/makesdna/DNA_actuator_types.h        
2010-08-15 17:40:57 UTC (rev 31355)
@@ -527,6 +527,7 @@
 #define ACT_STEERING_SELFTERMINATED   1
 #define ACT_STEERING_ENABLEVISUALIZATION   2
 #define ACT_STEERING_AUTOMATICFACING   4
+#define ACT_STEERING_NORMALUP  8
 
 #endif
 

Modified: branches/soc-2010-nicks/source/blender/makesrna/intern/rna_actuator.c
===================================================================
--- branches/soc-2010-nicks/source/blender/makesrna/intern/rna_actuator.c       
2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/blender/makesrna/intern/rna_actuator.c       
2010-08-15 17:40:57 UTC (rev 31355)
@@ -1976,7 +1976,11 @@
        RNA_def_property_enum_items(prop, facingaxis_items);
        RNA_def_property_ui_text(prop, "Axis", "Axis for automatic facing");
        RNA_def_property_update(prop, NC_LOGIC, NULL);
-       
+
+       prop= RNA_def_property(srna, "normalup", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", 
ACT_STEERING_NORMALUP);
+       RNA_def_property_ui_text(prop, "N", "Use normal of the navmesh to set 
\"UP\" vector");
+       RNA_def_property_update(prop, NC_LOGIC, NULL);
 }
 
 void RNA_def_actuator(BlenderRNA *brna)

Modified: 
branches/soc-2010-nicks/source/gameengine/Converter/KX_ConvertActuators.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Converter/KX_ConvertActuators.cpp 
2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/gameengine/Converter/KX_ConvertActuators.cpp 
2010-08-15 17:40:57 UTC (rev 31355)
@@ -1060,11 +1060,12 @@
                                bool selfTerminated = (stAct->flag & 
ACT_STEERING_SELFTERMINATED) !=0;
                                bool enableVisualization = (stAct->flag & 
ACT_STEERING_ENABLEVISUALIZATION) !=0;
                                short facingMode = (stAct->flag & 
ACT_STEERING_AUTOMATICFACING) ? stAct->facingaxis : 0;
+                               bool normalup = (stAct->flag & 
ACT_STEERING_NORMALUP) !=0;
                                KX_SteeringActuator *tmpstact
                                        = new KX_SteeringActuator(gameobj, 
mode, targetob, navmeshob,stAct->dist, 
                                                                
stAct->velocity, stAct->acceleration, stAct->turnspeed, 
                                                                selfTerminated, 
stAct->updateTime,
-                                                               
scene->GetObstacleSimulation(), facingMode, enableVisualization);
+                                                               
scene->GetObstacleSimulation(), facingMode, normalup, enableVisualization);
                                baseact = tmpstact;
                                break;
                        }

Modified: 
branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp    
2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.cpp    
2010-08-15 17:40:57 UTC (rev 31355)
@@ -39,8 +39,8 @@
 #include "KX_ObstacleSimulation.h"
 #include "KX_PythonInit.h"
 #include "KX_PyMath.h"
+#include "Recast.h"
 
-
 /* ------------------------------------------------------------------------- */
 /* Native functions                                                          */
 /* ------------------------------------------------------------------------- */
@@ -57,6 +57,7 @@
                                                                        int 
pathUpdatePeriod,
                                                                        
KX_ObstacleSimulation* simulation,
                                                                        short 
facingmode,
+                                                                       bool 
normalup,
                                                                        bool 
enableVisualization)        : 
        SCA_IActuator(gameobj, KX_ACT_STEERING),
        m_mode(mode),
@@ -72,6 +73,7 @@
        m_simulation(simulation),       
        m_enableVisualization(enableVisualization),
        m_facingMode(facingmode),
+       m_normalUp(normalup),
        m_obstacle(NULL),
        m_pathLen(0),
        m_wayPointIdx(-1),
@@ -309,23 +311,129 @@
 
 const MT_Vector3& KX_SteeringActuator::GetSteeringVec()
 {
+       static MT_Vector3 ZERO_VECTOR(0, 0, 0);
        if (m_isActive)
                return m_steerVec;
        else
-               return MT_Vector3(0, 0, 0);
+               return ZERO_VECTOR;
 }
 
+inline float vdot2(const float* a, const float* b)
+{
+       return a[0]*b[0] + a[2]*b[2];
+}
+static bool barDistSqPointToTri(const float* p, const float* a, const float* 
b, const float* c)
+{
+       float v0[3], v1[3], v2[3];
+       vsub(v0, c,a);
+       vsub(v1, b,a);
+       vsub(v2, p,a);
+
+       const float dot00 = vdot2(v0, v0);
+       const float dot01 = vdot2(v0, v1);
+       const float dot02 = vdot2(v0, v2);
+       const float dot11 = vdot2(v1, v1);
+       const float dot12 = vdot2(v1, v2);
+
+       // Compute barycentric coordinates
+       float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
+       float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+       float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+       float ud = u<0.f ? -u : (u>1.f ? u-1.f : 0.f);
+       float vd = v<0.f ? -v : (v>1.f ? v-1.f : 0.f);
+       return ud*ud+vd*vd ;
+}
+
+inline void flipAxes(float* vec)
+{
+       std::swap(vec[1],vec[2]);
+}
+
+static bool getNavmeshNormal(dtStatNavMesh* navmesh, const MT_Vector3& pos, 
MT_Vector3& normal)
+{
+       static const float polyPickExt[3] = {2, 4, 2};
+       float spos[3];
+       pos.getValue(spos);     
+       flipAxes(spos); 
+       dtStatPolyRef sPolyRef = navmesh->findNearestPoly(spos, polyPickExt);
+       if (sPolyRef == 0)
+               return false;
+       const dtStatPoly* p = navmesh->getPoly(sPolyRef-1);
+       const dtStatPolyDetail* pd = navmesh->getPolyDetail(sPolyRef-1);
+
+       float distMin = FLT_MAX;
+       int idxMin = -1;
+       for (int i = 0; i < pd->ntris; ++i)
+       {
+               const unsigned char* t = navmesh->getDetailTri(pd->tbase+i);
+               const float* v[3];
+               for (int j = 0; j < 3; ++j)
+               {
+                       if (t[j] < p->nv)
+                               v[j] = navmesh->getVertex(p->v[t[j]]);
+                       else
+                               v[j] = 
navmesh->getDetailVertex(pd->vbase+(t[j]-p->nv));
+               }
+               float dist = barDistSqPointToTri(spos, v[0], v[1], v[2]);
+               if (dist<distMin)
+               {
+                       distMin = dist;
+                       idxMin = i;
+               }                       
+       }
+
+       if (idxMin>=0)
+       {
+               const unsigned char* t = 
navmesh->getDetailTri(pd->tbase+idxMin);
+               const float* v[3];
+               for (int j = 0; j < 3; ++j)
+               {
+                       if (t[j] < p->nv)
+                               v[j] = navmesh->getVertex(p->v[t[j]]);
+                       else
+                               v[j] = 
navmesh->getDetailVertex(pd->vbase+(t[j]-p->nv));
+               }
+               MT_Vector3 tri[3];
+               for (size_t j=0; j<3; j++)
+                       tri[j].setValue(v[j][0],v[j][2],v[j][1]);
+               MT_Vector3 a,b;
+               a = tri[1]-tri[0];
+               b = tri[2]-tri[0];
+               normal = b.cross(a).safe_normalized();
+               return true;
+       }
+
+       return false;
+}
+
 void KX_SteeringActuator::HandleActorFace(MT_Vector3& velocity)
 {
-       if (m_facingMode==0)
+       if (m_facingMode==0 && (!m_navmesh || !m_normalUp))
                return;
-       MT_Vector3 dir = velocity;
+       KX_GameObject* curobj = (KX_GameObject*) GetParent();
+       MT_Vector3 dir = m_facingMode==0 ?  
curobj->NodeGetLocalOrientation().getColumn(1) : velocity;
        if (dir.fuzzyZero())
                return; 
        dir.normalize();
        MT_Vector3 up(0,0,1);
        MT_Vector3 left;
        MT_Matrix3x3 mat;
+       
+       if (m_navmesh && m_normalUp)
+       {
+               dtStatNavMesh* navmesh =  m_navmesh->GetNavMesh();
+               MT_Vector3 normal;
+               MT_Vector3 trpos = 
m_navmesh->TransformToLocalCoords(curobj->NodeGetWorldPosition());
+               if (getNavmeshNormal(navmesh, trpos, normal))
+               {
+
+                       left = (dir.cross(up)).safe_normalized();
+                       dir = (-left.cross(normal)).safe_normalized();          
        
+                       up = normal;
+               }
+       }
+
        switch (m_facingMode)
        {
        case 1: // TRACK X
@@ -370,14 +478,15 @@
                        break;
                }
        }
+
        mat.setValue (
                left[0], dir[0],up[0], 
                left[1], dir[1],up[1],
                left[2], dir[2],up[2]
        );
 
-       KX_GameObject* curobj = (KX_GameObject*) GetParent();
        
+       
        KX_GameObject* parentObject = curobj->GetParent();
        if(parentObject)
        { 

Modified: branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.h
===================================================================
--- branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.h      
2010-08-15 16:50:58 UTC (rev 31354)
+++ branches/soc-2010-nicks/source/gameengine/Ketsji/KX_SteeringActuator.h      
2010-08-15 17:40:57 UTC (rev 31355)
@@ -66,6 +66,7 @@
        bool m_isSelfTerminated;
        bool m_enableVisualization;
        short m_facingMode;
+       bool m_normalUp;
        float m_path[MAX_PATH_LENGTH*3];
        int m_pathLen;
        int m_pathUpdatePeriod;
@@ -96,6 +97,7 @@
                                                int pathUpdatePeriod,
                                                KX_ObstacleSimulation* 
simulation,
                                                short facingmode,
+                                               bool normalup,
                                                bool enableVisualization);
        virtual ~KX_SteeringActuator();
        virtual bool Update(double curtime, bool frame);


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

Reply via email to