This commit is contained in:
Campbell Barton 2009-07-25 23:16:45 +00:00
commit 777a0d78e7
14 changed files with 506 additions and 50 deletions

@ -1039,7 +1039,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
layer.face++;
}
}
meshobj->m_sharedvertex_map.clear();
// keep meshobj->m_sharedvertex_map for reinstance phys mesh.
// 2.49a and before it did: meshobj->m_sharedvertex_map.clear();
// but this didnt save much ram. - Campbell
meshobj->EndConversion();
// pre calculate texture generation
for(list<RAS_MeshMaterial>::iterator mit = meshobj->GetFirstMaterial();

@ -68,6 +68,8 @@ public:
virtual RAS_Deformer* GetReplica(){return NULL;};
virtual void ProcessReplica();
struct Mesh* GetMesh() { return m_bmesh; };
virtual class RAS_MeshObject* GetRasMesh() { return (RAS_MeshObject*)m_pMeshObject; };
virtual float (* GetTransVerts(int *tot))[3] { *tot= m_tvtot; return m_transverts; }
// virtual void InitDeform(double time){};
protected:

@ -164,7 +164,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
struct KX_ObjectProperties* objprop);
void KX_ClearBulletSharedShapes();
//bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj);
bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj);
#endif
#endif //KX_CONVERTPHYSICSOBJECTS

@ -628,5 +628,44 @@ void KX_ClearBulletSharedShapes()
{
}
#endif
/* Refresh the physics object from either an object or a mesh.
* gameobj must be valid
* from_gameobj and from_meshobj can be NULL
*
* when setting the mesh, the following vars get priority
* 1) from_meshobj - creates the phys mesh from RAS_MeshObject
* 2) from_gameobj - creates the phys mesh from the DerivedMesh where possible, else the RAS_MeshObject
* 3) gameobj - update the phys mesh from DerivedMesh or RAS_MeshObject
*
* Most of the logic behind this is in shapeInfo->UpdateMesh(...)
*/
bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj)
{
KX_BulletPhysicsController *spc= static_cast<KX_BulletPhysicsController*>((gameobj->GetPhysicsController()));
CcdShapeConstructionInfo *shapeInfo;
/* if this is the child of a compound shape this can happen
* dont support compound shapes for now */
if(spc==NULL)
return false;
shapeInfo = spc->GetShapeInfo();
if(shapeInfo->m_shapeType != PHY_SHAPE_MESH || spc->GetSoftBody())
return false;
spc->DeleteControllerShape();
if(from_gameobj==NULL && from_meshobj==NULL)
from_gameobj= gameobj;
/* updates the arrays used for making the new bullet mesh */
shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
/* create the new bullet mesh */
btCollisionShape* bm= shapeInfo->CreateBulletShape(spc->getConstructionInfo().m_margin);
spc->ReplaceControllerShape(bm);
return true;
}
#endif

@ -66,6 +66,7 @@ typedef unsigned long uint_ptr;
#include "KX_PythonInit.h"
#include "KX_PyMath.h"
#include "KX_PythonSeq.h"
#include "KX_ConvertPhysicsObject.h"
#include "SCA_IActuator.h"
#include "SCA_ISensor.h"
#include "SCA_IController.h"
@ -1389,6 +1390,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_NOARGS},
{"replaceMesh",(PyCFunction) KX_GameObject::sPyReplaceMesh, METH_O},
{"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_NOARGS},
{"reinstancePhysicsMesh", (PyCFunction)KX_GameObject::sPyReinstancePhysicsMesh,METH_VARARGS},
KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
KX_PYMETHODTABLE(KX_GameObject, rayCast),
@ -1486,6 +1488,28 @@ PyObject* KX_GameObject::PyEndObject()
}
PyObject* KX_GameObject::PyReinstancePhysicsMesh(PyObject* args)
{
KX_GameObject *gameobj= NULL;
RAS_MeshObject *mesh= NULL;
PyObject *gameobj_py= NULL;
PyObject *mesh_py= NULL;
if ( !PyArg_ParseTuple(args,"|OO:reinstancePhysicsMesh",&gameobj_py, &mesh_py) ||
(gameobj_py && !ConvertPythonToGameObject(gameobj_py, &gameobj, true, "gameOb.reinstancePhysicsMesh(obj, mesh): KX_GameObject")) ||
(mesh_py && !ConvertPythonToMesh(mesh_py, &mesh, true, "gameOb.reinstancePhysicsMesh(obj, mesh): KX_GameObject"))
) {
return NULL;
}
/* gameobj and mesh can be NULL */
if(KX_ReInstanceBulletShapeFromMesh(this, gameobj, mesh))
Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
PyObject* KX_GameObject::PyGetPosition()
{

@ -856,6 +856,7 @@ public:
KX_PYMETHOD_DOC_O(KX_GameObject,getDistanceTo);
KX_PYMETHOD_DOC_O(KX_GameObject,getVectTo);
KX_PYMETHOD_DOC_VARARGS(KX_GameObject, sendMessage);
KX_PYMETHOD_VARARGS(KX_GameObject, ReinstancePhysicsMesh);
/* Dict access */
KX_PYMETHOD_VARARGS(KX_GameObject,get);

@ -84,7 +84,6 @@ PyMethodDef KX_MeshProxy::Methods[] = {
{"getVertexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetVertexArrayLength,METH_VARARGS},
{"getVertex", (PyCFunction)KX_MeshProxy::sPyGetVertex,METH_VARARGS},
{"getPolygon", (PyCFunction)KX_MeshProxy::sPyGetPolygon,METH_VARARGS},
KX_PYMETHODTABLE(KX_MeshProxy, reinstancePhysicsMesh),
//{"getIndexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetIndexArrayLength,METH_VARARGS},
{NULL,NULL} //Sentinel
@ -243,17 +242,6 @@ PyObject* KX_MeshProxy::PyGetPolygon(PyObject* args, PyObject* kwds)
return polyob;
}
KX_PYMETHODDEF_DOC(KX_MeshProxy, reinstancePhysicsMesh,
"Reinstance the physics mesh.")
{
#if 0
//this needs to be reviewed, it is dependend on Sumo/Solid. Who is using this ?
if(KX_ReInstanceShapeFromMesh(m_meshobj))
Py_RETURN_TRUE;
#endif
Py_RETURN_FALSE;
}
PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_MeshProxy* self= static_cast<KX_MeshProxy*>(self_v);

@ -66,7 +66,6 @@ public:
KX_PYMETHOD(KX_MeshProxy,GetVertexArrayLength);
KX_PYMETHOD(KX_MeshProxy,GetVertex);
KX_PYMETHOD(KX_MeshProxy,GetPolygon);
KX_PYMETHOD_DOC(KX_MeshProxy, reinstancePhysicsMesh);
static PyObject* pyattr_get_materials(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject * pyattr_get_numMaterials(void * self, const KX_PYATTRIBUTE_DEF * attrdef);

@ -22,6 +22,8 @@ subject to the following restrictions:
#include "PHY_IMotionState.h"
#include "CcdPhysicsEnvironment.h"
#include "RAS_MeshObject.h"
#include "KX_GameObject.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody//btSoftBodyInternals.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
@ -529,7 +531,7 @@ void CcdPhysicsController::CreateRigidbody()
}
static void DeleteBulletShape(btCollisionShape* shape)
static void DeleteBulletShape(btCollisionShape* shape, bool free)
{
if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
@ -539,7 +541,66 @@ static void DeleteBulletShape(btCollisionShape* shape)
if (meshInterface)
delete meshInterface;
}
delete shape;
if(free) {
delete shape;
}
}
bool CcdPhysicsController::DeleteControllerShape( )
{
if (m_collisionShape)
{
// collision shape is always unique to the controller, can delete it here
if (m_collisionShape->isCompound())
{
// bullet does not delete the child shape, must do it here
btCompoundShape* compoundShape = (btCompoundShape*)m_collisionShape;
int numChild = compoundShape->getNumChildShapes();
for (int i=numChild-1 ; i >= 0; i--)
{
btCollisionShape* childShape = compoundShape->getChildShape(i);
DeleteBulletShape(childShape, true);
}
}
DeleteBulletShape(m_collisionShape, true);
return true;
}
return false;
}
bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape)
{
/* Note, deleting the previous collision shape must be done alredy */
/* if (m_collisionShape) DeleteControllerShape(); */
m_object->setCollisionShape(newShape);
m_collisionShape= newShape;
m_cci.m_collisionShape= newShape;
/* Copied from CcdPhysicsEnvironment::addCcdPhysicsController() */
/* without this, an object can rest on the old physics mesh
* and not move to account for the physics mesh, even with 'nosleep' */
btSoftRigidDynamicsWorld* dw= GetPhysicsEnvironment()->getDynamicsWorld();
btCollisionObjectArray &obarr= dw->getCollisionObjectArray();
btCollisionObject *ob;
btBroadphaseProxy* proxy;
for(int i= 0; i < obarr.size(); i++) {
ob= obarr[i];
if (ob->getCollisionShape() == newShape); {
proxy = obarr[i]->getBroadphaseHandle();
if(proxy)
dw->getPairCache()->cleanProxyFromPairs(proxy,dw->getDispatcher());
}
}
return true;
}
CcdPhysicsController::~CcdPhysicsController()
@ -554,22 +615,8 @@ CcdPhysicsController::~CcdPhysicsController()
delete m_bulletMotionState;
delete m_object;
if (m_collisionShape)
{
// collision shape is always unique to the controller, can delete it here
if (m_collisionShape->isCompound())
{
// bullet does not delete the child shape, must do it here
btCompoundShape* compoundShape = (btCompoundShape*)m_collisionShape;
int numChild = compoundShape->getNumChildShapes();
for (int i=numChild-1 ; i >= 0; i--)
{
btCollisionShape* childShape = compoundShape->getChildShape(i);
DeleteBulletShape(childShape);
}
}
DeleteBulletShape(m_collisionShape);
}
DeleteControllerShape();
if (m_shapeInfo)
{
m_shapeInfo->Release();
@ -1264,7 +1311,7 @@ PHY_IPhysicsController* CcdPhysicsController::GetReplica()
if (m_shapeInfo)
{
// This situation does not normally happen
cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape(0.01);
cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin);
}
else if (m_collisionShape)
{
@ -1621,6 +1668,311 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
return true;
}
#include <cstdio>
/* Updates the arrays used by CreateBulletShape(),
* take care that recalcLocalAabb() runs after CreateBulletShape is called.
* */
bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RAS_MeshObject* meshobj)
{
int numpolys;
int numverts;
unsigned int tot_bt_tris= 0;
unsigned int tot_bt_verts= 0;
int i, j;
int v_orig;
/* Use for looping over verts in a face as a try or 2 tris */
const int quad_verts[7]= {0,1,2, 0,2,3, -1};
const int tri_verts[4]= {0,1,2, -1};
const int *fv_pt;
if(gameobj==NULL && meshobj==NULL)
return false;
if(m_shapeType != PHY_SHAPE_MESH)
return false;
RAS_Deformer *deformer= gameobj ? gameobj->GetDeformer():NULL;
/* get the mesh from the object if not defined */
if(meshobj==NULL) {
/* modifier mesh */
if(deformer && deformer->GetFinalMesh())
meshobj= deformer->GetRasMesh();
/* game object first mesh */
if(meshobj==NULL) {
if(gameobj->GetMeshCount() > 0) {
meshobj= gameobj->GetMesh(0);
}
}
}
if(deformer && deformer->GetFinalMesh() && deformer->GetRasMesh() == meshobj)
{ /*
* Derived Mesh Update
*
* */
DerivedMesh* dm= gameobj->GetDeformer()->GetFinalMesh();
MVert *mvert = dm->getVertArray(dm);
MFace *mface = dm->getFaceArray(dm);
numpolys = dm->getNumFaces(dm);
numverts = dm->getNumVerts(dm);
int* index = (int*)dm->getFaceDataArray(dm, CD_ORIGINDEX);
MFace *mf;
MVert *mv;
int flen;
if(CustomData_has_layer(&dm->faceData, CD_MTFACE))
{
MTFace *tface = (MTFace *)dm->getFaceDataArray(dm, CD_MTFACE);
MTFace *tf;
vector<bool> vert_tag_array(numverts, false);
vector<int> vert_remap_array(numverts, 0);
for(mf= mface, tf= tface, i=0; i < numpolys; mf++, tf++, i++) {
if(tf->mode & TF_DYNAMIC)
{
if(mf->v4) {
tot_bt_tris+= 2;
flen= 4;
} else {
tot_bt_tris++;
flen= 3;
}
for(j=0; j<flen; j++)
{
v_orig = (*(&mf->v1 + j));
if(vert_tag_array[v_orig]==false)
{
vert_tag_array[v_orig]= true;
vert_remap_array[v_orig]= tot_bt_verts;
tot_bt_verts++;
}
}
}
}
m_vertexArray.resize(tot_bt_verts*3);
btScalar *bt= &m_vertexArray[0];
m_triFaceArray.resize(tot_bt_tris*3);
int *tri_pt= &m_triFaceArray[0];
m_polygonIndexArray.resize(tot_bt_tris);
int *poly_index_pt= &m_polygonIndexArray[0];
for(mf= mface, tf= tface, i=0; i < numpolys; mf++, tf++, i++)
{
if(tf->mode & TF_DYNAMIC)
{
if(mf->v4) {
fv_pt= quad_verts;
*poly_index_pt++ = *poly_index_pt++ = index[i];
flen= 4;
} else {
fv_pt= tri_verts;
*poly_index_pt++ = index[i];
flen= 3;
}
for(; *fv_pt > -1; fv_pt++)
{
v_orig = (*(&mf->v1 + (*fv_pt)));
if(vert_tag_array[v_orig])
{
mv= mvert + v_orig;
*bt++ = mv->co[0];
*bt++ = mv->co[1];
*bt++ = mv->co[2];
vert_tag_array[v_orig]= false;
}
*tri_pt++ = vert_remap_array[v_orig];
}
}
}
}
else {
/* no need for a vertex mapping. simple/fast */
tot_bt_verts= numverts;
for(mf= mface, i=0; i < numpolys; mf++, i++) {
tot_bt_tris += (mf->v4 ? 2:1);
}
m_vertexArray.resize(tot_bt_verts*3);
btScalar *bt= &m_vertexArray[0];
m_triFaceArray.resize(tot_bt_tris*3);
int *tri_pt= &m_triFaceArray[0];
m_polygonIndexArray.resize(tot_bt_tris);
int *poly_index_pt= &m_polygonIndexArray[0];
for(mv= mvert, i=0; i < numverts; mv++, i++) {
*bt++ = mv->co[0]; *bt++ = mv->co[1]; *bt++ = mv->co[2];
}
for(mf= mface, i=0; i < numpolys; mf++, i++) {
unsigned int *fv = &mf->v1;
if(mf->v4) {
fv_pt= quad_verts;
*poly_index_pt++ = *poly_index_pt++ = index[i];
}
else {
fv_pt= tri_verts;
*poly_index_pt++ = index[i];
}
for(; *fv_pt > -1; fv_pt++)
*tri_pt++ = (*(&mf->v1 + (*fv_pt)));
}
}
}
else { /*
* RAS Mesh Update
*
* */
/* Note!, gameobj can be NULL here */
/* transverts are only used for deformed RAS_Meshes, the RAS_TexVert data
* is too hard to get at, see below for details */
float (*transverts)[3]= NULL;
int transverts_tot= 0; /* with deformed meshes - should always be greater then the max orginal index, or we get crashes */
if(deformer) {
/* map locations from the deformed array
*
* Could call deformer->Update(); but rely on redraw updating.
* */
transverts= deformer->GetTransVerts(&transverts_tot);
}
// Tag verts we're using
numpolys= meshobj->NumPolygons();
numverts= meshobj->m_sharedvertex_map.size();
const float *xyz;
vector<bool> vert_tag_array(numverts, false);
vector<int> vert_remap_array(numverts, 0);
for(int p=0; p<numpolys; p++)
{
RAS_Polygon* poly= meshobj->GetPolygon(p);
if (poly->IsCollider())
{
for(i=0; i < poly->VertexCount(); i++)
{
v_orig= poly->GetVertex(i)->getOrigIndex();
if(vert_tag_array[v_orig]==false)
{
vert_tag_array[v_orig]= true;
vert_remap_array[v_orig]= tot_bt_verts;
tot_bt_verts++;
}
}
tot_bt_tris += (poly->VertexCount()==4 ? 2:1);
}
}
m_vertexArray.resize(tot_bt_verts*3);
btScalar *bt= &m_vertexArray[0];
m_triFaceArray.resize(tot_bt_tris*3);
int *tri_pt= &m_triFaceArray[0];
/* cant be used for anything useful in this case, since we dont rely on the original mesh
* will just be an array like pythons range(tot_bt_tris) */
m_polygonIndexArray.resize(tot_bt_tris);
for(int p=0; p<numpolys; p++)
{
RAS_Polygon* poly= meshobj->GetPolygon(p);
if (poly->IsCollider())
{
/* quad or tri loop */
fv_pt= (poly->VertexCount()==3 ? tri_verts:quad_verts);
for(; *fv_pt > -1; fv_pt++)
{
v_orig= poly->GetVertex(*fv_pt)->getOrigIndex();
if(vert_tag_array[v_orig])
{
if(transverts) {
/* deformed mesh, using RAS_TexVert locations would be too troublesome
* because they are use the gameob as a hash in the material slot */
*bt++ = transverts[v_orig][0];
*bt++ = transverts[v_orig][1];
*bt++ = transverts[v_orig][2];
}
else {
/* static mesh python may have modified */
xyz= meshobj->GetVertexLocation( v_orig );
*bt++ = xyz[0];
*bt++ = xyz[1];
*bt++ = xyz[2];
}
vert_tag_array[v_orig]= false;
}
*tri_pt++ = vert_remap_array[v_orig];
}
}
m_polygonIndexArray[p]= p; /* dumb counting */
}
}
#if 0
/* needs #include <cstdio> */
printf("# vert count %d\n", m_vertexArray.size());
for(int i=0; i<m_vertexArray.size(); i+=3) {
printf("v %.6f %.6f %.6f\n", m_vertexArray[i], m_vertexArray[i+1], m_vertexArray[i+2]);
}
printf("# face count %d\n", m_triFaceArray.size());
for(int i=0; i<m_triFaceArray.size(); i+=3) {
printf("f %d %d %d\n", m_triFaceArray[i]+1, m_triFaceArray[i+1]+1, m_triFaceArray[i+2]+1);
}
#endif
/* force recreation of the m_unscaledShape.
* If this has multiple users we cant delete */
if(m_unscaledShape) {
// dont free now so it can re-allocate under the same location and not break pointers.
// DeleteBulletShape(m_unscaledShape);
m_forceReInstance= true;
}
m_meshObject= meshobj;
return true;
}
bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo)
{
if (shapeInfo == NULL)
@ -1696,7 +2048,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin)
} else
{
if (!m_unscaledShape)
if (!m_unscaledShape || m_forceReInstance)
{
btTriangleIndexVertexArray* indexVertexArrays = 0;
@ -1731,7 +2083,18 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin)
}
// this shape will be shared and not deleted until shapeInfo is deleted
m_unscaledShape = new btBvhTriangleMeshShape( indexVertexArrays, true );
// for UpdateMesh, reuse the last memory location so instancing wont crash.
if(m_unscaledShape) {
DeleteBulletShape(m_unscaledShape, false);
m_unscaledShape->~btBvhTriangleMeshShape();
m_unscaledShape = new(m_unscaledShape) btBvhTriangleMeshShape( indexVertexArrays, true );
} else {
m_unscaledShape = new btBvhTriangleMeshShape( indexVertexArrays, true );
}
m_forceReInstance= false;
m_unscaledShape->recalcLocalAabb();
}
collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f));
@ -1776,7 +2139,7 @@ CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
m_shapeArray.clear();
if (m_unscaledShape)
{
DeleteBulletShape(m_unscaledShape);
DeleteBulletShape(m_unscaledShape, true);
}
m_vertexArray.clear();
if (m_shapeType == PHY_SHAPE_MESH && m_meshObject != NULL)

@ -146,6 +146,9 @@ public:
return m_meshObject;
}
bool UpdateMesh(class KX_GameObject* gameobj, class RAS_MeshObject* mesh);
bool SetProxy(CcdShapeConstructionInfo* shapeInfo);
CcdShapeConstructionInfo* GetProxy(void)
{
@ -185,6 +188,7 @@ protected:
// the actual shape is of type btScaledBvhTriangleMeshShape
std::vector<CcdShapeConstructionInfo*> m_shapeArray; // for compound shapes
bool m_useGimpact; //use gimpact for concave dynamic/moving collision detection
bool m_forceReInstance; //use gimpact for concave dynamic/moving collision detection
float m_weldingThreshold1; //welding closeby vertices together can improve softbody stability etc.
CcdShapeConstructionInfo* m_shapeProxy; // only used for PHY_SHAPE_PROXY, pointer to actual shape info
};
@ -381,6 +385,9 @@ protected:
CcdPhysicsController (const CcdConstructionInfo& ci);
bool DeleteControllerShape();
bool ReplaceControllerShape(btCollisionShape *newShape);
virtual ~CcdPhysicsController();
CcdConstructionInfo& getConstructionInfo()

@ -2078,6 +2078,26 @@ class KX_GameObject(SCA_IObject):
@param to: The name of the object to send the message to (optional)
@type to: string
"""
def reinstancePhysicsMesh(gameObject, meshObject):
"""
Updates the physics system with the changed mesh.
If no arguments are given the physics mesh will be re-created from the first mesh assigned to the game object.
@param gameObject: optional argument, set the physics shape from this gameObjets mesh.
@type gameObject: string, L{KX_GameObject} or None
@param meshObject: optional argument, set the physics shape from this mesh.
@type meshObject: string, L{KX_MeshProxy} or None
@note: if this object has instances the other instances will be updated too.
@note: the gameObject argument has an advantage that it can convert from a mesh with modifiers applied (such as subsurf).
@warning: only triangle mesh type objects are supported currently (not convex hull)
@warning: if the object is a part of a combound object it will fail (parent or child)
@warning: rebuilding the physics mesh can be slow, running many times per second will give a performance hit.
@rtype: boolean
@return: True if reinstance succeeded, False if it failed.
"""
def get(key, default=None):
"""
Return the value matching key, or the default value if its not found.
@ -2387,18 +2407,6 @@ class KX_MeshProxy(SCA_IObject):
@rtype: L{KX_PolyProxy}
@return: a polygon object.
"""
def reinstancePhysicsMesh():
"""
Updates the physics system with the changed mesh.
A mesh must have only one material with collision flags,
and have all collision primitives in one vertex array (ie. < 65535 verts) and
be either a polytope or polyheder mesh. If you don't get a warning in the
console when the collision type is polytope, the mesh is suitable for reinstance.
@bug: This currently does not work.
@rtype: boolean
@return: True if reinstance succeeded, False if it failed.
"""
class SCA_MouseSensor(SCA_ISensor):
"""

@ -38,6 +38,7 @@
#include "GEN_Map.h"
struct DerivedMesh;
class RAS_MeshObject;
class RAS_Deformer
{
@ -71,6 +72,12 @@ public:
{
return NULL;
}
virtual class RAS_MeshObject* GetRasMesh()
{
/* m_pMesh does not seem to be being used?? */
return NULL;
}
virtual float (* GetTransVerts(int *tot))[3] { *tot= 0; return NULL; }
protected:
class RAS_MeshObject *m_pMesh;

@ -382,6 +382,13 @@ RAS_TexVert* RAS_MeshObject::GetVertex(unsigned int matid,
return NULL;
}
const float* RAS_MeshObject::GetVertexLocation(unsigned int orig_index)
{
vector<SharedVertex>& sharedmap = m_sharedvertex_map[orig_index];
vector<SharedVertex>::iterator it= sharedmap.begin();
return it->m_darray->m_vertex[it->m_offset].getXYZ();
}
void RAS_MeshObject::AddMeshUser(void *clientobj, SG_QList *head, RAS_Deformer* deformer)
{
list<RAS_MeshMaterial>::iterator it;

@ -126,6 +126,7 @@ public:
/* vertex and polygon acces */
int NumVertices(RAS_IPolyMaterial* mat);
RAS_TexVert* GetVertex(unsigned int matid, unsigned int index);
const float* GetVertexLocation(unsigned int orig_index);
int NumPolygons();
RAS_Polygon* GetPolygon(int num) const;
@ -141,6 +142,13 @@ public:
bool culled);
void RemoveFromBuckets(void *clientobj);
void EndConversion() {
#if 0
m_sharedvertex_map.clear(); // SharedVertex
vector<vector<SharedVertex> > shared_null(0);
shared_null.swap( m_sharedvertex_map ); /* really free the memory */
#endif
}
/* colors */
void DebugColor(unsigned int abgr);