ReplaceMesh Actuator option to replace the physics mesh and display mesh + python api options.

When the mesh field is left blank and Physics option is enabled, it reinstances the physics mesh from the existing mesh.
like calling gameOb.reinstancePhysicsMesh() from python.
This commit is contained in:
Campbell Barton
2009-07-26 01:32:37 +00:00
parent e9ca43521f
commit dd918da8de
11 changed files with 162 additions and 120 deletions

View File

@@ -405,6 +405,10 @@ typedef struct FreeCamera {
/* editObjectActuator->flag */
#define ACT_TRACK_3D 1
/* editObjectActuator->flag for replace mesh actuator */
#define ACT_EDOB_REPLACE_MESH_NOGFX 2 /* use for replace mesh actuator */
#define ACT_EDOB_REPLACE_MESH_PHYS 4
/* SceneActuator->type */
#define ACT_SCENE_RESTART 0
#define ACT_SCENE_SET 1

View File

@@ -2177,7 +2177,10 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, 1, "ME:", xco+40, yco-44, (width-80), 19, &(eoa->me), "replace the existing mesh with this one");
uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, 1, "ME:", xco+40, yco-44, (width-80)/2, 19, &(eoa->me), "replace the existing, when left blank 'Phys' will remake the existing physics mesh");
uiDefButBitS(block, TOGN, ACT_EDOB_REPLACE_MESH_NOGFX, B_NOP, "Gfx", xco+40 + (width-80)/2, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the display mesh");
uiDefButBitS(block, TOG, ACT_EDOB_REPLACE_MESH_PHYS, B_NOP, "Phys", xco+40 + (width-80)/2 +(width-80)/4, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the physics mesh (triangle bounds only. compound shapes not supported)");
}
else if(eoa->type==ACT_EDOB_TRACK_TO) {
ysize= 48;

View File

@@ -638,7 +638,10 @@ void BL_ConvertActuators(char* maggiename,
= new KX_SCA_ReplaceMeshActuator(
gameobj,
tmpmesh,
scene
scene,
(editobact->flag & ACT_EDOB_REPLACE_MESH_NOGFX)==0,
(editobact->flag & ACT_EDOB_REPLACE_MESH_PHYS)!=0
);
baseact = tmpreplaceact;

View File

@@ -55,7 +55,7 @@ public:
//virtual void DelayedReleaseObject(class CValue* gameobj)=0;
virtual void ReplaceMesh(class CValue* gameobj,
void* meshobj)=0;
void* meshobj, bool use_gfx, bool use_phys)=0;
std::vector<SCA_DebugProp*>& GetDebugProperties();
void AddDebugProperty(class CValue* debugprop,
const STR_String &name);

View File

@@ -1182,7 +1182,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getChildrenRecursive", (PyCFunction)KX_GameObject::sPyGetChildrenRecursive,METH_NOARGS},
{"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_NOARGS},
{"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_NOARGS},
{"replaceMesh",(PyCFunction) KX_GameObject::sPyReplaceMesh, METH_O},
{"replaceMesh",(PyCFunction) KX_GameObject::sPyReplaceMesh, METH_VARARGS},
{"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_NOARGS},
{"reinstancePhysicsMesh", (PyCFunction)KX_GameObject::sPyReinstancePhysicsMesh,METH_VARARGS},
@@ -1260,15 +1260,21 @@ bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
}
*/
PyObject* KX_GameObject::PyReplaceMesh(PyObject* value)
PyObject* KX_GameObject::PyReplaceMesh(PyObject* args)
{
KX_Scene *scene = KX_GetActiveScene();
PyObject *value;
int use_gfx= 1, use_phys= 0;
RAS_MeshObject *new_mesh;
if (!PyArg_ParseTuple(args,"O|ii:replaceMesh", &value, &use_gfx, &use_phys))
return NULL;
if (!ConvertPythonToMesh(value, &new_mesh, false, "gameOb.replaceMesh(value): KX_GameObject"))
return NULL;
scene->ReplaceMesh(this, new_mesh);
scene->ReplaceMesh(this, new_mesh, (bool)use_gfx, (bool)use_phys);
Py_RETURN_NONE;
}

View File

@@ -865,7 +865,7 @@ public:
KX_PYMETHOD_VARARGS(KX_GameObject,GetMesh);
KX_PYMETHOD_NOARGS(KX_GameObject,GetPhysicsId);
KX_PYMETHOD_NOARGS(KX_GameObject,GetPropertyNames);
KX_PYMETHOD_O(KX_GameObject,ReplaceMesh);
KX_PYMETHOD_VARARGS(KX_GameObject,ReplaceMesh);
KX_PYMETHOD_NOARGS(KX_GameObject,EndObject);
KX_PYMETHOD_DOC(KX_GameObject,rayCastTo);
KX_PYMETHOD_DOC(KX_GameObject,rayCast);

View File

@@ -96,6 +96,8 @@ PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = {
PyAttributeDef KX_SCA_ReplaceMeshActuator::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("mesh", KX_SCA_ReplaceMeshActuator, pyattr_get_mesh, pyattr_set_mesh),
KX_PYATTRIBUTE_BOOL_RW ("useDisplayMesh", KX_SCA_ReplaceMeshActuator, m_use_gfx),
KX_PYATTRIBUTE_BOOL_RW ("usePhysicsMesh", KX_SCA_ReplaceMeshActuator, m_use_phys),
{ NULL } //Sentinel
};
@@ -179,11 +181,15 @@ KX_PYMETHODDEF_DOC(KX_SCA_ReplaceMeshActuator, instantReplaceMesh,
KX_SCA_ReplaceMeshActuator::KX_SCA_ReplaceMeshActuator(SCA_IObject *gameobj,
class RAS_MeshObject *mesh,
SCA_IScene* scene,
bool use_gfx,
bool use_phys,
PyTypeObject* T) :
SCA_IActuator(gameobj, T),
m_mesh(mesh),
m_scene(scene)
m_scene(scene),
m_use_gfx(use_gfx),
m_use_phys(use_phys)
{
} /* End of constructor */
@@ -205,7 +211,8 @@ bool KX_SCA_ReplaceMeshActuator::Update()
if (bNegativeEvent)
return false; // do nothing on negative events
if (m_mesh) m_scene->ReplaceMesh(GetParent(),m_mesh);
if (m_mesh || m_use_phys) /* NULL mesh is ok if were updating physics */
m_scene->ReplaceMesh(GetParent(),m_mesh, m_use_gfx, m_use_phys);
return false;
}
@@ -227,7 +234,7 @@ CValue* KX_SCA_ReplaceMeshActuator::GetReplica()
void KX_SCA_ReplaceMeshActuator::InstantReplaceMesh()
{
if (m_mesh) m_scene->ReplaceMesh(GetParent(),m_mesh);
if (m_mesh) m_scene->ReplaceMesh(GetParent(),m_mesh, m_use_gfx, m_use_phys);
}
/* eof */

View File

@@ -50,12 +50,16 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator
// mesh reference (mesh to replace)
RAS_MeshObject* m_mesh;
SCA_IScene* m_scene;
bool m_use_phys;
bool m_use_gfx;
public:
KX_SCA_ReplaceMeshActuator(
SCA_IObject* gameobj,
RAS_MeshObject *mesh,
SCA_IScene* scene,
bool use_gfx,
bool use_phys,
PyTypeObject* T=&Type
);

View File

@@ -1017,17 +1017,18 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool use_phys)
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(obj);
RAS_MeshObject* mesh = static_cast<RAS_MeshObject*>(meshobj);
if(!gameobj || !mesh)
{
std::cout << "warning: invalid object, mesh will not be replaced" << std::endl;
if(!gameobj) {
std::cout << "KX_Scene::ReplaceMesh Warning: invalid object, doing nothing" << std::endl;
return;
}
if(use_gfx && mesh != NULL)
{
gameobj->RemoveMeshes();
gameobj->AddMesh(mesh);
@@ -1156,6 +1157,11 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
gameobj->AddMeshUser();
}
if(use_phys) { /* update the new assigned mesh with the physics mesh */
KX_ReInstanceBulletShapeFromMesh(gameobj, NULL, use_gfx?NULL:mesh);
}
}
KX_Camera* KX_Scene::FindCamera(KX_Camera* cam)
{
list<KX_Camera*>::iterator it = m_cameras.begin();

View File

@@ -323,7 +323,7 @@ public:
int NewRemoveObject(CValue* gameobj);
void ReplaceMesh(CValue* gameobj,
void* meshobj);
void* meshob, bool use_gfx, bool use_phys);
/**
* @section Logic stuff
* Initiate an update of the logic system.

View File

@@ -1642,10 +1642,14 @@ class KX_GameObject(SCA_IObject):
Delete this object, can be used inpace of the EndObject Actuator.
The actual removal of the object from the scene is delayed.
"""
def replaceMesh(mesh):
def replaceMesh(mesh, useDisplayMesh=True, usePhysicsMesh=False):
"""
Replace the mesh of this object with a new mesh. This works the same was as the actuator.
@type mesh: L{KX_MeshProxy} or mesh name
@type useDisplayMesh: bool
@param useDisplayMesh: when enabled the display mesh will be replaced (optional argument).
@type usePhysicsMesh: bool
@param usePhysicsMesh: when enabled the physics mesh will be replaced (optional argument).
"""
def getVisible():
"""
@@ -3791,6 +3795,11 @@ class KX_SCA_ReplaceMeshActuator(SCA_IActuator):
@ivar mesh: L{KX_MeshProxy} or the name of the mesh that will replace the current one
Set to None to disable actuator
@type mesh: L{KX_MeshProxy} or None if no mesh is set
@ivar useDisplayMesh: when true the displayed mesh is replaced.
@type useDisplayMesh: boolean
@ivar usePhysicsMesh: when true the physics mesh is replaced.
@type usePhysicsMesh: boolean
"""
def setMesh(name):
"""