forked from bartvdbraak/blender
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r21899:21908
This commit is contained in:
commit
777a0d78e7
@ -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;
|
||||
}
|
||||
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
|
||||
|
||||
// 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);
|
||||
|
Loading…
Reference in New Issue
Block a user