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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>2004-11-22 13:19:19 +0300
committerKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>2004-11-22 13:19:19 +0300
commit46fbe6b01e095ddb66f3bf6e0516569cfdca8f74 (patch)
treee7a7754188ef9b290eca479df6ac59b00ea7478b /source/gameengine
parentcf91617d7829647629c8ce04b9f047dfbdf3d910 (diff)
Fix for bugs: 1788 (forces) and 1799 (python delattr on game objects)
Use Polytope collision for faster mesh intersection tests, so SOLID can actually use that qhull lib now.
Diffstat (limited to 'source/gameengine')
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp8
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp5
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h92
-rw-r--r--source/gameengine/Expressions/Value.cpp13
-rw-r--r--source/gameengine/Expressions/Value.h1
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h3
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp269
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp107
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h1
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp47
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.h15
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h2
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h42
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h7
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h16
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp71
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp39
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp67
-rwxr-xr-xsource/gameengine/Physics/Sumo/SConscript4
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp8
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h3
24 files changed, 544 insertions, 290 deletions
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index e0d460d18d6..7fa2b68e0c2 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -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)
{
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index 88a38b35ad4..2b331d7f728 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -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);
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index 05c806ec4ff..7e6b3f29bab 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -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_
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index 07505829737..9233a10b784 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -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)
{
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index d30e8a26d97..d49c8debfdc 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -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);
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index f96276c37f1..4952c1050a7 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -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? */
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
index 0cf305dd14b..909229b04c2 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
@@ -44,7 +44,8 @@ typedef enum {
KX_BOUNDSPHERE,
KX_BOUNDCYLINDER,
KX_BOUNDCONE,
- KX_BOUNDMESH
+ KX_BOUNDMESH,
+ KX_BOUNDPOLYTOPE
} KX_BoundBoxClass;
struct KX_BoxBounds
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 3e0c7768f56..b72d17aa3b5 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -78,10 +78,11 @@
#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();
}
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index 52d9d3e4790..08464fc88de 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -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)
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index bd84e7e0104..3bd36aebc93 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -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);
}
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index f10ea902c96..26825fe5e1f 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -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)
{
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 2f867c28c40..74161a4d5b8 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -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;
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
index 4f074ce9b12..a95e6a13548 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -40,31 +40,6 @@
#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);
}
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h
index eb2c26a64f3..128758f0be6 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.h
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.h
@@ -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;
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h
index 116eed12cea..4db531d945d 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_FhObject.h
@@ -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; }
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
index e7fbf3cdacc..b0e0717cf8c 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_MotionState.h
@@ -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;
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
index 4a69f7e2990..b37e1a5466b 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Object.h
@@ -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;
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
index 0b429a3c1a4..80e8c635cbb 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
@@ -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
index 00000000000..a3285b19116
--- /dev/null
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_MotionState.cpp
@@ -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;
+}
+
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
index 42adfcd4d9e..ed5171a87a2 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Object.cpp
@@ -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
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
index 1ea19c56336..c29be228d64 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
+++ b/source/gameengine/Physics/Sumo/Fuzzics/src/SM_Scene.cpp
@@ -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");
diff --git a/source/gameengine/Physics/Sumo/SConscript b/source/gameengine/Physics/Sumo/SConscript
index 63261f6f627..4e2ea9f566f 100755
--- a/source/gameengine/Physics/Sumo/SConscript
+++ b/source/gameengine/Physics/Sumo/SConscript
@@ -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',
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 4c24a58237c..bfc4c3012c3 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -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);
}
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index f2be0355c6e..367aab750e0 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -197,8 +197,7 @@ public:
void SchedulePolygons(
const MT_Transform &transform,
- int drawingmode,
- class RAS_IRasterizer* rasty
+ int drawingmode
);
void ClearArrayData();