Fix for bugs: 1788 (forces) and 1799 (python delattr on game objects)
authorKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Mon, 22 Nov 2004 10:19:19 +0000 (10:19 +0000)
committerKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Mon, 22 Nov 2004 10:19:19 +0000 (10:19 +0000)
Use Polytope collision for faster mesh intersection tests, so SOLID can actually use that qhull lib now.

28 files changed:
intern/moto/include/MT_Quaternion.h
intern/moto/include/MT_Quaternion.inl
source/blender/makesdna/DNA_object_types.h
source/blender/src/buttons_logic.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Expressions/PyObjectPlus.cpp
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/Expressions/Value.cpp
source/gameengine/Expressions/Value.h
source/gameengine/Ketsji/KX_CameraActuator.cpp
source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_IpoActuator.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_TouchEventManager.cpp
source/gameengine/Ketsji/KX_TouchEventManager.h
source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h
source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp [new file with mode: 0644]
source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
source/gameengine/Physics/Sumo/SConscript
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h

index aa2045fc56f5026968039491fc5b6ebbd0fd391f..03b52efe600c8cac332abc61bef2072203f7b100 100644 (file)
@@ -95,6 +95,9 @@ public:
     void invert();
     MT_Quaternion inverse() const;
 
+    MT_Scalar angle(const MT_Quaternion& q) const;
+    MT_Quaternion slerp(const MT_Quaternion& q, const MT_Scalar& t) const;
+    
     static MT_Quaternion random();
 };
 
index 225b95b78ce29cc7a554c9e7fae15feb5bc443d0..8b4fbc93c41dae9ae62ee74ba09b4ad5571e1477 100644 (file)
@@ -60,3 +60,27 @@ GEN_INLINE MT_Quaternion operator*(const MT_Vector3& w, const MT_Quaternion& q)
                          -w[0] * q[0] - w[1] * q[1] - w[2] * q[2]); 
 }
 
+GEN_INLINE MT_Scalar MT_Quaternion::angle(const MT_Quaternion& q) const 
+{
+       MT_Scalar s = sqrt(length2() * q.length2());
+       assert(s != MT_Scalar(0.0));
+       return acos(dot(q) / s);
+}
+
+GEN_INLINE MT_Quaternion MT_Quaternion::slerp(const MT_Quaternion& q, const MT_Scalar& t) const
+{
+       MT_Scalar theta = angle(q);
+       if (theta != MT_Scalar(0.0))
+       {
+               MT_Scalar d = MT_Scalar(1.0) / sin(theta);
+               MT_Scalar s0 = sin((MT_Scalar(1.0) - t) * theta);
+               MT_Scalar s1 = sin(t * theta);
+               
+               return d*(*this * s0 + q * s1);
+       }
+       else
+       {
+               return *this;
+       }
+}
+
index 7c4279a3b8a143b44113ef3f932e6d723b130662..da056ee35cd5f763970b0c61bf28d7a3e8931370 100644 (file)
@@ -318,6 +318,7 @@ extern Object workob;
 #define OB_BOUND_CYLINDER      2
 #define OB_BOUND_CONE          3
 #define OB_BOUND_POLYH         4
+#define OB_BOUND_POLYT         5
 
 /* also needed for base!!!!! or rather, thy interfere....*/
 /* base->flag and ob->flag */
index 3719a5cf2250327fb9be3830bc732f01189a8a7a..0bc5344074ce1f920ead68861d1942c05375955c 100644 (file)
@@ -2389,7 +2389,7 @@ void buttons_ketsji(uiBlock *block, Object *ob)
                                &ob->gameflag, 0, 0,0, 0,
                                "Specify a bounds object for physics");
                if (ob->gameflag & OB_BOUNDS) {
-                       uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4",
+                       uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4|Polytope%x5",
                                85, 125, 100, 19, &ob->boundtype, 0, 0, 0, 0, "Selects the boundary display type");
                }
        }
index e0d460d18d6d76fc38d5059a5aff7063691f1906..7fa2b68e0c2c05cb1fe47e0284b16fc92e9ddacb 100644 (file)
@@ -715,6 +715,14 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
                                objprop.m_boundobject.box.m_extends[1]=2.f*bb.m_extends[1];
                                objprop.m_boundobject.box.m_extends[2]=2.f*bb.m_extends[2];
                                break;
+                       case OB_BOUND_POLYT:
+                               if (blenderobject->type == OB_MESH)
+                               {
+                                       objprop.m_boundclass = KX_BOUNDPOLYTOPE;
+                                       break;
+                               }
+                               // Object is not a mesh... fall through OB_BOUND_POLYH to 
+                               // OB_BOUND_SPHERE
                        case OB_BOUND_POLYH:
                                if (blenderobject->type == OB_MESH)
                                {
index 88a38b35ad4d505001a9f98d1830089d64ce4551..2b331d7f728e6d3fda3771d9f213306f62e4f95f 100644 (file)
@@ -111,6 +111,11 @@ PyObject *PyObjectPlus::_getattr(const STR_String& attr)
   return Py_FindMethod(Methods, this, const_cast<char *>(attr.ReadPtr()));
 }
 
+int PyObjectPlus::_delattr(const STR_String& attr)
+{
+       return 1;
+}
+
 int PyObjectPlus::_setattr(const STR_String& attr, PyObject *value)
 {
        //return PyObject::_setattr(attr,value);
index 05c806ec4ff1c16c4b135da347cbd3f49e73406f..7e6b3f29bab48837804d5271bec669b1bd975cc9 100644 (file)
@@ -119,47 +119,57 @@ PyObject* class_name::Py##method_name(PyObject*, PyObject* args, PyObject*)
 ------------------------------*/
 typedef PyTypeObject * PyParentObject;                         // Define the PyParent Object
 
-class PyObjectPlus : public PyObject {                         // The PyObjectPlus abstract class
-
-  Py_Header;                                                   // Always start with Py_Header
-
- public:  
-  PyObjectPlus(PyTypeObject *T);
-  
-  virtual ~PyObjectPlus() {};                                  // destructor
-  static void PyDestructor(PyObject *P)                                // python wrapper
-  {  
-         delete ((PyObjectPlus *) P);  
-  };
-
-  //void INCREF(void) {
-//       Py_INCREF(this);
-//  };                         // incref method
-  //void DECREF(void) {
-//       Py_DECREF(this);
-//  };                         // decref method
-
-  virtual PyObject *_getattr(const STR_String& attr);                  // _getattr method
-  static  PyObject *__getattr(PyObject * PyObj, char *attr)    // This should be the entry in Type. 
-    { return ((PyObjectPlus*) PyObj)->_getattr(STR_String(attr)); };
-   
-  virtual int _setattr(const STR_String& attr, PyObject *value);               // _setattr method
-  static  int __setattr(PyObject *PyObj,                       // This should be the entry in Type. 
-                       char *attr, 
-                       PyObject *value)
-    { return ((PyObjectPlus*) PyObj)->_setattr(STR_String(attr), value);  };
-
-  virtual PyObject *_repr(void);                               // _repr method
-  static  PyObject *__repr(PyObject *PyObj)                    // This should be the entry in Type.
-    {  return ((PyObjectPlus*) PyObj)->_repr();  };
-
-
-                                                               // isA methods
-  bool isA(PyTypeObject *T);
-  bool isA(const char *mytypename);
-  PyObject *Py_isA(PyObject *args);
-  static PyObject *sPy_isA(PyObject *self, PyObject *args, PyObject *kwd)
-    {return ((PyObjectPlus*)self)->Py_isA(args);};
+class PyObjectPlus : public PyObject 
+{                              // The PyObjectPlus abstract class
+       Py_Header;                                                      // Always start with Py_Header
+       
+public:
+       PyObjectPlus(PyTypeObject *T);
+       
+       virtual ~PyObjectPlus() {};                                     // destructor
+       static void PyDestructor(PyObject *P)                           // python wrapper
+       {  
+               delete ((PyObjectPlus *) P);  
+       };
+       
+       //void INCREF(void) {
+       //        Py_INCREF(this);
+       //  };                          // incref method
+       //void DECREF(void) {
+       //        Py_DECREF(this);
+       //  };                          // decref method
+       
+       virtual PyObject *_getattr(const STR_String& attr);                     // _getattr method
+       static  PyObject *__getattr(PyObject * PyObj, char *attr)       // This should be the entry in Type. 
+       {
+               return ((PyObjectPlus*) PyObj)->_getattr(STR_String(attr)); 
+       }
+       
+       virtual int _delattr(const STR_String& attr);
+       virtual int _setattr(const STR_String& attr, PyObject *value);          // _setattr method
+       static  int __setattr(PyObject *PyObj,                  // This should be the entry in Type. 
+                               char *attr, 
+                               PyObject *value)
+       { 
+               if (!value)
+                       return ((PyObjectPlus*) PyObj)->_delattr(attr);
+               return ((PyObjectPlus*) PyObj)->_setattr(STR_String(attr), value);  
+       }
+       
+       virtual PyObject *_repr(void);                          // _repr method
+       static  PyObject *__repr(PyObject *PyObj)                       // This should be the entry in Type.
+       {
+               return ((PyObjectPlus*) PyObj)->_repr();  
+       }
+       
+                                                                       // isA methods
+       bool isA(PyTypeObject *T);
+       bool isA(const char *mytypename);
+       PyObject *Py_isA(PyObject *args);
+       static PyObject *sPy_isA(PyObject *self, PyObject *args, PyObject *kwd)
+       {
+               return ((PyObjectPlus*)self)->Py_isA(args);
+       }
 };
 
 #endif //  _adr_py_lib_h_
index 07505829737b8ec3ba97358245e139c9726b7c70..9233a10b78439c26b6f07ecfe14fd779976d9ecf 100644 (file)
@@ -698,14 +698,15 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj)
        return vallie;
 
 }
-int    CValue::_setattr(const STR_String& attr,PyObject* pyobj)
+
+int    CValue::_delattr(const STR_String& attr)
 {
-       
-       if (!pyobj) { // member deletion
-               RemoveProperty(attr);
-               return 0;
-       }
+       RemoveProperty(attr);
+       return 0;
+}
 
+int    CValue::_setattr(const STR_String& attr,PyObject* pyobj)
+{
        CValue* vallie = ConvertPythonToValue(pyobj);
        if (vallie)
        {
index d30e8a26d97548a40f6e6be93c40718f8cdb5f33..d49c8debfdcbe75d70244e9ece03bc9b7126f2e3 100644 (file)
@@ -249,6 +249,7 @@ public:
        virtual CValue* ConvertPythonToValue(PyObject* pyobj);
 
 
+       virtual int                             _delattr(const STR_String& attr);
        virtual int                             _setattr(const STR_String& attr,PyObject* value);
        
        KX_PYMETHOD(CValue,GetName);
index f96276c37f145d14454e6e901f4f270ceaf66179..4952c1050a78ebe17282a68ad7653fa6d2e6e3fa 100644 (file)
@@ -194,7 +194,7 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
        RemoveAllEvents();
 
        if (bNegativeEvent) return false;
-
+       
        /* The rules:                                                            */
        /* CONSTRAINT 1: not implemented */
        /* CONSTRAINT 2: can camera see actor?              */
index 0cf305dd14bf53459064f0971fa21e6bb6d5af3b..909229b04c2bd8a7a2370f544239036c0675ccc1 100644 (file)
@@ -44,7 +44,8 @@ typedef enum {
        KX_BOUNDSPHERE,
        KX_BOUNDCYLINDER,
        KX_BOUNDCONE,
-       KX_BOUNDMESH
+       KX_BOUNDMESH,
+       KX_BOUNDPOLYTOPE
 } KX_BoundBoxClass;
 
 struct KX_BoxBounds
index 3e0c7768f565e19a046748f8b3ea8594a58bb4cd..b72d17aa3b5e54f8074b84e102dca94c63f5b0dd 100644 (file)
 #include "KX_SumoPhysicsController.h"
 
 static GEN_Map<GEN_HashedPtr,DT_ShapeHandle> map_gamemesh_to_sumoshape;
+static GEN_Map<GEN_HashedPtr, DT_VertexBaseHandle> map_gamemesh_to_vertex_base_handle;
 
 // forward declarations
-void   BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,class SM_Object* sumoObj,const STR_String& matname,bool isDynamic,bool isActor);
-DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj);
+static void    BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,class SM_Object* sumoObj,const STR_String& matname,bool isDynamic,bool isActor);
+static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope);
 
 
 void   KX_ConvertSumoObject(   KX_GameObject* gameobj,
@@ -127,6 +128,7 @@ void        KX_ConvertSumoObject(   KX_GameObject* gameobj,
        if (objprop->m_dyna && objprop->m_isactor)
        {
                DT_ShapeHandle shape = NULL;
+               bool polytope = false;
                switch (objprop->m_boundclass)
                {
                        case KX_BOUNDBOX:
@@ -151,10 +153,13 @@ void      KX_ConvertSumoObject(   KX_GameObject* gameobj,
                                        smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height);
                                break;
                        /* Dynamic mesh objects.  WARNING! slow. */
+                       case KX_BOUNDPOLYTOPE:
+                               polytope = true;
+                               // fall through
                        case KX_BOUNDMESH:
                                if (meshobj && meshobj->NumPolygons() > 0)
                                {
-                                       if ((shape = CreateShapeFromMesh(meshobj)))
+                                       if ((shape = CreateShapeFromMesh(meshobj, polytope)))
                                        {
                                                // TODO: calculate proper inertia
                                                smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius;
@@ -185,6 +190,7 @@ void        KX_ConvertSumoObject(   KX_GameObject* gameobj,
                        {
 
                                DT_ShapeHandle complexshape=0;
+                               bool polytope = false;
 
                                switch (objprop->m_boundclass)
                                {
@@ -200,11 +206,14 @@ void      KX_ConvertSumoObject(   KX_GameObject* gameobj,
                                        case KX_BOUNDCONE:
                                                complexshape = DT_NewCone(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height);
                                                break;
+                                       case KX_BOUNDPOLYTOPE:
+                                               polytope = true;
+                                               // fall through
                                        default:
                                        case KX_BOUNDMESH:
                                                if (numpolys>0)
                                                {
-                                                       complexshape = CreateShapeFromMesh(meshobj);
+                                                       complexshape = CreateShapeFromMesh(meshobj, polytope);
                                                        //std::cout << "Convert Physics Mesh: " << meshobj->GetName() << std::endl;
 /*                                                     if (!complexshape) 
                                                        {
@@ -267,7 +276,7 @@ void        KX_ConvertSumoObject(   KX_GameObject* gameobj,
 
 
 
-void   BL_RegisterSumoObject(
+static void    BL_RegisterSumoObject(
        KX_GameObject* gameobj,
        class SM_Scene* sumoScene,
        class SM_Object* sumoObj,
@@ -296,21 +305,114 @@ void     BL_RegisterSumoObject(
                physicscontroller->SetObject(gameobj->GetSGNode());
 }
 
-DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj)
+static DT_ShapeHandle InstancePhysicsComplex(RAS_MeshObject* meshobj, int vtxarray, RAS_IPolyMaterial *mat)
+{
+       // instance a mesh from a single vertex array & material
+       const RAS_TexVert *vertex_array = &((*meshobj->GetVertexCache(mat)[vtxarray])[0]);
+       //const KX_IndexArray &index_array = *meshobj->GetIndexCache(mat)[vtxarray];
+       DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getLocalXYZ(), sizeof(RAS_TexVert));
+       
+       DT_ShapeHandle shape = DT_NewComplexShape(vertex_base);
+       
+       std::vector<DT_Index> indices;
+       for (int p = 0; p < meshobj->NumPolygons(); p++)
+       {
+               RAS_Polygon* poly = meshobj->GetPolygon(p);
+       
+               // only add polygons that have the collisionflag set
+               if (poly->IsCollider())
+               {
+                       DT_VertexIndices(3, poly->GetVertexIndexBase().m_indexarray);
+                       
+                       // tesselate
+                       if (poly->VertexCount() == 4)
+                       {
+                               DT_Begin();
+                                 DT_VertexIndex(poly->GetVertexIndexBase().m_indexarray[0]);
+                                 DT_VertexIndex(poly->GetVertexIndexBase().m_indexarray[2]);
+                                 DT_VertexIndex(poly->GetVertexIndexBase().m_indexarray[3]);
+                               DT_End();
+                       }
+               }
+       }
+
+       //DT_VertexIndices(indices.size(), &indices[0]);
+       DT_EndComplexShape();
+       
+       map_gamemesh_to_vertex_base_handle.insert(GEN_HashedPtr(meshobj), vertex_base);
+       return shape;
+}
+
+static DT_ShapeHandle InstancePhysicsPolytope(RAS_MeshObject* meshobj, int vtxarray, RAS_IPolyMaterial *mat)
+{
+       // instance a mesh from a single vertex array & material
+       const RAS_TexVert *vertex_array = &((*meshobj->GetVertexCache(mat)[vtxarray])[0]);
+       //const KX_IndexArray &index_array = *meshobj->GetIndexCache(mat)[vtxarray];
+       DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getLocalXYZ(), sizeof(RAS_TexVert));
+       
+       std::vector<DT_Index> indices;
+       for (int p = 0; p < meshobj->NumPolygons(); p++)
+       {
+               RAS_Polygon* poly = meshobj->GetPolygon(p);
+       
+               // only add polygons that have the collisionflag set
+               if (poly->IsCollider())
+               {
+                       indices.push_back(poly->GetVertexIndexBase().m_indexarray[0]);
+                       indices.push_back(poly->GetVertexIndexBase().m_indexarray[1]);
+                       indices.push_back(poly->GetVertexIndexBase().m_indexarray[2]);
+                       
+                       if (poly->VertexCount() == 4)
+                               indices.push_back(poly->GetVertexIndexBase().m_indexarray[3]);
+               }
+       }
+
+       DT_ShapeHandle shape = DT_NewPolytope(vertex_base);
+       DT_VertexIndices(indices.size(), &indices[0]);
+       DT_EndPolytope();
+       
+       map_gamemesh_to_vertex_base_handle.insert(GEN_HashedPtr(meshobj), vertex_base);
+       return shape;
+}
+
+// This will have to be a method in a class somewhere...
+// Update SOLID with a changed physics mesh.
+// not used... yet.
+bool ReInstanceShapeFromMesh(RAS_MeshObject* meshobj, int vtxarray, RAS_IPolyMaterial *mat)
+{
+       DT_VertexBaseHandle *vertex_base = map_gamemesh_to_vertex_base_handle[GEN_HashedPtr(meshobj)];
+       if (vertex_base)
+       {
+               const RAS_TexVert *vertex_array = &((*meshobj->GetVertexCache(mat)[vtxarray])[0]);
+               DT_ChangeVertexBase(*vertex_base, vertex_array[0].getLocalXYZ());
+               return true;
+       }
+       return false;
+}
+
+static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope)
 {
 
        DT_ShapeHandle *shapeptr = map_gamemesh_to_sumoshape[GEN_HashedPtr(meshobj)];
+       // Mesh has already been converted: reuse
        if (shapeptr)
        {
                return *shapeptr;
        }
        
+       // Mesh has no polygons!
        int numpolys = meshobj->NumPolygons();
        if (!numpolys)
        {
                return NULL;
        }
+       
+       // Count the number of collision polygons and check they all come from the same 
+       // vertex array
        int numvalidpolys = 0;
+       int vtxarray = -1;
+       RAS_IPolyMaterial *poly_material = NULL;
+       bool reinstance = true;
 
        for (int p=0; p<numpolys; p++)
        {
@@ -319,74 +421,116 @@ DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj)
                // only add polygons that have the collisionflag set
                if (poly->IsCollider())
                {
+                       // check polygon is from the same vertex array
+                       if (poly->GetVertexIndexBase().m_vtxarray != vtxarray)
+                       {
+                               if (vtxarray < 0)
+                                       vtxarray = poly->GetVertexIndexBase().m_vtxarray;
+                               else
+                               {
+                                       reinstance = false;
+                                       vtxarray = -1;
+                               }
+                       }
+                       
+                       // check poly is from the same material
+                       if (poly->GetMaterial()->GetPolyMaterial() != poly_material)
+                       {
+                               if (poly_material)
+                               {
+                                       reinstance = false;
+                                       poly_material = NULL;
+                               }
+                               else
+                                       poly_material = poly->GetMaterial()->GetPolyMaterial();
+                       }
+                       
+                       // count the number of collision polys
                        numvalidpolys++;
-                       break;
+                       
+                       // We have one collision poly, and we can't reinstance, so we
+                       // might as well break here.
+                       if (!reinstance)
+                               break;
                }
        }
        
+       // No collision polygons
        if (numvalidpolys < 1)
                return NULL;
        
-       DT_ShapeHandle shape = DT_NewComplexShape(NULL);
-       
-       
-       numvalidpolys = 0;
-
-       for (int p2=0; p2<numpolys; p2++)
+       DT_ShapeHandle shape;
+       if (reinstance)
        {
-               RAS_Polygon* poly = meshobj->GetPolygon(p2);
-       
-               // only add polygons that have the collisionflag set
-               if (poly->IsCollider())
-               {   /* We have to tesselate here because SOLID can only raycast triangles */
-                   DT_Begin();
-                       DT_Vector3 pt;
-                       /* V1 */
-                       meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-                               poly->GetVertexIndexBase().m_indexarray[2],
-                               poly->GetMaterial()->GetPolyMaterial())->xyz().getValue(pt);
-                       DT_Vertex(pt);
-                       /* V2 */
-                       meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-                               poly->GetVertexIndexBase().m_indexarray[1],
-                               poly->GetMaterial()->GetPolyMaterial())->xyz().getValue(pt);
-                       DT_Vertex(pt);
-                       /* V3 */
-                       meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-                               poly->GetVertexIndexBase().m_indexarray[0],
-                               poly->GetMaterial()->GetPolyMaterial())->xyz().getValue(pt);
-                       DT_Vertex(pt);
-                       
-                       numvalidpolys++;
-                   DT_End();
+               if (polytope)
+                       shape = InstancePhysicsPolytope(meshobj, vtxarray, poly_material);
+               else
+                       shape = InstancePhysicsComplex(meshobj, vtxarray, poly_material);
+       }
+       else
+       {
+               if (polytope)
+               {
+                       std::cout << "CreateShapeFromMesh: " << meshobj->GetName() << " is not suitable for polytope." << std::endl;
+                       if (!poly_material)
+                               std::cout << "                     Check mesh materials." << std::endl;
+                       if (vtxarray < 0)
+                               std::cout << "                     Check number of vertices." << std::endl;
+               }
+               
+               shape = DT_NewComplexShape(NULL);
                        
-                       if (poly->VertexCount() == 4)
-                       {
-                           DT_Begin();
+               numvalidpolys = 0;
+       
+               for (int p2=0; p2<numpolys; p2++)
+               {
+                       RAS_Polygon* poly = meshobj->GetPolygon(p2);
+               
+                       // only add polygons that have the collisionflag set
+                       if (poly->IsCollider())
+                       {   /* We have to tesselate here because SOLID can only raycast triangles */
+                          DT_Begin();
                                /* V1 */
-                               meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
-                                       poly->GetVertexIndexBase().m_indexarray[3],
-                                       poly->GetMaterial()->GetPolyMaterial())->xyz().getValue(pt);
-                               DT_Vertex(pt);
-                               /* V3 */
-                               meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+                               DT_Vertex(meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
                                        poly->GetVertexIndexBase().m_indexarray[2],
-                                       poly->GetMaterial()->GetPolyMaterial())->xyz().getValue(pt);
-                               DT_Vertex(pt);
-                               /* V4 */
-                               meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+                                       poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ());
+                               /* V2 */
+                               DT_Vertex(meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+                                       poly->GetVertexIndexBase().m_indexarray[1],
+                                       poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ());
+                               /* V3 */
+                               DT_Vertex(meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
                                        poly->GetVertexIndexBase().m_indexarray[0],
-                                       poly->GetMaterial()->GetPolyMaterial())->xyz().getValue(pt);
-                               DT_Vertex(pt);
-                       
+                                       poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ());
+                               
                                numvalidpolys++;
-                           DT_End();
+                          DT_End();
+                               
+                               if (poly->VertexCount() == 4)
+                               {
+                                  DT_Begin();
+                                       /* V1 */
+                                       DT_Vertex(meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+                                               poly->GetVertexIndexBase().m_indexarray[3],
+                                               poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ());
+                                       /* V3 */
+                                       DT_Vertex(meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+                                               poly->GetVertexIndexBase().m_indexarray[2],
+                                               poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ());
+                                       /* V4 */
+                                       DT_Vertex(meshobj->GetVertex(poly->GetVertexIndexBase().m_vtxarray, 
+                                               poly->GetVertexIndexBase().m_indexarray[0],
+                                               poly->GetMaterial()->GetPolyMaterial())->getLocalXYZ());
+                               
+                                       numvalidpolys++;
+                                  DT_End();
+                               }
+               
                        }
-       
                }
+               
+               DT_EndComplexShape();
        }
-       
-       DT_EndComplexShape();
 
        if (numvalidpolys > 0)
        {
@@ -398,17 +542,22 @@ DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj)
        return NULL;
 }
 
-
 void   KX_ClearSumoSharedShapes()
 {
        int numshapes = map_gamemesh_to_sumoshape.size();
-       for (int i=0;i<numshapes ;i++)
+       int i;
+       for (i=0;i<numshapes ;i++)
        {
                DT_ShapeHandle shape = *map_gamemesh_to_sumoshape.at(i);
                DT_DeleteShape(shape);
        }
        
        map_gamemesh_to_sumoshape.clear();
+       
+       for (i=0; i < map_gamemesh_to_vertex_base_handle.size(); i++)
+               DT_DeleteVertexBase(*map_gamemesh_to_vertex_base_handle.at(i));
+       
+       map_gamemesh_to_vertex_base_handle.clear();
 }
 
 
index 52d9d3e47907d0ed7ff5162acc1c842dc3254316..08464fc88de4e77ca7cd8045a3d0d46df0179c0c 100644 (file)
@@ -276,7 +276,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
                                m_direction = 1;
                        SetStartTime(curtime);
                }
-
+               
                SetLocalTime(curtime);
                
                if (ClampLocalTime() && m_localtime == m_startframe)
index bd84e7e0104aadfe668f45a39030a5ad2b1a456d..3bd36aebc93f48a4d0f58351800ab5025b470a10 100644 (file)
@@ -315,13 +315,13 @@ void KX_KetsjiEngine::NextFrame()
        m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
 
        double curtime;
-       double localtime = m_previoustime;
        if (m_bFixedTime)
                curtime = m_previoustime + 1.0/m_ticrate;
        else
                curtime = m_kxsystem->GetTimeInSeconds();
        m_deltatime += curtime - m_previoustime;
        m_previoustime = curtime;
+       double localtime = curtime - m_deltatime;
 
        // Compute the number of logic frames to do each update (fixed tic bricks)
        int frames = (int) (m_deltatime*m_ticrate);
@@ -329,44 +329,7 @@ void KX_KetsjiEngine::NextFrame()
        
        KX_SceneList::iterator sceneit;
        
-       if (!frames)
-       {
-               for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
-               // for each scene, call the proceed functions
-               {
-                       KX_Scene* scene = *sceneit;
-       
-                       if (!scene->IsSuspended())
-                       {
-                               // set Python hooks for each scene
-                               PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
-                               PHY_SetActiveScene(scene);
-                               
-                               // Perform physics calculations on the scene. This can involve 
-                               // many iterations of the physics solver.
-                               m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->GetPhysicsEnvironment()->proceed(curtime);
-                               // Update scenegraph after physics step. This maps physics calculations
-                               // into node positions.         
-                               m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->UpdateParents(curtime);
-                               
-                               // Do some cleanup work for this logic frame
-                               m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->LogicUpdateFrame(curtime, false);
-       
-                               // Actuators can affect the scenegraph
-                               m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->UpdateParents(curtime);
-                       } // suspended
-       
-                       DoSound(scene);
-       
-                       m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
-               }
-       }
-       
-       while (frames--)
+       while (frames)
        {
                localtime += 1.0/m_ticrate;
                for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
@@ -384,44 +347,46 @@ void KX_KetsjiEngine::NextFrame()
                        if (!scene->IsSuspended())
                        {
                                m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->GetPhysicsEnvironment()->endFrame();
-                               scene->GetPhysicsEnvironment()->beginFrame();
-                       
                                m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->GetNetworkScene()->proceed(curtime);
+                               scene->GetNetworkScene()->proceed(localtime);
        
                                // set Python hooks for each scene
                                PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
                                PHY_SetActiveScene(scene);
        
-                               // Perform physics calculations on the scene. This can involve 
-                               // many iterations of the physics solver.
-                               m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->GetPhysicsEnvironment()->proceed(curtime);
+                               scene->GetPhysicsEnvironment()->endFrame();
+                               
                                // Update scenegraph after physics step. This maps physics calculations
                                // into node positions.         
                                m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->UpdateParents(curtime);
+                               scene->UpdateParents(localtime);
                                
                                // Process sensors, and controllers
                                m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->LogicBeginFrame(curtime);
+                               scene->LogicBeginFrame(localtime);
        
                                // Scenegraph needs to be updated again, because Logic Controllers 
                                // can affect the local matrices.
                                m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->UpdateParents(curtime);
+                               scene->UpdateParents(localtime);
        
                                // Process actuators
        
                                // Do some cleanup work for this logic frame
                                m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->LogicUpdateFrame(curtime, true);
+                               scene->LogicUpdateFrame(localtime, true);
                                scene->LogicEndFrame();
        
                                // Actuators can affect the scenegraph
                                m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
-                               scene->UpdateParents(curtime);
+                               scene->UpdateParents(localtime);
+                               
+                               scene->GetPhysicsEnvironment()->beginFrame();
+               
+                               // Perform physics calculations on the scene. This can involve 
+                               // many iterations of the physics solver.
+                               m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
+                               scene->GetPhysicsEnvironment()->proceed(localtime);
                        } // suspended
        
                        DoSound(scene);
@@ -445,8 +410,46 @@ void KX_KetsjiEngine::NextFrame()
        
                // scene management
                ProcessScheduledScenes();
+               
+               frames--;
        }
 
+       // Logic update sub frame: this will let some logic bricks run at the
+       // full frame rate.
+       for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
+       // for each scene, call the proceed functions
+       {
+               KX_Scene* scene = *sceneit;
+
+               if (!scene->IsSuspended())
+               {
+                       // set Python hooks for each scene
+                       PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
+                       PHY_SetActiveScene(scene);
+                       
+                       // Perform physics calculations on the scene. This can involve 
+                       // many iterations of the physics solver.
+                       m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
+                       scene->GetPhysicsEnvironment()->proceed(curtime);
+                       // Update scenegraph after physics step. This maps physics calculations
+                       // into node positions.         
+                       m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+                       scene->UpdateParents(curtime);
+                       
+                       // Do some cleanup work for this logic frame
+                       m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
+                       scene->LogicUpdateFrame(curtime, false);
+
+                       // Actuators can affect the scenegraph
+                       m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
+                       scene->UpdateParents(curtime);
+               } // suspended
+
+               DoSound(scene);
+
+               m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
+       }
+       
        // Start logging time spend outside main loop
        m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true);
 }
index f10ea902c96b4bd9b6de5d08237e807cec35e0c5..26825fe5e1f372b7278cd3de41f2d23177616276 100644 (file)
@@ -860,7 +860,7 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
                                for (int m=0;m<nummeshes;m++)
                                {
                                        // this adds the vertices to the display list
-                                       (gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode(),rasty);
+                                       (gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode());
                                }
                        }
                        gameobj->MarkVisible(visible);
@@ -916,7 +916,7 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj)
                for (int m=0;m<nummeshes;m++)
                {
                        // this adds the vertices to the display list
-                       (gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode(),rasty);
+                       (gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode());
                }
                // Visibility/ non-visibility are marked
                // elsewhere now.
@@ -1186,6 +1186,12 @@ PyObject* KX_Scene::_getattr(const STR_String& attr)
        _getattr_up(PyObjectPlus);
 }
 
+int KX_Scene::_delattr(const STR_String &attr)
+{
+       PyDict_DelItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()));
+       return 0;
+}
+
 int KX_Scene::_setattr(const STR_String &attr, PyObject *pyvalue)
 {
 
index 2f867c28c40f1b3eaf5162050aced80e39618da6..74161a4d5b8581f56ec3262581d0cd19f22307b8 100644 (file)
@@ -514,6 +514,7 @@ public:
 
        virtual PyObject* _getattr(const STR_String& attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */
        virtual int _setattr(const STR_String &attr, PyObject *pyvalue);
+       virtual int _delattr(const STR_String &attr);
 };
 
 typedef std::vector<KX_Scene*> KX_SceneList;
index 4f074ce9b12ec312918ada05c8c62cd8dd93fb8c..a95e6a135486968a11d97302556ddddc1e6594b7 100644 (file)
 
 #include "SM_Object.h"
 
-KX_TouchEventManager::Collision::Collision(SCA_ISensor *sensor, SM_Object *obj1, SM_Object *obj2)
-       : m_id(next_id++),
-         m_sensor(sensor),
-         m_object1(obj1),
-         m_object2(obj2)
-{
-}
-
-bool KX_TouchEventManager::Collision::operator<(const Collision &other) const
-{
-       if (*this == other)
-               return true;
-               
-       return m_id < other.m_id;
-}
-               
-bool KX_TouchEventManager::Collision::operator==(const Collision &other) const
-{
-       return m_sensor == other.m_sensor && 
-               ((m_object1 == other.m_object1 && m_object2 == other.m_object2) ||
-                (m_object1 == other.m_object2 && m_object2 == other.m_object1));
-}
-
-int KX_TouchEventManager::Collision::next_id = 0;
-
 KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr,
        SM_Scene *scene)
        : SCA_EventManager(TOUCH_EVENTMGR),
@@ -80,15 +55,8 @@ DT_Bool KX_TouchEventManager::HandleCollision(void* object1, void* object2, cons
 {
        SM_Object * obj1 = static_cast<SM_Object*>(object1);
        SM_Object * obj2 = static_cast<SM_Object*>(object2);
-       KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>(obj1->getClientObject());
        
-       list<SCA_ISensor*>::iterator it;
-       for ( it = client_info->m_sensors.begin(); it != client_info->m_sensors.end(); ++it)
-               m_collisions.insert(Collision(*it, obj1, obj2));
-
-       client_info = static_cast<KX_ClientObjectInfo *>(obj2->getClientObject());
-       for ( it = client_info->m_sensors.begin(); it != client_info->m_sensors.end(); ++it)
-               m_collisions.insert(Collision(*it, obj2, obj1));
+       m_collisions.insert(std::pair<SM_Object*, SM_Object*>(obj1, obj2));
                
        return DT_CONTINUE;
 }
@@ -164,7 +132,17 @@ void KX_TouchEventManager::NextFrame()
                        static_cast<KX_TouchSensor*>(*it)->SynchronizeTransform();
                
                for (std::set<Collision>::iterator cit = m_collisions.begin(); cit != m_collisions.end(); ++cit)
-                       static_cast<KX_TouchSensor*>((*cit).m_sensor)->HandleCollision((*cit).m_object1, (*cit).m_object2, NULL);
+               {
+                       KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>((*cit).first->getClientObject());
+       
+                       list<SCA_ISensor*>::iterator sit;
+                       for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit)
+                               static_cast<KX_TouchSensor*>(*sit)->HandleCollision((*cit).first, (*cit).second, NULL);
+               
+                       client_info = static_cast<KX_ClientObjectInfo *>((*cit).second->getClientObject());
+                       for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit)
+                               static_cast<KX_TouchSensor*>(*sit)->HandleCollision((*cit).second, (*cit).first, NULL);
+               }
                        
                m_collisions.clear();
                        
@@ -184,6 +162,7 @@ void KX_TouchEventManager::RemoveSensor(class SCA_ISensor* sensor)
                std::swap(*i, m_sensors.back());
                m_sensors.pop_back();
        }
+       
        // remove the sensor forever :)
        SCA_EventManager::RemoveSensor(sensor);
 }
index eb2c26a64f32db9e13171de5208e57ae9a958596..128758f0be6c3573898bf708054b233976df27d1 100644 (file)
@@ -44,20 +44,7 @@ class SM_Object;
 
 class KX_TouchEventManager : public SCA_EventManager
 {
-       struct Collision
-       {
-               static int next_id;
-               int          m_id;
-               SCA_ISensor *m_sensor;
-               SM_Object   *m_object1;
-               SM_Object   *m_object2;
-               
-               Collision(SCA_ISensor *sensor, SM_Object *obj1, SM_Object *obj2);
-               
-               bool operator<(const Collision &other) const;
-               bool operator==(const Collision &other) const;
-       };
-
+       typedef std::pair<SM_Object*, SM_Object*> Collision;
        class SCA_LogicManager* m_logicmgr;
        SM_Scene *m_scene;
        
index 116eed12ceaa26f5b6ad446f32ee4a0829192119..4db531d945d2584b3e24efd4e902060ffd365713 100644 (file)
@@ -40,7 +40,7 @@ public:
        SM_FhObject(DT_ShapeHandle rayshape, MT_Vector3 ray, SM_Object *parent_object);
 
        const MT_Vector3&  getRay()          const { return m_ray; }
-       MT_Point3          getSpot()         const { return m_pos + m_ray; }
+       MT_Point3          getSpot()         const { return getPosition() + m_ray; }
        const MT_Vector3&  getRayDirection() const { return m_ray_direction; }
        SM_Object         *getParentObject() const { return m_parent_object; }
 
index e7fbf3cdacc05a55a4435134167a31a627fb9f17..b0e0717cf8cf8b1e16513d593b50812ef9178062 100644 (file)
@@ -1,3 +1,34 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
 #ifndef SM_MOTIONSTATE_H
 #define SM_MOTIONSTATE_H
 
@@ -6,6 +37,7 @@
 class SM_MotionState {
 public:
        SM_MotionState() :
+               m_time(0.0),
                m_pos(0.0, 0.0, 0.0),
                m_orn(0.0, 0.0, 0.0, 1.0),
                m_lin_vel(0.0, 0.0, 0.0),
@@ -16,17 +48,27 @@ public:
        void setOrientation(const MT_Quaternion& orn)      { m_orn = orn; }
        void setLinearVelocity(const MT_Vector3& lin_vel)  { m_lin_vel = lin_vel; }
        void setAngularVelocity(const MT_Vector3& ang_vel) { m_ang_vel = ang_vel; }
+       void setTime(MT_Scalar time)                       { m_time = time; }
        
        const MT_Point3&     getPosition()        const { return m_pos; }
        const MT_Quaternion& getOrientation()     const { return m_orn; }
        const MT_Vector3&    getLinearVelocity()  const { return m_lin_vel; }
        const MT_Vector3&    getAngularVelocity() const { return m_ang_vel;     }
        
+       MT_Scalar            getTime()            const { return m_time; }
+       
+       void integrateMidpoint(MT_Scalar timeStep, const SM_MotionState &prev_state, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel);
+       void integrateBackward(MT_Scalar timeStep, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel);
+       void integrateForward(MT_Scalar timeStep, const SM_MotionState &prev_state);
+       
+       void lerp(MT_Scalar t, const SM_MotionState &other);
+       
        virtual MT_Transform getTransform() const {
                return MT_Transform(m_pos, m_orn);
        }
 
 protected:
+       MT_Scalar         m_time;
        MT_Point3         m_pos;
        MT_Quaternion     m_orn;
        MT_Vector3        m_lin_vel;
index 4a69f7e2990fd51fc41cb482b64520a0e305f95b..b37e1a5466b0d4848ed7572c933d614176272331 100644 (file)
@@ -144,7 +144,6 @@ public:
        void setOrientation(const MT_Quaternion& orn);
        void setScaling(const MT_Vector3& scaling);
        
-
        /**
         * set an external velocity. This velocity complements
         * the physics velocity. So setting it does not override the
@@ -267,13 +266,7 @@ public:
        
        void relax();
        
-       void backup() {
-               m_pos = m_prev_state.getPosition();
-               m_orn = m_prev_state.getOrientation();
-               m_xform = m_prev_xform;
-       }
 private:
-
        // Tweak parameters
        static MT_Scalar ImpulseThreshold;
 
index 0b429a3c1a43fc99a057d38935cb6f7cada3843b..80e8c635cbb0fdd11e5f99f36f2b927d4b40bac4 100644 (file)
@@ -88,13 +88,7 @@ public:
     void add(SM_Object& object);
     void remove(SM_Object& object);
 
-       void addPair(SM_Object *obj1, SM_Object *obj2) {
-               m_pairList.insert(std::make_pair(obj1, obj2));
-       }
-
-       void clearPairs() {
-               m_pairList.clear();
-       }
+       void notifyCollision(SM_Object *obj1, SM_Object *obj2);
 
        void setSecondaryRespTable(DT_RespTableHandle secondaryRespTable); 
        DT_RespTableHandle getSecondaryRespTable() { return m_secondaryRespTable; }
@@ -146,8 +140,6 @@ private:
        
        /** internal type */
        typedef std::vector<SM_Object *> T_ObjectList;
-       /** internal type */
-       typedef std::set<std::pair<SM_Object *, SM_Object *> > T_PairList;
 
        /** Handle to the scene in SOLID */
        DT_SceneHandle      m_scene;
@@ -174,12 +166,6 @@ private:
         * The list of objects that receive motion updates and do
         * collision tests. */
        T_ObjectList        m_objectList;
-
-       /**
-        * A list with pairs of objects that collided the previous
-        * timestep. The list is built during the proceed(). During that
-        * time, it is not valid. */
-       T_PairList          m_pairList;
        
        MT_Scalar           m_lastTime;
 };
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp
new file mode 100644 (file)
index 0000000..a3285b1
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <MT_Vector3.h>
+#include <MT_Quaternion.h>
+#include "SM_MotionState.h"
+
+void SM_MotionState::integrateMidpoint(MT_Scalar timeStep, const SM_MotionState &prev_state, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel)
+{
+       m_pos += (prev_state.getLinearVelocity() + velocity) * (timeStep * 0.5);
+       m_orn += (prev_state.getAngularVelocity() * prev_state.getOrientation() + ang_vel * m_orn) * (timeStep * 0.25);
+       m_orn.normalize();
+}
+
+void SM_MotionState::integrateBackward(MT_Scalar timeStep, const MT_Vector3 &velocity, const MT_Quaternion& ang_vel)
+{
+       m_pos += velocity * timeStep;
+       m_orn += ang_vel * m_orn * (timeStep * 0.5);
+       m_orn.normalize();
+}
+
+void SM_MotionState::integrateForward(MT_Scalar timeStep, const SM_MotionState &prev_state)
+{
+       m_pos += prev_state.getLinearVelocity() * timeStep;
+       m_orn += prev_state.getAngularVelocity() * m_orn * (timeStep * 0.5);
+       m_orn.normalize();
+}
+
+void SM_MotionState::lerp(MT_Scalar t, const SM_MotionState &other)
+{
+       MT_Scalar x = (t - getTime())/(other.getTime() - getTime());
+       m_pos = x*m_pos + (1-x)*other.getPosition();
+       
+       m_orn = m_orn.slerp(other.getOrientation(), x);
+       
+       m_lin_vel = x*m_lin_vel + (1-x)*other.getLinearVelocity();
+       m_ang_vel = x*m_ang_vel + (1-x)*other.getAngularVelocity();
+       
+       m_time = t;
+}
+
index 42adfcd4d9e89a946419c28eda3159152d72c66e..ed5171a87a27589b66e20eabbd8500b76801674a 100644 (file)
@@ -65,7 +65,6 @@ SM_Object::SM_Object(
        m_materialPropsBackup(0),
        m_shapeProps(shapeProps),
        m_shapePropsBackup(0),
-       m_object(DT_CreateObject(this, shape)),
        m_margin(0.0),
        m_scaling(1.0, 1.0, 1.0),
        m_reaction_impulse(0.0, 0.0, 0.0),
@@ -84,6 +83,7 @@ SM_Object::SM_Object(
        m_inv_mass(0.0),
        m_inv_inertia(0., 0., 0.)
 {
+       m_object = DT_CreateObject(this, shape);
        m_xform.setIdentity();
        m_xform.getValue(m_ogl_matrix);
        if (shapeProps)
@@ -146,19 +146,14 @@ integrateMomentum(
 //#define BACKWARD
 #ifdef  MIDPOINT
 // Midpoint rule
-               m_pos += (m_prev_state.getLinearVelocity() + actualLinVelocity()) * (timeStep * 0.5);
-               m_orn += (m_prev_state.getAngularVelocity() * m_prev_state.getOrientation() + actualAngVelocity() * m_orn) * (timeStep * 0.25);
+               integrateMidpoint(timeStep, m_prev_state, actualLinVelocity(), actualAngVelocity());
 #elif defined BACKWARD
 // Backward Euler
-               m_pos += actualLinVelocity() * timeStep;
-               m_orn += actualAngVelocity() * m_orn * (timeStep * 0.5);
+               integrateBackward(timeStep, actualLinVelocity(), actualAngVelocity());
 #else 
 // Forward Euler
-
-               m_pos += m_prev_state.getLinearVelocity() * timeStep;
-               m_orn += m_prev_state.getAngularVelocity() * m_orn * (timeStep * 0.5);
+               integrateForward(timeStep, m_prev_state);
 #endif
-               m_orn.normalize(); // I might not be necessary to do this every call
 
                calcXform();
                notifyClient();         
@@ -212,7 +207,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2,
                         * Apply impulse at the collision point.
                         * Take rotational inertia into account.
                         */
-                       applyImpulse(local2 + m_pos, impulse * normal);
+                       applyImpulse(local2 + getPosition(), impulse * normal);
                } else {
                        /**
                         * Apply impulse through object centre. (no rotation.)
@@ -323,7 +318,7 @@ void SM_Object::dynamicCollision(const MT_Point3 &local2,
                                        (invMass + lateral.dot(temp.cross(local2)));
 
                                MT_Scalar friction = MT_min(impulse_lateral, max_friction);
-                               applyImpulse(local2 + m_pos, -lateral * friction);
+                               applyImpulse(local2 + getPosition(), -lateral * friction);
                        }
                        else {
                                MT_Scalar impulse_lateral = rel_vel_lateral / invMass;
@@ -349,7 +344,7 @@ static void AddCallback(SM_Scene *scene, SM_Object *obj1, SM_Object *obj2)
        if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) || 
            (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback()) &&
             DT_GetIntersect(obj1->getObjectHandle(), obj2->getObjectHandle(), v))
-               scene->addPair(obj1, obj2);
+               scene->notifyCollision(obj1, obj2);
 }
 
 DT_Bool SM_Object::boing(
@@ -402,10 +397,10 @@ DT_Bool SM_Object::boing(
        // Set callbacks for game engine.
        if ((obj1->getClientObject() && obj1->getClientObject()->hasCollisionCallback()) || 
            (obj2->getClientObject() && obj2->getClientObject()->hasCollisionCallback()))
-               scene->addPair(obj1, obj2);
+               scene->notifyCollision(obj1, obj2);
        
-       local1 -= obj1->m_pos;
-       local2 -= obj2->m_pos;
+       local1 -= obj1->getPosition();
+       local2 -= obj2->getPosition();
        
        // Calculate collision parameters
        MT_Vector3 rel_vel        = obj1->getVelocity(local1) - obj2->getVelocity(local2);
@@ -492,7 +487,7 @@ void SM_Object::relax(void)
                return;
        //std::cout << "SM_Object::relax: { " << m_error << " }" << std::endl;
        
-       m_pos += m_error
+       setPosition(getPosition() + m_error)
        m_error.setValue(0., 0., 0.); 
        calcXform();
        notifyClient();
@@ -641,15 +636,15 @@ calcXform() {
        printf("                 m_scaling = { %-0.5f, %-0.5f, %-0.5f }\n",
                m_scaling[0], m_scaling[1], m_scaling[2]);
 #endif
-       m_xform.setOrigin(m_pos);
-       m_xform.setBasis(MT_Matrix3x3(m_orn, m_scaling));
+       m_xform.setOrigin(getPosition());
+       m_xform.setBasis(MT_Matrix3x3(getOrientation(), m_scaling));
        m_xform.getValue(m_ogl_matrix);
        
        /* Blender has been known to crash here.
           This usually means SM_Object *this has been deleted more than once. */
        DT_SetMatrixd(m_object, m_ogl_matrix);
        if (m_fh_object) {
-               m_fh_object->setPosition(m_pos);
+               m_fh_object->setPosition(getPosition());
                m_fh_object->calcXform();
        }
        updateInvInertiaTensor();
@@ -765,9 +760,9 @@ setPosition(
        const MT_Point3& pos
 ){
        m_kinematic = true;
-       m_pos = pos;
+       SM_MotionState::setPosition(pos);
 }
-
+       
        void 
 SM_Object::
 setOrientation(
@@ -775,7 +770,7 @@ setOrientation(
 ){
        assert(!orn.fuzzyZero());
        m_kinematic = true;
-       m_orn = orn;
+       SM_MotionState::setOrientation(orn);
 }
 
        void 
index 1ea19c56336769c8b990f39f07f708f5bcb52d81..c29be228d64bb19521090b1d4090e0af4d0fe003 100644 (file)
@@ -65,21 +65,21 @@ SM_Scene::SM_Scene() :
        
        /* Sensor */
        DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this);
-       DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Scene::boing, DT_BROAD_RESPONSE, this);
-       DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Scene::boing, DT_BROAD_RESPONSE, this);
+       DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this);
+       DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this);
        DT_AddPairResponse(m_respTable, m_ResponseClass[SENSOR_RESPONSE], m_ResponseClass[FH_RESPONSE], 0, DT_NO_RESPONSE, this);
        
        /* Static */
-       DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_BROAD_RESPONSE, this);
+       DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this);
        DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[STATIC_RESPONSE], 0, DT_NO_RESPONSE, this);
        DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this);
-       DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this);
+       DT_AddPairResponse(m_respTable, m_ResponseClass[STATIC_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
        
        /* Object */
-       DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_BROAD_RESPONSE, this);
+       DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], SM_Scene::boing, DT_SIMPLE_RESPONSE, this);
        DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[STATIC_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this);
        DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[OBJECT_RESPONSE], SM_Object::boing, DT_BROAD_RESPONSE, this);
-       DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_BROAD_RESPONSE, this);
+       DT_AddPairResponse(m_respTable, m_ResponseClass[OBJECT_RESPONSE], m_ResponseClass[FH_RESPONSE], SM_FhObject::ray_hit, DT_SIMPLE_RESPONSE, this);
        
        /* Fh Object */
        DT_AddPairResponse(m_respTable, m_ResponseClass[FH_RESPONSE], m_ResponseClass[SENSOR_RESPONSE], 0, DT_NO_RESPONSE, this);
@@ -187,8 +187,30 @@ bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
        // Divide the timeStep into a number of subsamples of size roughly 
        // equal to subS (might be a little smaller).
        MT_Scalar timeStep = curtime - m_lastTime;
-       MT_Scalar subStep = 1.0/ticrate;
-       int num_samples = int(timeStep * ticrate);
+       MT_Scalar subStep;
+       int num_samples;
+       
+       if (ticrate > 0.0)
+       {
+               subStep = 1.0/ticrate;
+               num_samples = int(timeStep * ticrate);
+       
+               if (num_samples > 4)
+               {
+                       std::cout << "Dropping physics frames! step: " << timeStep << " frames:" << num_samples << std::endl;
+                       num_samples /= 4;
+                       subStep *= 4.0;
+               }
+       } 
+       else
+       {
+               // Variable time step. (old update)
+               // Integrate at least 100 Hz
+               subStep = timeStep > 0.01 ? 0.01 : timeStep;
+               num_samples = int(timeStep * 0.01);
+               if (num_samples < 1)
+                       num_samples = 1;
+       }
        
        T_ObjectList::iterator i;
        
@@ -209,7 +231,7 @@ bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
 #endif
                return false;   
        }
-
+       
        m_lastTime += MT_Scalar(num_samples)*subStep;
        
        // Do the integration steps per object.
@@ -253,24 +275,17 @@ bool SM_Scene::proceed(MT_Scalar curtime, MT_Scalar ticrate) {
                        //(*i)->clearForce();
                }
        }
-       // For each pair of object that collided, call the corresponding callback.
-       // Additional collisions of a pair within the same time step are ignored.
-
-       if (m_secondaryRespTable) {
-               T_PairList::iterator p;
-               for (p = m_pairList.begin(); p != m_pairList.end(); ++p) {
-                       DT_CallResponse(m_secondaryRespTable, 
-                                                       (*p).first->getObjectHandle(), 
-                                                       (*p).second->getObjectHandle(), 
-                                                       0);
-               }
-       }
-       
-       clearPairs();
-       
        return true;
 }
 
+void SM_Scene::notifyCollision(SM_Object *obj1, SM_Object *obj2)
+{
+       // For each pair of object that collided, call the corresponding callback.
+       if (m_secondaryRespTable)
+               DT_CallResponse(m_secondaryRespTable, obj1->getObjectHandle(), obj2->getObjectHandle(), 0);
+}
+
+
 SM_Object *SM_Scene::rayTest(void *ignore_client, 
                                                         const MT_Point3& from, const MT_Point3& to, 
                                                         MT_Point3& result, MT_Vector3& normal) const {
@@ -320,13 +335,13 @@ DT_Bool SM_Scene::boing(
        void *client_data,  
        void *object1,
        void *object2,
-       const DT_CollData *coll_data
+       const DT_CollData *
 ){
        SM_Scene  *scene = (SM_Scene *)client_data; 
        SM_Object *obj1  = (SM_Object *)object1;  
        SM_Object *obj2  = (SM_Object *)object2;  
        
-       scene->addPair(obj1, obj2); // Record this collision for client callbacks
+       scene->notifyCollision(obj1, obj2); // Record this collision for client callbacks
 
 #ifdef SM_DEBUG_BOING  
        printf("SM_Scene::boing\n");
index 63261f6f627c42957d2868e3500b3b7d27076522..4e2ea9f566ff3b6150903624f1984e2feca49660 100755 (executable)
@@ -9,7 +9,9 @@ source_files = ['SumoPhysicsController.cpp',
                 'SumoPhysicsEnvironment.cpp',
                 'Fuzzics/src/SM_FhObject.cpp',
                 'Fuzzics/src/SM_Object.cpp',
-                'Fuzzics/src/SM_Scene.cpp']
+                'Fuzzics/src/SM_Scene.cpp',
+               'Fuzzics/src/SM_MotionState.cpp'
+               ]
 
 phy_sumo_env.Append (CPPPATH = ['.',
                                 '../common',
index 4c24a58237c2994b9ad72c0ae3a530832c21a574..bfc4c3012c3198abba6e8eaada73da385cf2dfa0 100644 (file)
@@ -636,7 +636,7 @@ void RAS_MeshObject::SortPolygons(const MT_Transform &transform)
 }
 
 
-void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawingmode,RAS_IRasterizer* rasty)
+void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawingmode)
 {
 //     int nummaterials = m_materials.size();
        int i;
@@ -654,8 +654,8 @@ void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawing
 
                int numpolys = m_Polygons.size();
                
-               if ((rasty->GetDrawingMode() > RAS_IRasterizer::KX_BOUNDINGBOX) && 
-                       (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID))
+               if ((drawingmode > RAS_IRasterizer::KX_BOUNDINGBOX) && 
+                       (drawingmode < RAS_IRasterizer::KX_SOLID))
                {
                        for (i=0;i<numpolys;i++)
                        {
@@ -684,7 +684,7 @@ void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawing
                m_bModified = false;
        } 
        
-       if (m_zsort && rasty->GetDrawingMode() >= RAS_IRasterizer::KX_SOLID)
+       if (m_zsort && drawingmode >= RAS_IRasterizer::KX_SOLID)
        {
                SortPolygons(transform);
        }
index f2be0355c6e70fdb71c122fc6cd54076788377ee..367aab750e0af80dc0ea983364cb11969c6a651c 100644 (file)
@@ -197,8 +197,7 @@ public:
 
        void                            SchedulePolygons(
                                                        const MT_Transform &transform,
-                                                       int drawingmode,
-                                                       class RAS_IRasterizer* rasty
+                                                       int drawingmode
                                                );
 
        void                            ClearArrayData();