BGE Bugfixes (mostly in the py api)
KX_PolygonMaterial and KX_BlenderMaterial - Added a print function (would raise a python error on printing) * Crashes * KX_GameObject SetParent - Disallowed setting a parent to its self, caused a recursion crash. KX_MeshProxy "materials" attribute was segfaulting because of my recent change - I was wrong, you do need to check material types (no idea why since they are both PyObject * at the base) KX_VisibilityActuator - Wasn't initialized with PyType_Ready() making it crash on access (own fault) * Crashes because of missing NULL checks * KX_PolygonMaterial's "gl_texture" attribute wasnt checking for a valid m_tface KX_GameObject - added checks for GetPhysicsController() KX_RayCast::RayTest - didnt check for a valid physics_environment KX_SceneActuator's getCamera python function wasnt checking if there was a camera.
This commit is contained in:
@@ -84,6 +84,7 @@ public:
|
||||
// --------------------------------
|
||||
virtual PyObject* py_getattro(PyObject *attr);
|
||||
virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
|
||||
virtual PyObject* py_repr(void) { return PyString_FromString(mMaterial->matname.ReadPtr()); }
|
||||
|
||||
KX_PYMETHOD_DOC( KX_BlenderMaterial, getShader );
|
||||
KX_PYMETHOD_DOC( KX_BlenderMaterial, getMaterialIndex );
|
||||
|
||||
@@ -73,6 +73,8 @@ typedef unsigned long uint_ptr;
|
||||
|
||||
#include "KX_SG_NodeRelationships.h"
|
||||
|
||||
static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0);
|
||||
|
||||
KX_GameObject::KX_GameObject(
|
||||
void* sgReplicationInfo,
|
||||
SG_Callbacks callbacks,
|
||||
@@ -943,7 +945,7 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
|
||||
}
|
||||
|
||||
|
||||
static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0);
|
||||
|
||||
const MT_Point3& KX_GameObject::NodeGetWorldPosition() const
|
||||
{
|
||||
// check on valid node in case a python controller holds a reference to a deleted object
|
||||
@@ -964,7 +966,8 @@ void KX_GameObject::Resume(void)
|
||||
{
|
||||
if (m_suspended) {
|
||||
SCA_IObject::Resume();
|
||||
GetPhysicsController()->RestoreDynamics();
|
||||
if(GetPhysicsController())
|
||||
GetPhysicsController()->RestoreDynamics();
|
||||
|
||||
m_suspended = false;
|
||||
}
|
||||
@@ -975,7 +978,8 @@ void KX_GameObject::Suspend()
|
||||
if ((!m_ignore_activity_culling)
|
||||
&& (!m_suspended)) {
|
||||
SCA_IObject::Suspend();
|
||||
GetPhysicsController()->SuspendDynamics();
|
||||
if(GetPhysicsController())
|
||||
GetPhysicsController()->SuspendDynamics();
|
||||
m_suspended = true;
|
||||
}
|
||||
}
|
||||
@@ -1717,7 +1721,7 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* self, PyObject* args)
|
||||
PyObject* KX_GameObject::PyGetMass(PyObject* self)
|
||||
{
|
||||
ShowDeprecationWarning("getMass()", "the mass property");
|
||||
return PyFloat_FromDouble(GetPhysicsController()->GetMass());
|
||||
return PyFloat_FromDouble((GetPhysicsController() != NULL) ? GetPhysicsController()->GetMass() : 0.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -1725,14 +1729,24 @@ PyObject* KX_GameObject::PyGetMass(PyObject* self)
|
||||
PyObject* KX_GameObject::PyGetReactionForce(PyObject* self)
|
||||
{
|
||||
// only can get the velocity if we have a physics object connected to us...
|
||||
return PyObjectFrom(GetPhysicsController()->getReactionForce());
|
||||
|
||||
// XXX - Currently not working with bullet intergration, see KX_BulletPhysicsController.cpp's getReactionForce
|
||||
/*
|
||||
if (GetPhysicsController())
|
||||
return PyObjectFrom(GetPhysicsController()->getReactionForce());
|
||||
return PyObjectFrom(dummy_point);
|
||||
*/
|
||||
|
||||
return Py_BuildValue("fff", 0.0f, 0.0f, 0.0f);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject* KX_GameObject::PyEnableRigidBody(PyObject* self)
|
||||
{
|
||||
GetPhysicsController()->setRigidBody(true);
|
||||
if(GetPhysicsController())
|
||||
GetPhysicsController()->setRigidBody(true);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@@ -1741,7 +1755,8 @@ PyObject* KX_GameObject::PyEnableRigidBody(PyObject* self)
|
||||
|
||||
PyObject* KX_GameObject::PyDisableRigidBody(PyObject* self)
|
||||
{
|
||||
GetPhysicsController()->setRigidBody(false);
|
||||
if(GetPhysicsController())
|
||||
GetPhysicsController()->setRigidBody(false);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@@ -1763,6 +1778,10 @@ PyObject* KX_GameObject::PySetParent(PyObject* self, PyObject* value)
|
||||
PyErr_SetString(PyExc_TypeError, "expected a KX_GameObject type");
|
||||
return NULL;
|
||||
}
|
||||
if (self==value) {
|
||||
PyErr_SetString(PyExc_ValueError, "cannot set the object to be its own parent!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// The object we want to set as parent
|
||||
CValue *m_ob = (CValue*)value;
|
||||
|
||||
@@ -190,24 +190,24 @@ PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* self,
|
||||
PyObject* args,
|
||||
PyObject* kwds)
|
||||
{
|
||||
int matid= -1;
|
||||
int length = -1;
|
||||
int matid= 0;
|
||||
int length = 0;
|
||||
|
||||
|
||||
if (PyArg_ParseTuple(args,"i",&matid))
|
||||
{
|
||||
RAS_MeshMaterial *mmat = m_meshobj->GetMeshMaterial(matid);
|
||||
RAS_IPolyMaterial* mat = mmat->m_bucket->GetPolyMaterial();
|
||||
if (!PyArg_ParseTuple(args,"i",&matid))
|
||||
return NULL;
|
||||
|
||||
|
||||
RAS_MeshMaterial *mmat = m_meshobj->GetMeshMaterial(matid); /* can be NULL*/
|
||||
|
||||
if (mmat)
|
||||
{
|
||||
RAS_IPolyMaterial* mat = mmat->m_bucket->GetPolyMaterial();
|
||||
if (mat)
|
||||
length = m_meshobj->NumVertices(mat);
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return PyInt_FromLong(length);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -244,15 +244,21 @@ PyObject* KX_MeshProxy::PyGetPolygon(PyObject* self,
|
||||
|
||||
if (!PyArg_ParseTuple(args,"i",&polyindex))
|
||||
return NULL;
|
||||
|
||||
if (polyindex<0 || polyindex >= m_meshobj->NumPolygons())
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError, "Invalid polygon index");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
RAS_Polygon* polygon = m_meshobj->GetPolygon(polyindex);
|
||||
if (polygon)
|
||||
{
|
||||
polyob = new KX_PolyProxy(m_meshobj, polygon);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_AttributeError, "Invalid polygon index");
|
||||
else {
|
||||
PyErr_SetString(PyExc_AttributeError, "polygon is NULL, unknown reason");
|
||||
}
|
||||
return polyob;
|
||||
}
|
||||
@@ -275,11 +281,22 @@ PyObject* KX_MeshProxy::pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_
|
||||
|
||||
list<RAS_MeshMaterial>::iterator mit= self->m_meshobj->GetFirstMaterial();
|
||||
|
||||
/* Can be a KX_PolygonMaterial or KX_BlenderMaterial, since both are cast to a PyObject * we dont need to care */
|
||||
|
||||
for(i=0; i<tot; mit++, i++) {
|
||||
PyObject *py_mat = (PyObject *)mit->m_bucket->GetPolyMaterial();
|
||||
PyList_SET_ITEM(materials, i, py_mat);
|
||||
Py_INCREF(py_mat);
|
||||
RAS_IPolyMaterial *polymat = mit->m_bucket->GetPolyMaterial();
|
||||
|
||||
/* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */
|
||||
if(polymat->GetFlag() & RAS_BLENDERMAT)
|
||||
{
|
||||
KX_BlenderMaterial *mat = static_cast<KX_BlenderMaterial*>(polymat);
|
||||
PyList_SET_ITEM(materials, i, mat);
|
||||
Py_INCREF(mat);
|
||||
}
|
||||
else {
|
||||
KX_PolygonMaterial *mat = static_cast<KX_PolygonMaterial*>(polymat);
|
||||
PyList_SET_ITEM(materials, i, mat);
|
||||
Py_INCREF(mat);
|
||||
}
|
||||
}
|
||||
return materials;
|
||||
}
|
||||
|
||||
@@ -333,8 +333,11 @@ PyObject* KX_PolygonMaterial::pyattr_get_tface(void *self_v, const KX_PYATTRIBUT
|
||||
PyObject* KX_PolygonMaterial::pyattr_get_gl_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_PolygonMaterial* self= static_cast<KX_PolygonMaterial*>(self_v);
|
||||
Image *ima = self->m_tface->tpage;
|
||||
return PyInt_FromLong(ima ? ima->bindcode:0);
|
||||
int bindcode= 0;
|
||||
if (self->m_tface && self->m_tface->tpage)
|
||||
bindcode= self->m_tface->tpage->bindcode;
|
||||
|
||||
return PyInt_FromLong(bindcode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "RAS_MaterialBucket.h"
|
||||
#include "RAS_IRasterizer.h"
|
||||
#include "DNA_ID.h"
|
||||
|
||||
struct MTFace;
|
||||
struct Material;
|
||||
@@ -117,7 +118,7 @@ public:
|
||||
|
||||
virtual PyObject* py_getattro(PyObject *attr);
|
||||
virtual int py_setattro(PyObject *attr, PyObject *pyvalue);
|
||||
|
||||
virtual PyObject* py_repr(void) { return PyString_FromString(m_material ? ((ID *)m_material)->name+2 : ""); }
|
||||
|
||||
static PyObject* pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#include "KX_SCA_DynamicActuator.h"
|
||||
#include "KX_SoundActuator.h"
|
||||
#include "KX_TouchSensor.h"
|
||||
#include "KX_VisibilityActuator.h"
|
||||
#include "SCA_PropertySensor.h"
|
||||
#include "SCA_PythonController.h"
|
||||
#include "SCA_RandomActuator.h"
|
||||
@@ -177,6 +178,7 @@ void initPyTypes(void)
|
||||
PyType_Ready(&KX_TrackToActuator::Type);
|
||||
PyType_Ready(&KX_VehicleWrapper::Type);
|
||||
PyType_Ready(&KX_VertexProxy::Type);
|
||||
PyType_Ready(&KX_VisibilityActuator::Type);
|
||||
PyType_Ready(&PyObjectPlus::Type);
|
||||
PyType_Ready(&SCA_2DFilterActuator::Type);
|
||||
PyType_Ready(&SCA_ANDController::Type);
|
||||
|
||||
@@ -56,12 +56,15 @@ void KX_RayCast::reportHit(PHY_RayCastResult* result)
|
||||
|
||||
bool KX_RayCast::RayTest(PHY_IPhysicsEnvironment* physics_environment, const MT_Point3& _frompoint, const MT_Point3& topoint, KX_RayCast& callback)
|
||||
{
|
||||
if(physics_environment==NULL) return false; /* prevents crashing in some cases */
|
||||
|
||||
// Loops over all physics objects between frompoint and topoint,
|
||||
// calling callback.RayHit for each one.
|
||||
//
|
||||
// callback.RayHit should return true to stop looking, or false to continue.
|
||||
//
|
||||
// returns true if an object was found, false if not.
|
||||
|
||||
MT_Point3 frompoint(_frompoint);
|
||||
const MT_Vector3 todir( (topoint - frompoint).safe_normalized() );
|
||||
MT_Point3 prevpoint(_frompoint+todir*(-1.f));
|
||||
|
||||
@@ -468,6 +468,11 @@ PyObject* KX_SceneActuator::PyGetCamera(PyObject* self,
|
||||
PyObject* kwds)
|
||||
{
|
||||
ShowDeprecationWarning("getCamera()", "the camera property");
|
||||
return PyString_FromString(m_camera->GetName());
|
||||
if (m_camera) {
|
||||
PyString_FromString(m_camera->GetName());
|
||||
}
|
||||
else {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
}
|
||||
/* eof */
|
||||
|
||||
@@ -270,6 +270,8 @@ class KX_GameObject: # (SCA_IObject)
|
||||
The reaction force is the force applied to this object over the last simulation timestep.
|
||||
This also includes impulses, eg from collisions.
|
||||
|
||||
(B{This is not implimented for bullet physics at the moment})
|
||||
|
||||
@rtype: list [fx, fy, fz]
|
||||
@return: the reaction force of this object.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user