svn merge -r15643:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender
This commit is contained in:
@@ -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;
|
||||
|
@@ -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}
|
||||
};
|
||||
|
||||
|
@@ -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:
|
||||
"""
|
||||
|
@@ -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)));
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
@@ -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;};
|
||||
|
@@ -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()
|
||||
{
|
||||
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user