This commit is contained in:
2008-07-20 17:25:12 +00:00
parent 31cbb6060c
commit 2c436f660b
13 changed files with 215 additions and 28 deletions

View File

@@ -915,7 +915,10 @@ void lattice_calc_modifiers(Object *ob)
mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
}
if (vertexCos) {
/* always displist to make this work like derivedmesh */
if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
{
DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
dl->type = DL_VERTS;
dl->parts = 1;

View File

@@ -1135,9 +1135,78 @@ static PyObject *M_Library_Load(PyObject *self, PyObject * args)
return (PyObject *)lib;
}
static PyObject *M_Library_GetPaths(PyObject *self, PyObject * args)
{
PyObject *list;
PyObject *name;
int type=0;
Library *lib;
if( !PyArg_ParseTuple( args, "|i", &type ) || type < 0 || type > 2 ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected an int between 0 and 2." );
}
list = PyList_New(0);
for(lib= G.main->library.first; lib; lib= lib->id.next) {
if (type==0) {
/* any type is ok */
} else if (type==1 && lib->parent == 0) {
/* only direct linked */
} else if (type==2 && lib->parent != 0) {
/* only indirect */
} else {
continue; /* incompatible type */
}
name = PyString_FromString(lib->name);
PyList_Append(list, name);
Py_DECREF(name);
}
return list;
}
static PyObject *M_Library_ReplacePath(PyObject *self, PyObject * args)
{
char *name_from, *name_to;
Library *lib;
if( !PyArg_ParseTuple( args, "ss", &name_from, &name_to )) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected the name of a library path" );
}
for(lib= G.main->library.first; lib; lib= lib->id.next) {
if (strcmp(lib->name, name_from)==0) {
if (lib->parent) {
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"path is indirectly linked, cannot be changed." );
}
if (strlen(name_to) > sizeof(lib->name)) {
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"string length too long, cannot set path." );
}
strcpy(lib->name, name_to);
Py_RETURN_NONE;
}
}
return EXPP_ReturnPyObjError( PyExc_ValueError,
"path given does not exist as a library" );
}
static struct PyMethodDef M_Library_methods[] = {
{"load", (PyCFunction)M_Library_Load, METH_VARARGS,
"(string) - declare a .blend file for use as a library"},
{"paths", (PyCFunction)M_Library_GetPaths, METH_VARARGS,
"(type) - return a list of library paths, type 0 for all, 1 only direct links, 2 only indirect links"},
{"replace", (PyCFunction)M_Library_ReplacePath, METH_VARARGS,
"(from, to) - replace the path of an existing, directly linked library."},
{NULL, NULL, 0, NULL}
};

View File

@@ -27,17 +27,37 @@ Example::
"""
def load(filename,relative=False):
"""
Select an existing .blend file for use as a library. Unlike the
Library module, multiple libraries can be defined at the same time.
@type filename: string
@param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
@type relative: boolean
@param relative: Convert relative paths to absolute paths (default). Setting this parameter to True will leave paths relative.
@rtype: Library
@return: return a L{Library} object.
"""
"""
Select an existing .blend file for use as a library. Unlike the
Library module, multiple libraries can be defined at the same time.
@type filename: string
@param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
@type relative: boolean
@param relative: Convert relative paths to absolute paths (default). Setting this parameter to True will leave paths relative.
@rtype: Library
@return: return a L{Library} object.
"""
def paths(link=0):
"""
Returns a list of paths used in the current blend file.
@type link: int
@param link: 0 (default if no args given) for all library paths, 1 for directly linked library paths only, 2 for indirectly linked library paths only.
@rtype: List
@return: return a list of path strings.
"""
def replace(pathFrom, pathTo):
"""
Replaces an existing directly linked path.
@type pathFrom: string
@param pathFrom: An existing library path.
@type pathTo: string
@param pathTo: A new library path.
"""
class Libraries:
"""

View File

@@ -1379,6 +1379,8 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
}
/* specularity */
shadfac[3]*= phongcorr; /* note, shadfac not allowed to be stored nonlocal */
if(shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC) && !(lar->mode & LA_ONLYSHADOW)) {
if(!(passflag & (SCE_PASS_COMBINED|SCE_PASS_SPEC)));

View File

@@ -1275,7 +1275,12 @@ static void drawlattice(Object *ob)
int use_wcol= 0;
lt= (ob==G.obedit)?editLatt:ob->data;
/* now we default make displist, this will modifiers work for non animated case */
if(ob->disp.first==NULL)
lattice_calc_modifiers(ob);
dl= find_displist(&ob->disp, DL_VERTS);
if(ob==G.obedit) {
cpack(0x004000);

View File

@@ -170,10 +170,12 @@ void KX_BulletPhysicsController::SuspendDynamics(bool ghost)
{
btBroadphaseProxy* handle = body->getBroadphaseHandle();
m_savedCollisionFlags = body->getCollisionFlags();
m_savedMass = GetMass();
m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
m_savedCollisionFilterMask = handle->m_collisionFilterMask;
body->setActivationState(DISABLE_SIMULATION);
GetPhysicsEnvironment()->updateCcdPhysicsController(this,
0.0,
btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
btBroadphaseProxy::StaticFilter,
btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
@@ -185,11 +187,12 @@ void KX_BulletPhysicsController::RestoreDynamics()
btRigidBody *body = GetRigidBody();
if (body->getActivationState() == DISABLE_SIMULATION)
{
GetRigidBody()->forceActivationState(ACTIVE_TAG);
GetPhysicsEnvironment()->updateCcdPhysicsController(this,
m_savedMass,
m_savedCollisionFlags,
m_savedCollisionFilterGroup,
m_savedCollisionFilterMask);
GetRigidBody()->forceActivationState(ACTIVE_TAG);
}
}

View File

@@ -11,6 +11,8 @@ private:
int m_savedCollisionFlags;
short int m_savedCollisionFilterGroup;
short int m_savedCollisionFilterMask;
MT_Scalar m_savedMass;
public:
KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna);

View File

@@ -224,6 +224,10 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
RemoveParent(scene);
obj->GetSGNode()->AddChild(GetSGNode());
if (m_pPhysicsController1)
{
m_pPhysicsController1->SuspendDynamics(true);
}
// Set us to our new scale, position, and orientation
scale1[0] = scale1[0]/scale2[0];
scale1[1] = scale1[1]/scale2[1];
@@ -240,10 +244,6 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
if (rootlist->RemoveValue(this))
// the object was in parent list, decrement ref count as it's now removed
Release();
if (m_pPhysicsController1)
{
m_pPhysicsController1->SuspendDynamics(true);
}
}
}
@@ -724,8 +724,12 @@ MT_Vector3 KX_GameObject::GetAngularVelocity(bool local)
void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
{
if (m_pPhysicsController1)
if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{
// don't update physic controller if the object is a child:
// 1) the transformation will not be right
// 2) in this case, the physic controller is necessarily a static object
// that is updated from the normal kinematic synchronization
m_pPhysicsController1->setPosition(trans);
}
@@ -737,25 +741,22 @@ void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot)
{
if (m_pPhysicsController1)
if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{
// see note above
m_pPhysicsController1->setOrientation(rot.getRotation());
}
if (GetSGNode())
GetSGNode()->SetLocalOrientation(rot);
else
{
int i;
i=0;
}
}
void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale)
{
if (m_pPhysicsController1)
if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{
// see note above
m_pPhysicsController1->setScaling(scale);
}
@@ -885,6 +886,8 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_NOARGS},
{"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
{"getChildren", (PyCFunction)KX_GameObject::sPyGetChildren,METH_NOARGS},
{"getChildrenRecursive", (PyCFunction)KX_GameObject::sPyGetChildrenRecursive,METH_NOARGS},
{"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
{"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_NOARGS},
{"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_NOARGS},
@@ -1302,6 +1305,43 @@ PyObject* KX_GameObject::PyRemoveParent(PyObject* self)
Py_RETURN_NONE;
}
static void walk_children(SG_Node* node, PyObject *list, bool recursive)
{
NodeList& children = node->GetSGChildren();
for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
{
SG_Node* childnode = (*childit);
KX_GameObject* childobj = (KX_GameObject*)childnode->GetSGClientObject();
if (childobj != NULL) // This is a GameObject
{
// add to the list
PyList_Append(list, (PyObject *)childobj);
}
// if the childobj is NULL then this may be an inverse parent link
// so a non recursive search should still look down this node.
if (recursive || childobj==NULL) {
walk_children(childnode, list, recursive);
}
}
}
PyObject* KX_GameObject::PyGetChildren(PyObject* self)
{
PyObject * list = PyList_New(0);
walk_children(m_pSGNode, list, 0);
return list;
}
PyObject* KX_GameObject::PyGetChildrenRecursive(PyObject* self)
{
PyObject * list = PyList_New(0);
walk_children(m_pSGNode, list, 1);
return list;
}
PyObject* KX_GameObject::PyGetMesh(PyObject* self,
PyObject* args,
PyObject* kwds)

View File

@@ -746,6 +746,8 @@ public:
KX_PYMETHOD_NOARGS(KX_GameObject,GetParent);
KX_PYMETHOD_O(KX_GameObject,SetParent);
KX_PYMETHOD_NOARGS(KX_GameObject,RemoveParent);
KX_PYMETHOD_NOARGS(KX_GameObject,GetChildren);
KX_PYMETHOD_NOARGS(KX_GameObject,GetChildrenRecursive);
KX_PYMETHOD(KX_GameObject,GetMesh);
KX_PYMETHOD_NOARGS(KX_GameObject,GetPhysicsId);
KX_PYMETHOD_NOARGS(KX_GameObject,GetPropertyNames);

View File

@@ -106,6 +106,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
btRigidBody* m_body;
class PHY_IMotionState* m_MotionState;
btMotionState* m_bulletMotionState;
friend class CcdPhysicsEnvironment; // needed when updating the controller
void* m_newClientInfo;
@@ -194,7 +195,6 @@ class CcdPhysicsController : public PHY_IPhysicsController
return m_cci.m_collisionFilterMask;
}
virtual void calcXform() {} ;
virtual void SetMargin(float margin) {};
virtual float GetMargin() const {return 0.f;};

View File

@@ -466,17 +466,39 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
}
void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
{
// this function is used when the collisionning group of a controller is changed
// remove and add the collistioning object
btRigidBody* body = ctrl->GetRigidBody();
btVector3 inertia;
m_dynamicsWorld->removeCollisionObject(body);
body->setCollisionFlags(newCollisionFlags);
body->getCollisionShape()->calculateLocalInertia(newMass, inertia);
body->setMassProps(newMass, inertia);
m_dynamicsWorld->addCollisionObject(body, newCollisionGroup, newCollisionMask);
// to avoid nasty interaction, we must update the property of the controller as well
ctrl->m_cci.m_mass = newMass;
ctrl->m_cci.m_collisionFilterGroup = newCollisionGroup;
ctrl->m_cci.m_collisionFilterMask = newCollisionMask;
ctrl->m_cci.m_collisionFlags = newCollisionFlags;
}
void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctrl)
{
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_controllers.begin(), m_controllers.end(), ctrl);
if (i == m_controllers.end())
{
btRigidBody* body = ctrl->GetRigidBody();
m_dynamicsWorld->addCollisionObject(body,
ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
}
}
void CcdPhysicsEnvironment::beginFrame()
{

View File

@@ -183,7 +183,14 @@ protected:
void removeCcdPhysicsController(CcdPhysicsController* ctrl);
void updateCcdPhysicsController(CcdPhysicsController* ctrl, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
void updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
void disableCcdPhysicsController(CcdPhysicsController* ctrl)
{
removeCcdPhysicsController(ctrl);
}
void enableCcdPhysicsController(CcdPhysicsController* ctrl);
btBroadphaseInterface* getBroadphase();

View File

@@ -214,6 +214,18 @@ class KX_GameObject:
"""
Removes this objects parent.
"""
def getChildren():
"""
Return a list of immediate children of this object.
@rtype: list
@return: a list of all this objects children.
"""
def getChildrenRecursive():
"""
Return a list of children of this object, including all their childrens children.
@rtype: list
@return: a list of all this objects children recursivly.
"""
def getMesh(mesh):
"""
Gets the mesh object for this object.