BGE: replace mesh works for Soft Body (including reinstantiation of physics soft body mesh).

Even a static mesh can be used as replacement: the mesh
will be instantiated with the soft body settings of the
object. The position and orientation of the soft body
is preserved after the replacement.

Known limitation: the velocity of the soft body is reset
aftet the replacement. This is because soft body don't
have a well defined velocity.
This commit is contained in:
Benoit Bolsee 2009-11-24 22:44:29 +00:00
parent 6c55047b40
commit 5b722b1e87
26 changed files with 645 additions and 774 deletions

@ -525,10 +525,6 @@
RelativePath="..\..\..\source\gameengine\Converter\BL_SkinDeformer.cpp"
>
</File>
<File
RelativePath="..\..\..\source\gameengine\Converter\BL_SkinMeshObject.cpp"
>
</File>
<File
RelativePath="..\..\..\source\gameengine\Converter\BlenderWorldInfo.cpp"
>
@ -561,6 +557,10 @@
RelativePath="..\..\..\source\gameengine\Converter\KX_IpoConvert.cpp"
>
</File>
<File
RelativePath="..\..\..\source\gameengine\Converter\KX_SoftBodyDeformer.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
@ -614,10 +614,6 @@
RelativePath="..\..\..\source\gameengine\Converter\BL_SkinDeformer.h"
>
</File>
<File
RelativePath="..\..\..\source\gameengine\Converter\BL_SkinMeshObject.h"
>
</File>
<File
RelativePath="..\..\..\source\gameengine\Converter\BlenderWorldInfo.h"
>
@ -650,6 +646,10 @@
RelativePath="..\..\..\source\gameengine\Converter\KX_IpoConvert.h"
>
</File>
<File
RelativePath="..\..\..\source\gameengine\Converter\KX_SoftBodyDeformer.h"
>
</File>
</Filter>
</Files>
<Globals>

@ -43,7 +43,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT;GLEW_STATIC"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -118,7 +118,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
StringPooling="true"
RuntimeLibrary="2"
@ -194,7 +194,7 @@
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT;GLEW_STATIC"
StringPooling="true"
RuntimeLibrary="0"
@ -269,7 +269,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@ -344,7 +344,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT;GLEW_STATIC"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -419,7 +419,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\SceneGraph;..\..\..\..\lib\windows\python\include\python3.1;..\..\..\source\blender\makesdna"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT;GLEW_STATIC"
StringPooling="true"
RuntimeLibrary="0"

@ -89,11 +89,11 @@
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_scene.h"
#include "BL_SkinMeshObject.h"
#include "BL_ModifierDeformer.h"
#include "BL_ShapeDeformer.h"
#include "BL_SkinDeformer.h"
#include "BL_MeshDeformer.h"
#include "KX_SoftBodyDeformer.h"
//#include "BL_ArmatureController.h"
#include "BlenderWorldInfo.h"
@ -720,7 +720,6 @@ bool ConvertMaterial(
RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, KX_BlenderSceneConverter *converter)
{
RAS_MeshObject *meshobj;
bool skinMesh = false;
int lightlayer = blenderobj ? blenderobj->lay:(1<<20)-1; // all layers if no object.
if ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL)
@ -743,14 +742,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
tangent = (float(*)[3])dm->getFaceDataArray(dm, CD_TANGENT);
}
// Determine if we need to make a skinned mesh
if (blenderobj && (mesh->dvert || mesh->key || ((blenderobj->gameflag & OB_SOFT_BODY) != 0) || BL_ModifierDeformer::HasCompatibleDeformer(blenderobj)))
{
meshobj = new BL_SkinMeshObject(mesh);
skinMesh = true;
}
else
meshobj = new RAS_MeshObject(mesh);
meshobj = new RAS_MeshObject(mesh);
// Extract avaiable layers
MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
@ -877,7 +869,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
if (kx_blmat == NULL)
kx_blmat = new KX_BlenderMaterial();
kx_blmat->Initialize(scene, bl_mat, skinMesh);
kx_blmat->Initialize(scene, bl_mat);
polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat);
}
else {
@ -1736,30 +1728,34 @@ static KX_GameObject *gameobject_from_blenderobject(
bool bHasDvert = mesh->dvert != NULL && ob->defbase.first;
bool bHasArmature = (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && bHasDvert);
bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(ob);
bool bHasSoftBody = (!ob->parent && (ob->gameflag & OB_SOFT_BODY));
if (bHasModifier) {
BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL_DeformableGameObject *)gameobj,
kxscene->GetBlenderScene(), ob, (BL_SkinMeshObject *)meshobj);
kxscene->GetBlenderScene(), ob, meshobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
if (bHasShapeKey && bHasArmature)
dcont->LoadShapeDrivers(ob->parent);
} else if (bHasShapeKey) {
// not that we can have shape keys without dvert!
BL_ShapeDeformer *dcont = new BL_ShapeDeformer((BL_DeformableGameObject*)gameobj,
ob, (BL_SkinMeshObject*)meshobj);
ob, meshobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
if (bHasArmature)
dcont->LoadShapeDrivers(ob->parent);
} else if (bHasArmature) {
BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
ob, (BL_SkinMeshObject*)meshobj);
ob, meshobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
} else if (bHasDvert) {
// this case correspond to a mesh that can potentially deform but not with the
// object to which it is attached for the moment. A skin mesh was created in
// BL_ConvertMesh() so must create a deformer too!
BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
ob, (BL_SkinMeshObject*)meshobj);
ob, meshobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
} else if (bHasSoftBody) {
KX_SoftBodyDeformer *dcont = new KX_SoftBodyDeformer(meshobj, (BL_DeformableGameObject*)gameobj);
((BL_DeformableGameObject*)gameobj)->SetDeformer(dcont);
}

@ -41,7 +41,7 @@
#include "RAS_IPolygonMaterial.h"
#include "BL_DeformableGameObject.h"
#include "BL_MeshDeformer.h"
#include "BL_SkinMeshObject.h"
#include "RAS_MeshObject.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"

@ -50,7 +50,7 @@ public:
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map);
BL_MeshDeformer(BL_DeformableGameObject *gameobj,
struct Object* obj,
class BL_SkinMeshObject *meshobj ):
class RAS_MeshObject *meshobj ):
m_pMeshObject(meshobj),
m_bmesh((struct Mesh*)(obj->data)),
m_transverts(0),
@ -73,7 +73,7 @@ public:
// virtual void InitDeform(double time){};
protected:
class BL_SkinMeshObject* m_pMeshObject;
class RAS_MeshObject* m_pMeshObject;
struct Mesh* m_bmesh;
// this is so m_transverts doesn't need to be converted

@ -36,7 +36,7 @@
#include "GEN_Map.h"
#include "STR_HashedString.h"
#include "RAS_IPolygonMaterial.h"
#include "BL_SkinMeshObject.h"
#include "RAS_MeshObject.h"
#include "PHY_IGraphicController.h"
//#include "BL_ArmatureController.h"

@ -50,7 +50,7 @@ public:
BL_ModifierDeformer(BL_DeformableGameObject *gameobj,
Scene *scene,
Object *bmeshobj,
BL_SkinMeshObject *mesh)
RAS_MeshObject *mesh)
:
BL_ShapeDeformer(gameobj,bmeshobj, mesh),
m_lastModifierUpdate(-1),
@ -65,7 +65,7 @@ public:
struct Scene *scene,
struct Object *bmeshobj_old,
struct Object *bmeshobj_new,
class BL_SkinMeshObject *mesh,
class RAS_MeshObject *mesh,
bool release_object,
BL_ArmatureObject* arma = NULL)
:

@ -36,7 +36,7 @@
#include "GEN_Map.h"
#include "STR_HashedString.h"
#include "RAS_IPolygonMaterial.h"
#include "BL_SkinMeshObject.h"
#include "RAS_MeshObject.h"
//#include "BL_ArmatureController.h"
#include "DNA_armature_types.h"

@ -45,7 +45,7 @@ class BL_ShapeDeformer : public BL_SkinDeformer
public:
BL_ShapeDeformer(BL_DeformableGameObject *gameobj,
Object *bmeshobj,
BL_SkinMeshObject *mesh)
RAS_MeshObject *mesh)
:
BL_SkinDeformer(gameobj,bmeshobj, mesh),
m_lastShapeUpdate(-1)
@ -56,7 +56,7 @@ public:
BL_ShapeDeformer(BL_DeformableGameObject *gameobj,
struct Object *bmeshobj_old,
struct Object *bmeshobj_new,
class BL_SkinMeshObject *mesh,
class RAS_MeshObject *mesh,
bool release_object,
bool recalc_normal,
BL_ArmatureObject* arma = NULL)

@ -35,7 +35,7 @@
#include "GEN_Map.h"
#include "STR_HashedString.h"
#include "RAS_IPolygonMaterial.h"
#include "BL_SkinMeshObject.h"
#include "RAS_MeshObject.h"
//#include "BL_ArmatureController.h"
#include "DNA_armature_types.h"
@ -59,7 +59,7 @@ extern "C"{
BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
struct Object *bmeshobj,
class BL_SkinMeshObject *mesh,
class RAS_MeshObject *mesh,
BL_ArmatureObject* arma)
: //
BL_MeshDeformer(gameobj, bmeshobj, mesh),
@ -77,7 +77,7 @@ BL_SkinDeformer::BL_SkinDeformer(
BL_DeformableGameObject *gameobj,
struct Object *bmeshobj_old, // Blender object that owns the new mesh
struct Object *bmeshobj_new, // Blender object that owns the original mesh
class BL_SkinMeshObject *mesh,
class RAS_MeshObject *mesh,
bool release_object,
bool recalc_normal,
BL_ArmatureObject* arma) :

@ -55,14 +55,14 @@ public:
BL_SkinDeformer(BL_DeformableGameObject *gameobj,
struct Object *bmeshobj,
class BL_SkinMeshObject *mesh,
class RAS_MeshObject *mesh,
BL_ArmatureObject* arma = NULL);
/* this second constructor is needed for making a mesh deformable on the fly. */
BL_SkinDeformer(BL_DeformableGameObject *gameobj,
struct Object *bmeshobj_old,
struct Object *bmeshobj_new,
class BL_SkinMeshObject *mesh,
class RAS_MeshObject *mesh,
bool release_object,
bool recalc_normal,
BL_ArmatureObject* arma = NULL);

@ -1,156 +0,0 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
* Deformer that supports armature skinning
*/
#ifdef WIN32
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
#endif //WIN32
#include "MEM_guardedalloc.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "RAS_BucketManager.h"
#include "RAS_IPolygonMaterial.h"
#include "KX_GameObject.h"
#include "BL_SkinMeshObject.h"
#include "BL_DeformableGameObject.h"
BL_SkinMeshObject::BL_SkinMeshObject(Mesh* mesh)
: RAS_MeshObject (mesh)
{
m_bDeformed = true;
if (m_mesh && m_mesh->key)
{
KeyBlock *kb;
int count=0;
// initialize weight cache for shape objects
// count how many keys in this mesh
for(kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next)
count++;
m_cacheWeightIndex.resize(count,-1);
}
}
BL_SkinMeshObject::~BL_SkinMeshObject()
{
if (m_mesh && m_mesh->key)
{
KeyBlock *kb;
// remove the weight cache to avoid memory leak
for(kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next) {
if(kb->weights)
MEM_freeN(kb->weights);
kb->weights= NULL;
}
}
}
void BL_SkinMeshObject::UpdateBuckets(void* clientobj,double* oglmatrix,bool useObjectColor,const MT_Vector4& rgbavec, bool visible, bool culled)
{
list<RAS_MeshMaterial>::iterator it;
list<RAS_MeshSlot*>::iterator sit;
for(it = m_materials.begin();it!=m_materials.end();++it) {
if(!it->m_slots[clientobj])
continue;
RAS_MeshSlot *slot = *it->m_slots[clientobj];
slot->SetDeformer(((BL_DeformableGameObject*)clientobj)->GetDeformer());
}
RAS_MeshObject::UpdateBuckets(clientobj, oglmatrix, useObjectColor, rgbavec, visible, culled);
}
static int get_def_index(Object* ob, const char* vgroup)
{
bDeformGroup *curdef;
int index = 0;
for (curdef = (bDeformGroup*)ob->defbase.first; curdef; curdef=(bDeformGroup*)curdef->next, index++)
if (!strcmp(curdef->name, vgroup))
return index;
return -1;
}
void BL_SkinMeshObject::CheckWeightCache(Object* obj)
{
KeyBlock *kb;
int kbindex, defindex;
MDeformVert *dvert= NULL;
int totvert, i, j;
float *weights;
if (!m_mesh->key)
return;
for(kbindex=0, kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next, kbindex++)
{
// first check the cases where the weight must be cleared
if (kb->vgroup[0] == 0 ||
m_mesh->dvert == NULL ||
(defindex = get_def_index(obj, kb->vgroup)) == -1) {
if (kb->weights) {
MEM_freeN(kb->weights);
kb->weights = NULL;
}
m_cacheWeightIndex[kbindex] = -1;
} else if (m_cacheWeightIndex[kbindex] != defindex) {
// a weight array is required but the cache is not matching
if (kb->weights) {
MEM_freeN(kb->weights);
kb->weights = NULL;
}
dvert= m_mesh->dvert;
totvert= m_mesh->totvert;
weights= (float*)MEM_callocN(totvert*sizeof(float), "weights");
for (i=0; i < totvert; i++, dvert++) {
for(j=0; j<dvert->totweight; j++) {
if (dvert->dw[j].def_nr == defindex) {
weights[i]= dvert->dw[j].weight;
break;
}
}
}
kb->weights = weights;
m_cacheWeightIndex[kbindex] = defindex;
}
}
}

@ -1,67 +0,0 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __BL_SKINMESHOBJECT
#define __BL_SKINMESHOBJECT
#ifdef WIN32
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
#endif //WIN32
#include "RAS_MeshObject.h"
#include "RAS_Deformer.h"
#include "RAS_IPolygonMaterial.h"
#include "BL_MeshDeformer.h"
class BL_SkinMeshObject : public RAS_MeshObject
{
protected:
vector<int> m_cacheWeightIndex;
public:
BL_SkinMeshObject(Mesh* mesh);
~BL_SkinMeshObject();
void UpdateBuckets(void* clientobj, double* oglmatrix,
bool useObjectColor, const MT_Vector4& rgbavec, bool visible, bool culled);
// for shape keys,
void CheckWeightCache(struct Object* obj);
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_SkinMeshObject"); }
void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
#endif

@ -0,0 +1,120 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifdef WIN32
#pragma warning (disable : 4786)
#endif //WIN32
#include "MT_assert.h"
#include "KX_ConvertPhysicsObject.h"
#include "KX_SoftBodyDeformer.h"
#include "RAS_MeshObject.h"
#include "GEN_Map.h"
#include "GEN_HashedPtr.h"
#ifdef USE_BULLET
#include "CcdPhysicsEnvironment.h"
#include "CcdPhysicsController.h"
#include "BulletSoftBody/btSoftBody.h"
#include "KX_BulletPhysicsController.h"
#include "btBulletDynamicsCommon.h"
void KX_SoftBodyDeformer::Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
{
void **h_obj = (*map)[m_gameobj];
if (h_obj) {
m_gameobj = (BL_DeformableGameObject*)(*h_obj);
m_pMeshObject = m_gameobj->GetMesh(0);
} else {
m_gameobj = NULL;
m_pMeshObject = NULL;
}
}
bool KX_SoftBodyDeformer::Apply(class RAS_IPolyMaterial *polymat)
{
KX_BulletPhysicsController* ctrl = (KX_BulletPhysicsController*) m_gameobj->GetPhysicsController();
if (!ctrl)
return false;
btSoftBody* softBody= ctrl->GetSoftBody();
if (!softBody)
return false;
//printf("apply\n");
RAS_MeshSlot::iterator it;
RAS_MeshMaterial *mmat;
RAS_MeshSlot *slot;
size_t i;
// update the vertex in m_transverts
Update();
// The vertex cache can only be updated for this deformer:
// Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
// share the same mesh (=the same cache). As the rendering is done per polymaterial
// cycling through the objects, the entire mesh cache cannot be updated in one shot.
mmat = m_pMeshObject->GetMeshMaterial(polymat);
if(!mmat->m_slots[(void*)m_gameobj])
return true;
slot = *mmat->m_slots[(void*)m_gameobj];
// for each array
for(slot->begin(it); !slot->end(it); slot->next(it))
{
btSoftBody::tNodeArray& nodes(softBody->m_nodes);
int index = 0;
for(i=it.startvertex; i<it.endvertex; i++,index++) {
RAS_TexVert& v = it.vertex[i];
btAssert(v.getSoftBodyIndex() >= 0);
MT_Point3 pt (
nodes[v.getSoftBodyIndex()].m_x.getX(),
nodes[v.getSoftBodyIndex()].m_x.getY(),
nodes[v.getSoftBodyIndex()].m_x.getZ());
v.SetXYZ(pt);
MT_Vector3 normal (
nodes[v.getSoftBodyIndex()].m_n.getX(),
nodes[v.getSoftBodyIndex()].m_n.getY(),
nodes[v.getSoftBodyIndex()].m_n.getZ());
v.SetNormal(normal);
}
}
return true;
}
#endif

@ -0,0 +1,102 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef KX_SOFTBODYDEFORMER
#define KX_SOFTBODYDEFORMER
#ifdef WIN32
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
#endif //WIN32
#include "RAS_Deformer.h"
#include "BL_DeformableGameObject.h"
#include <vector>
class KX_SoftBodyDeformer : public RAS_Deformer
{
class RAS_MeshObject* m_pMeshObject;
class BL_DeformableGameObject* m_gameobj;
public:
KX_SoftBodyDeformer(RAS_MeshObject* pMeshObject,BL_DeformableGameObject* gameobj)
:m_pMeshObject(pMeshObject),
m_gameobj(gameobj)
{
//printf("KX_SoftBodyDeformer\n");
};
virtual ~KX_SoftBodyDeformer()
{
//printf("~KX_SoftBodyDeformer\n");
};
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map);
virtual bool Apply(class RAS_IPolyMaterial *polymat);
virtual bool Update(void)
{
//printf("update\n");
m_bDynamic = true;
return true;//??
}
virtual bool UpdateBuckets(void)
{
// this is to update the mesh slots outside the rasterizer,
// no need to do it for this deformer, it's done in any case in Apply()
return false;
}
virtual RAS_Deformer *GetReplica()
{
KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(*this);
deformer->ProcessReplica();
return deformer;
}
virtual void ProcessReplica()
{
// we have two pointers to deal with but we cannot do it now, will be done in Relink
m_bDynamic = false;
}
virtual bool SkipVertexTransform()
{
return true;
}
protected:
//class RAS_MeshObject *m_pMesh;
#ifdef WITH_CXX_GUARDEDALLOC
public:
void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ShapeDeformer"); }
void operator delete( void *mem ) { MEM_freeN(mem); }
#endif
};
#endif

@ -58,8 +58,7 @@ KX_BlenderMaterial::KX_BlenderMaterial()
void KX_BlenderMaterial::Initialize(
KX_Scene *scene,
BL_Material *data,
bool skin)
BL_Material *data)
{
RAS_IPolyMaterial::Initialize(
data->texname[0],

@ -33,8 +33,7 @@ public:
KX_BlenderMaterial();
void Initialize(
class KX_Scene* scene,
BL_Material* mat,
bool skin
BL_Material* mat
);
virtual ~KX_BlenderMaterial();

@ -32,12 +32,12 @@
#include "MT_assert.h"
#include "KX_SoftBodyDeformer.h"
#include "KX_ConvertPhysicsObject.h"
#include "BL_DeformableGameObject.h"
#include "RAS_MeshObject.h"
#include "KX_Scene.h"
#include "SYS_System.h"
#include "BL_SkinMeshObject.h"
#include "BulletSoftBody/btSoftBody.h"
#include "PHY_Pro.h" //todo cleanup
@ -79,126 +79,6 @@ extern "C"{
#endif //WIN32
class KX_SoftBodyDeformer : public RAS_Deformer
{
class RAS_MeshObject* m_pMeshObject;
class BL_DeformableGameObject* m_gameobj;
public:
KX_SoftBodyDeformer(RAS_MeshObject* pMeshObject,BL_DeformableGameObject* gameobj)
:m_pMeshObject(pMeshObject),
m_gameobj(gameobj)
{
//printf("KX_SoftBodyDeformer\n");
};
virtual ~KX_SoftBodyDeformer()
{
//printf("~KX_SoftBodyDeformer\n");
};
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
{
void **h_obj = (*map)[m_gameobj];
if (h_obj) {
m_gameobj = (BL_DeformableGameObject*)(*h_obj);
m_pMeshObject = m_gameobj->GetMesh(0);
} else {
m_gameobj = NULL;
m_pMeshObject = NULL;
}
}
virtual bool Apply(class RAS_IPolyMaterial *polymat)
{
KX_BulletPhysicsController* ctrl = (KX_BulletPhysicsController*) m_gameobj->GetPhysicsController();
if (!ctrl)
return false;
btSoftBody* softBody= ctrl->GetSoftBody();
if (!softBody)
return false;
//printf("apply\n");
RAS_MeshSlot::iterator it;
RAS_MeshMaterial *mmat;
RAS_MeshSlot *slot;
size_t i;
// update the vertex in m_transverts
Update();
// The vertex cache can only be updated for this deformer:
// Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
// share the same mesh (=the same cache). As the rendering is done per polymaterial
// cycling through the objects, the entire mesh cache cannot be updated in one shot.
mmat = m_pMeshObject->GetMeshMaterial(polymat);
if(!mmat->m_slots[(void*)m_gameobj])
return true;
slot = *mmat->m_slots[(void*)m_gameobj];
// for each array
for(slot->begin(it); !slot->end(it); slot->next(it))
{
btSoftBody::tNodeArray& nodes(softBody->m_nodes);
int index = 0;
for(i=it.startvertex; i<it.endvertex; i++,index++) {
RAS_TexVert& v = it.vertex[i];
btAssert(v.getSoftBodyIndex() >= 0);
MT_Point3 pt (
nodes[v.getSoftBodyIndex()].m_x.getX(),
nodes[v.getSoftBodyIndex()].m_x.getY(),
nodes[v.getSoftBodyIndex()].m_x.getZ());
v.SetXYZ(pt);
MT_Vector3 normal (
nodes[v.getSoftBodyIndex()].m_n.getX(),
nodes[v.getSoftBodyIndex()].m_n.getY(),
nodes[v.getSoftBodyIndex()].m_n.getZ());
v.SetNormal(normal);
}
}
return true;
}
virtual bool Update(void)
{
//printf("update\n");
m_bDynamic = true;
return true;//??
}
virtual bool UpdateBuckets(void)
{
// this is to update the mesh slots outside the rasterizer,
// no need to do it for this deformer, it's done in any case in Apply()
return false;
}
virtual RAS_Deformer *GetReplica()
{
KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(*this);
deformer->ProcessReplica();
return deformer;
}
virtual void ProcessReplica()
{
// we have two pointers to deal with but we cannot do it now, will be done in Relink
m_bDynamic = false;
}
virtual bool SkipVertexTransform()
{
return true;
}
protected:
//class RAS_MeshObject *m_pMesh;
};
// forward declarations
@ -608,7 +488,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
physicscontroller->SetObject(gameobj->GetSGNode());
#if 0
///test for soft bodies
if (objprop->m_softbody && physicscontroller)
{
@ -620,6 +500,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
gameobj->SetDeformer(softbodyDeformer);
}
}
#endif
}
@ -651,7 +532,7 @@ bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *fro
shapeInfo = spc->GetShapeInfo();
if(shapeInfo->m_shapeType != PHY_SHAPE_MESH || spc->GetSoftBody())
if(shapeInfo->m_shapeType != PHY_SHAPE_MESH/* || spc->GetSoftBody()*/)
return false;
spc->DeleteControllerShape();

@ -53,7 +53,6 @@
#include "SCA_JoystickManager.h"
#include "RAS_MeshObject.h"
#include "BL_SkinMeshObject.h"
#include "RAS_IRasterizer.h"
#include "RAS_BucketManager.h"
@ -83,6 +82,7 @@
#include "BL_ModifierDeformer.h"
#include "BL_ShapeDeformer.h"
#include "BL_DeformableGameObject.h"
#include "KX_SoftBodyDeformer.h"
// to get USE_BULLET!
#include "KX_ConvertPhysicsObject.h"
@ -1076,7 +1076,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
newobj->SetDeformer(NULL);
}
if (mesh->IsDeformed()) /* checks GetMesh() isnt NULL */
if (mesh->GetMesh())
{
// we must create a new deformer but which one?
KX_GameObject* parentobj = newobj->GetParent();
@ -1097,12 +1097,14 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
blendobj->parent->type == OB_ARMATURE &&
blendobj->partype==PARSKEL &&
blendmesh->dvert!=NULL; // mesh has vertex group
bool bHasSoftBody = (!parentobj && (blendobj->gameflag & OB_SOFT_BODY));
bool releaseParent = true;
if (oldblendobj==NULL) {
std::cout << "warning: ReplaceMesh() new mesh is not used in an object from the current scene, you will get incorrect behavior" << std::endl;
bHasShapeKey= bHasDvert= bHasArmature=bHasModifier= false;
bHasShapeKey= bHasDvert= bHasArmature=bHasModifier=bHasSoftBody= false;
}
if (bHasModifier)
@ -1114,7 +1116,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
newobj,
m_blenderScene,
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
mesh,
true,
static_cast<BL_ArmatureObject*>( parentobj )
);
@ -1127,7 +1129,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
newobj,
m_blenderScene,
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
mesh,
false,
NULL
);
@ -1142,7 +1144,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
shapeDeformer = new BL_ShapeDeformer(
newobj,
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
mesh,
true,
true,
static_cast<BL_ArmatureObject*>( parentobj )
@ -1155,7 +1157,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
shapeDeformer = new BL_ShapeDeformer(
newobj,
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
mesh,
false,
true,
NULL
@ -1168,7 +1170,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
BL_SkinDeformer* skinDeformer = new BL_SkinDeformer(
newobj,
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
mesh,
true,
true,
static_cast<BL_ArmatureObject*>( parentobj )
@ -1179,10 +1181,15 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj, bool use_gfx, bool u
else if (bHasDvert)
{
BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(
newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
newobj, oldblendobj, mesh
);
newobj->SetDeformer(meshdeformer);
}
else if (bHasSoftBody)
{
KX_SoftBodyDeformer *softdeformer = new KX_SoftBodyDeformer(mesh, newobj);
newobj->SetDeformer(softdeformer);
}
// release parent reference if its not being used
if( releaseParent && parentobj)

@ -161,6 +161,246 @@ btSoftBody* CcdPhysicsController::GetSoftBody()
#include "BulletSoftBody/btSoftBodyHelpers.h"
bool CcdPhysicsController::CreateSoftbody()
{
int shapeType = m_cci.m_collisionShape ? m_cci.m_collisionShape->getShapeType() : 0;
//disable soft body until first sneak preview is ready
if (!m_cci.m_bSoft || !m_cci.m_collisionShape ||
(shapeType != CONVEX_HULL_SHAPE_PROXYTYPE)&&
(shapeType != TRIANGLE_MESH_SHAPE_PROXYTYPE) &&
(shapeType != SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE))
{
return false;
}
btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
rbci.m_linearDamping = m_cci.m_linearDamping;
rbci.m_angularDamping = m_cci.m_angularDamping;
rbci.m_friction = m_cci.m_friction;
rbci.m_restitution = m_cci.m_restitution;
btVector3 p(0,0,0);// = getOrigin();
//btSoftBody* psb=btSoftBodyHelpers::CreateRope(worldInfo, btVector3(-10,0,i*0.25),btVector3(10,0,i*0.25), 16,1+2);
btSoftBody* psb = 0;
btSoftBodyWorldInfo& worldInfo = m_cci.m_physicsEnv->getDynamicsWorld()->getWorldInfo();
if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE)
{
btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape;
{
int nvertices = convexHull->getNumPoints();
const btVector3* vertices = convexHull->getPoints();
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
HullResult hres;
HullLibrary hlib;/*??*/
hdsc.mMaxVertices=nvertices;
hlib.CreateConvexHull(hdsc,hres);
psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices,
&hres.m_OutputVertices[0],0);
for(int i=0;i<(int)hres.mNumFaces;++i)
{
const int idx[]={ hres.m_Indices[i*3+0],
hres.m_Indices[i*3+1],
hres.m_Indices[i*3+2]};
if(idx[0]<idx[1]) psb->appendLink( idx[0],idx[1]);
if(idx[1]<idx[2]) psb->appendLink( idx[1],idx[2]);
if(idx[2]<idx[0]) psb->appendLink( idx[2],idx[0]);
psb->appendFace(idx[0],idx[1],idx[2]);
}
hlib.ReleaseResult(hres);
}
} else
{
if (m_cci.m_collisionShape->getShapeType() ==SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
btScaledBvhTriangleMeshShape* scaledtrimeshshape = (btScaledBvhTriangleMeshShape*) m_cci.m_collisionShape;
btBvhTriangleMeshShape* trimeshshape = scaledtrimeshshape->getChildShape();
///only deal with meshes that have 1 sub part/component, for now
if (trimeshshape->getMeshInterface()->getNumSubParts()==1)
{
unsigned char* vertexBase;
PHY_ScalarType vertexType;
int numverts;
int vertexstride;
unsigned char* indexbase;
int indexstride;
int numtris;
PHY_ScalarType indexType;
trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType);
psb = btSoftBodyHelpers::CreateFromTriMesh(worldInfo,(const btScalar*)vertexBase,(const int*)indexbase,numtris);
}
} else
{
btBvhTriangleMeshShape* trimeshshape = (btBvhTriangleMeshShape*) m_cci.m_collisionShape;
///only deal with meshes that have 1 sub part/component, for now
if (trimeshshape->getMeshInterface()->getNumSubParts()==1)
{
unsigned char* vertexBase;
PHY_ScalarType vertexType;
int numverts;
int vertexstride;
unsigned char* indexbase;
int indexstride;
int numtris;
PHY_ScalarType indexType;
trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType);
psb = btSoftBodyHelpers::CreateFromTriMesh(worldInfo,(const btScalar*)vertexBase,(const int*)indexbase,numtris);
}
}
}
if (m_cci.m_margin > 0.f)
{
psb->getCollisionShape()->setMargin(m_cci.m_margin);
psb->updateBounds();
}
m_object = psb;
//btSoftBody::Material* pm=psb->appendMaterial();
btSoftBody::Material* pm=psb->m_materials[0];
pm->m_kLST = m_cci.m_soft_linStiff;
pm->m_kAST = m_cci.m_soft_angStiff;
pm->m_kVST = m_cci.m_soft_volume;
psb->m_cfg.collisions = 0;
if (m_cci.m_soft_collisionflags & CCD_BSB_COL_CL_RS)
{
psb->m_cfg.collisions += btSoftBody::fCollision::CL_RS;
} else
{
psb->m_cfg.collisions += btSoftBody::fCollision::SDF_RS;
}
if (m_cci.m_soft_collisionflags & CCD_BSB_COL_CL_SS)
{
psb->m_cfg.collisions += btSoftBody::fCollision::CL_SS;
} else
{
psb->m_cfg.collisions += btSoftBody::fCollision::VF_SS;
}
psb->m_cfg.kSRHR_CL = m_cci.m_soft_kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */
psb->m_cfg.kSKHR_CL = m_cci.m_soft_kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */
psb->m_cfg.kSSHR_CL = m_cci.m_soft_kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */
psb->m_cfg.kSR_SPLT_CL = m_cci.m_soft_kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
psb->m_cfg.kSK_SPLT_CL = m_cci.m_soft_kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
psb->m_cfg.kSS_SPLT_CL = m_cci.m_soft_kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
psb->m_cfg.kVCF = m_cci.m_soft_kVCF; /* Velocities correction factor (Baumgarte) */
psb->m_cfg.kDP = m_cci.m_soft_kDP; /* Damping coefficient [0,1] */
psb->m_cfg.kDG = m_cci.m_soft_kDG; /* Drag coefficient [0,+inf] */
psb->m_cfg.kLF = m_cci.m_soft_kLF; /* Lift coefficient [0,+inf] */
psb->m_cfg.kPR = m_cci.m_soft_kPR; /* Pressure coefficient [-inf,+inf] */
psb->m_cfg.kVC = m_cci.m_soft_kVC; /* Volume conversation coefficient [0,+inf] */
psb->m_cfg.kDF = m_cci.m_soft_kDF; /* Dynamic friction coefficient [0,1] */
psb->m_cfg.kMT = m_cci.m_soft_kMT; /* Pose matching coefficient [0,1] */
psb->m_cfg.kCHR = m_cci.m_soft_kCHR; /* Rigid contacts hardness [0,1] */
psb->m_cfg.kKHR = m_cci.m_soft_kKHR; /* Kinetic contacts hardness [0,1] */
psb->m_cfg.kSHR = m_cci.m_soft_kSHR; /* Soft contacts hardness [0,1] */
psb->m_cfg.kAHR = m_cci.m_soft_kAHR; /* Anchors hardness [0,1] */
if (m_cci.m_gamesoftFlag & CCD_BSB_BENDING_CONSTRAINTS)//OB_SB_GOAL)
{
psb->generateBendingConstraints(2,pm);
}
psb->m_cfg.piterations = m_cci.m_soft_piterations;
psb->m_cfg.viterations = m_cci.m_soft_viterations;
psb->m_cfg.diterations = m_cci.m_soft_diterations;
psb->m_cfg.citerations = m_cci.m_soft_citerations;
if (m_cci.m_gamesoftFlag & CCD_BSB_SHAPE_MATCHING)//OB_SB_GOAL)
{
psb->setPose(false,true);//
} else
{
psb->setPose(true,false);
}
psb->randomizeConstraints();
if (m_cci.m_soft_collisionflags & (CCD_BSB_COL_CL_RS+CCD_BSB_COL_CL_SS))
{
psb->generateClusters(m_cci.m_soft_numclusteriterations);
}
psb->setTotalMass(m_cci.m_mass);
psb->setCollisionFlags(0);
///create a mapping between graphics mesh vertices and soft body vertices
{
RAS_MeshObject* rasMesh= GetShapeInfo()->GetMesh();
if (rasMesh && !m_softbodyMappingDone)
{
//printf("apply\n");
RAS_MeshSlot::iterator it;
RAS_MeshMaterial *mmat;
RAS_MeshSlot *slot;
size_t i;
//for each material
for (int m=0;m<rasMesh->NumMaterials();m++)
{
mmat = rasMesh->GetMeshMaterial(m);
slot = mmat->m_baseslot;
for(slot->begin(it); !slot->end(it); slot->next(it))
{
int index = 0;
for(i=it.startvertex; i<it.endvertex; i++,index++)
{
RAS_TexVert* vertex = &it.vertex[i];
//search closest index, and store it in vertex
vertex->setSoftBodyIndex(0);
btScalar maxDistSqr = 1e30;
btSoftBody::tNodeArray& nodes(psb->m_nodes);
btVector3 xyz = btVector3(vertex->getXYZ()[0],vertex->getXYZ()[1],vertex->getXYZ()[2]);
for (int n=0;n<nodes.size();n++)
{
btScalar distSqr = (nodes[n].m_x - xyz).length2();
if (distSqr<maxDistSqr)
{
maxDistSqr = distSqr;
vertex->setSoftBodyIndex(n);
}
}
}
}
}
}
}
m_softbodyMappingDone = true;
btTransform startTrans;
rbci.m_motionState->getWorldTransform(startTrans);
m_MotionState->setWorldPosition(startTrans.getOrigin().getX(),startTrans.getOrigin().getY(),startTrans.getOrigin().getZ());
m_MotionState->setWorldOrientation(0,0,0,1);
if (!m_prototypeTransformInitialized)
{
m_prototypeTransformInitialized = true;
m_softBodyTransformInitialized = true;
psb->transform(startTrans);
}
m_object->setCollisionFlags(m_object->getCollisionFlags() | m_cci.m_collisionFlags);
if (m_cci.m_do_anisotropic)
m_object->setAnisotropicFriction(m_cci.m_anisotropicFriction);
return true;
}
void CcdPhysicsController::CreateRigidbody()
{
@ -169,330 +409,17 @@ void CcdPhysicsController::CreateRigidbody()
m_bulletMotionState = new BlenderBulletMotionState(m_MotionState);
///either create a btCollisionObject, btRigidBody or btSoftBody
if (CreateSoftbody())
// soft body created, done
return;
//create a collision object
int shapeType = m_cci.m_collisionShape ? m_cci.m_collisionShape->getShapeType() : 0;
//disable soft body until first sneak preview is ready
if (m_cci.m_bSoft && m_cci.m_collisionShape &&
(shapeType == CONVEX_HULL_SHAPE_PROXYTYPE)|
(shapeType == TRIANGLE_MESH_SHAPE_PROXYTYPE) |
(shapeType == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE))
{
btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
rbci.m_linearDamping = m_cci.m_linearDamping;
rbci.m_angularDamping = m_cci.m_angularDamping;
rbci.m_friction = m_cci.m_friction;
rbci.m_restitution = m_cci.m_restitution;
btVector3 p(0,0,0);// = getOrigin();
btSoftRigidDynamicsWorld* softDynaWorld = (btSoftRigidDynamicsWorld*)m_cci.m_physicsEnv->getDynamicsWorld();
PHY__Vector3 grav;
grav[0] = softDynaWorld->getGravity().getX();
grav[1] = softDynaWorld->getGravity().getY();
grav[2] = softDynaWorld->getGravity().getZ();
softDynaWorld->getWorldInfo().m_gravity.setValue(grav[0],grav[1],grav[2]); //??
//btSoftBody* psb=btSoftBodyHelpers::CreateRope(sbi, btVector3(-10,0,i*0.25),btVector3(10,0,i*0.25), 16,1+2);
btSoftBody* psb = 0;
if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE)
{
btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape;
//psb = btSoftBodyHelpers::CreateFromConvexHull(sbi,&transformedVertices[0],convexHull->getNumPoints());
{
int nvertices = convexHull->getNumPoints();
const btVector3* vertices = convexHull->getPoints();
btSoftBodyWorldInfo& worldInfo = softDynaWorld->getWorldInfo();
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
HullResult hres;
HullLibrary hlib;/*??*/
hdsc.mMaxVertices=nvertices;
hlib.CreateConvexHull(hdsc,hres);
psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices,
&hres.m_OutputVertices[0],0);
for(int i=0;i<(int)hres.mNumFaces;++i)
{
const int idx[]={ hres.m_Indices[i*3+0],
hres.m_Indices[i*3+1],
hres.m_Indices[i*3+2]};
if(idx[0]<idx[1]) psb->appendLink( idx[0],idx[1]);
if(idx[1]<idx[2]) psb->appendLink( idx[1],idx[2]);
if(idx[2]<idx[0]) psb->appendLink( idx[2],idx[0]);
psb->appendFace(idx[0],idx[1],idx[2]);
}
hlib.ReleaseResult(hres);
}
} else
{
btSoftBodyWorldInfo& sbi= softDynaWorld->getWorldInfo();
if (m_cci.m_collisionShape->getShapeType() ==SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
btScaledBvhTriangleMeshShape* scaledtrimeshshape = (btScaledBvhTriangleMeshShape*) m_cci.m_collisionShape;
btBvhTriangleMeshShape* trimeshshape = scaledtrimeshshape->getChildShape();
///only deal with meshes that have 1 sub part/component, for now
if (trimeshshape->getMeshInterface()->getNumSubParts()==1)
{
unsigned char* vertexBase;
PHY_ScalarType vertexType;
int numverts;
int vertexstride;
unsigned char* indexbase;
int indexstride;
int numtris;
PHY_ScalarType indexType;
trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType);
psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,(const btScalar*)vertexBase,(const int*)indexbase,numtris);
}
} else
{
btBvhTriangleMeshShape* trimeshshape = (btBvhTriangleMeshShape*) m_cci.m_collisionShape;
///only deal with meshes that have 1 sub part/component, for now
if (trimeshshape->getMeshInterface()->getNumSubParts()==1)
{
unsigned char* vertexBase;
PHY_ScalarType vertexType;
int numverts;
int vertexstride;
unsigned char* indexbase;
int indexstride;
int numtris;
PHY_ScalarType indexType;
trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType);
psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,(const btScalar*)vertexBase,(const int*)indexbase,numtris);
}
//psb = btSoftBodyHelpers::CreateFromTriMesh(sbi,&pts[0].getX(),triangles,numtriangles);
}
}
if (m_cci.m_margin > 0.f)
{
psb->getCollisionShape()->setMargin(m_cci.m_margin);
psb->updateBounds();
}
m_object = psb;
//psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RS;//btSoftBody::fCollision::CL_SS+ btSoftBody::fCollision::CL_RS;
//psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RS + btSoftBody::fCollision::VF_SS;//CL_SS;
//btSoftBody::Material* pm=psb->appendMaterial();
btSoftBody::Material* pm=psb->m_materials[0];
pm->m_kLST = m_cci.m_soft_linStiff;
pm->m_kAST = m_cci.m_soft_angStiff;
pm->m_kVST = m_cci.m_soft_volume;
psb->m_cfg.collisions = 0;
if (m_cci.m_soft_collisionflags & CCD_BSB_COL_CL_RS)
{
psb->m_cfg.collisions += btSoftBody::fCollision::CL_RS;
} else
{
psb->m_cfg.collisions += btSoftBody::fCollision::SDF_RS;
}
if (m_cci.m_soft_collisionflags & CCD_BSB_COL_CL_SS)
{
psb->m_cfg.collisions += btSoftBody::fCollision::CL_SS;
} else
{
psb->m_cfg.collisions += btSoftBody::fCollision::VF_SS;
}
psb->m_cfg.kSRHR_CL = m_cci.m_soft_kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */
psb->m_cfg.kSKHR_CL = m_cci.m_soft_kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */
psb->m_cfg.kSSHR_CL = m_cci.m_soft_kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */
psb->m_cfg.kSR_SPLT_CL = m_cci.m_soft_kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
psb->m_cfg.kSK_SPLT_CL = m_cci.m_soft_kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
psb->m_cfg.kSS_SPLT_CL = m_cci.m_soft_kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */
psb->m_cfg.kVCF = m_cci.m_soft_kVCF; /* Velocities correction factor (Baumgarte) */
psb->m_cfg.kDP = m_cci.m_soft_kDP; /* Damping coefficient [0,1] */
psb->m_cfg.kDG = m_cci.m_soft_kDG; /* Drag coefficient [0,+inf] */
psb->m_cfg.kLF = m_cci.m_soft_kLF; /* Lift coefficient [0,+inf] */
psb->m_cfg.kPR = m_cci.m_soft_kPR; /* Pressure coefficient [-inf,+inf] */
psb->m_cfg.kVC = m_cci.m_soft_kVC; /* Volume conversation coefficient [0,+inf] */
psb->m_cfg.kDF = m_cci.m_soft_kDF; /* Dynamic friction coefficient [0,1] */
psb->m_cfg.kMT = m_cci.m_soft_kMT; /* Pose matching coefficient [0,1] */
psb->m_cfg.kCHR = m_cci.m_soft_kCHR; /* Rigid contacts hardness [0,1] */
psb->m_cfg.kKHR = m_cci.m_soft_kKHR; /* Kinetic contacts hardness [0,1] */
psb->m_cfg.kSHR = m_cci.m_soft_kSHR; /* Soft contacts hardness [0,1] */
psb->m_cfg.kAHR = m_cci.m_soft_kAHR; /* Anchors hardness [0,1] */
if (m_cci.m_gamesoftFlag & CCD_BSB_BENDING_CONSTRAINTS)//OB_SB_GOAL)
{
psb->generateBendingConstraints(2,pm);
}
psb->m_cfg.piterations = m_cci.m_soft_piterations;
psb->m_cfg.viterations = m_cci.m_soft_viterations;
psb->m_cfg.diterations = m_cci.m_soft_diterations;
psb->m_cfg.citerations = m_cci.m_soft_citerations;
if (m_cci.m_gamesoftFlag & CCD_BSB_SHAPE_MATCHING)//OB_SB_GOAL)
{
psb->setPose(false,true);//
} else
{
psb->setPose(true,false);
}
psb->randomizeConstraints();
if (m_cci.m_soft_collisionflags & (CCD_BSB_COL_CL_RS+CCD_BSB_COL_CL_SS))
{
psb->generateClusters(m_cci.m_soft_numclusteriterations);
}
// psb->activate();
// psb->setActivationState(1);
// psb->setDeactivationTime(1.f);
//psb->m_materials[0]->m_kLST = 0.1+(i/(btScalar)(n-1))*0.9;
psb->setTotalMass(m_cci.m_mass);
psb->setCollisionFlags(0);
///create a mapping between graphics mesh vertices and soft body vertices
{
RAS_MeshObject* rasMesh= GetShapeInfo()->GetMesh();
if (rasMesh && !m_softbodyMappingDone)
{
//printf("apply\n");
RAS_MeshSlot::iterator it;
RAS_MeshMaterial *mmat;
RAS_MeshSlot *slot;
size_t i;
//for each material
for (int m=0;m<rasMesh->NumMaterials();m++)
{
// The vertex cache can only be updated for this deformer:
// Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
// share the same mesh (=the same cache). As the rendering is done per polymaterial
// cycling through the objects, the entire mesh cache cannot be updated in one shot.
mmat = rasMesh->GetMeshMaterial(m);
slot = mmat->m_baseslot;
for(slot->begin(it); !slot->end(it); slot->next(it))
{
int index = 0;
for(i=it.startvertex; i<it.endvertex; i++,index++)
{
RAS_TexVert* vertex = &it.vertex[i];
//search closest index, and store it in vertex
vertex->setSoftBodyIndex(0);
btScalar maxDistSqr = 1e30;
btSoftBody::tNodeArray& nodes(psb->m_nodes);
btVector3 xyz = btVector3(vertex->getXYZ()[0],vertex->getXYZ()[1],vertex->getXYZ()[2]);
for (int n=0;n<nodes.size();n++)
{
btScalar distSqr = (nodes[n].m_x - xyz).length2();
if (distSqr<maxDistSqr)
{
maxDistSqr = distSqr;
vertex->setSoftBodyIndex(n);
}
}
}
}
}
}
}
m_softbodyMappingDone = true;
// m_object->setCollisionShape(rbci.m_collisionShape);
btTransform startTrans;
if (rbci.m_motionState)
{
rbci.m_motionState->getWorldTransform(startTrans);
} else
{
startTrans = rbci.m_startWorldTransform;
}
//startTrans.setIdentity();
//m_object->setWorldTransform(startTrans);
//m_object->setInterpolationWorldTransform(startTrans);
m_MotionState->setWorldPosition(startTrans.getOrigin().getX(),startTrans.getOrigin().getY(),startTrans.getOrigin().getZ());
m_MotionState->setWorldOrientation(0,0,0,1);
if (!m_prototypeTransformInitialized)
{
m_prototypeTransformInitialized = true;
m_softBodyTransformInitialized = true;
GetSoftBody()->transform(startTrans);
}
// btVector3 wp = m_softBody->getWorldTransform().getOrigin();
// MT_Point3 center(wp.getX(),wp.getY(),wp.getZ());
// m_gameobj->NodeSetWorldPosition(center);
} else
{
btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
rbci.m_linearDamping = m_cci.m_linearDamping;
rbci.m_angularDamping = m_cci.m_angularDamping;
rbci.m_friction = m_cci.m_friction;
rbci.m_restitution = m_cci.m_restitution;
m_object = new btRigidBody(rbci);
}
//create a rgid collision object
btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
rbci.m_linearDamping = m_cci.m_linearDamping;
rbci.m_angularDamping = m_cci.m_angularDamping;
rbci.m_friction = m_cci.m_friction;
rbci.m_restitution = m_cci.m_restitution;
m_object = new btRigidBody(rbci);
//
// init the rigidbody properly
@ -580,6 +507,20 @@ bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape)
m_collisionShape= newShape;
m_cci.m_collisionShape= newShape;
if (GetSoftBody()) {
// soft body must be recreated
m_cci.m_physicsEnv->removeCcdPhysicsController(this);
delete m_object;
m_object = NULL;
// force complete reinitialization
m_softbodyMappingDone = false;
m_prototypeTransformInitialized = false;
m_softBodyTransformInitialized = false;
CreateSoftbody();
assert(m_object);
// reinsert the new body
m_cci.m_physicsEnv->addCcdPhysicsController(this);
}
/* Copied from CcdPhysicsEnvironment::addCcdPhysicsController() */

@ -71,6 +71,7 @@ public:
m_meshObject(NULL),
m_unscaledShape(NULL),
m_useGimpact(false),
m_forceReInstance(false),
m_weldingThreshold1(0.f),
m_shapeProxy(NULL)
{
@ -372,6 +373,7 @@ protected:
void GetWorldOrientation(btMatrix3x3& mat);
void CreateRigidbody();
bool CreateSoftbody();
bool Register() {
return (m_registerCount++ == 0) ? true : false;

@ -375,9 +375,7 @@ m_scalingPropagated(false)
//m_dynamicsWorld->getSolverInfo().m_solverMode= SOLVER_USE_WARMSTARTING + SOLVER_USE_2_FRICTION_DIRECTIONS + SOLVER_RANDMIZE_ORDER + SOLVER_USE_FRICTION_WARMSTARTING;
m_debugDrawer = 0;
m_gravity = btVector3(0.f,-10.f,0.f);
m_dynamicsWorld->setGravity(m_gravity);
setGravity(0.f,0.f,-9.81f);
}
void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
@ -884,7 +882,7 @@ void CcdPhysicsEnvironment::setGravity(float x,float y,float z)
{
m_gravity = btVector3(x,y,z);
m_dynamicsWorld->setGravity(m_gravity);
m_dynamicsWorld->getWorldInfo().m_gravity.setValue(x,y,z);
}

@ -34,6 +34,7 @@ SET(INC
../../../intern/string
../../../intern/moto/include
../../../extern/glew/include
../../../intern/guardedalloc
../Expressions
${PYTHON_INC}
)

@ -25,6 +25,12 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "RAS_MeshObject.h"
#include "RAS_IRasterizer.h"
@ -93,15 +99,35 @@ STR_String RAS_MeshObject::s_emptyname = "";
RAS_MeshObject::RAS_MeshObject(Mesh* mesh)
: m_bModified(true),
m_bMeshModified(true),
m_mesh(mesh),
m_bDeformed(false)
m_mesh(mesh)
{
if (m_mesh && m_mesh->key)
{
KeyBlock *kb;
int count=0;
// initialize weight cache for shape objects
// count how many keys in this mesh
for(kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next)
count++;
m_cacheWeightIndex.resize(count,-1);
}
}
RAS_MeshObject::~RAS_MeshObject()
{
vector<RAS_Polygon*>::iterator it;
if (m_mesh && m_mesh->key)
{
KeyBlock *kb;
// remove the weight cache to avoid memory leak
for(kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next) {
if(kb->weights)
MEM_freeN(kb->weights);
kb->weights= NULL;
}
}
for(it=m_Polygons.begin(); it!=m_Polygons.end(); it++)
delete (*it);
@ -430,39 +456,6 @@ void RAS_MeshObject::AddMeshUser(void *clientobj, SG_QList *head, RAS_Deformer*
}
}
void RAS_MeshObject::UpdateBuckets(void* clientobj,
double* oglmatrix,
bool useObjectColor,
const MT_Vector4& rgbavec,
bool visible,
bool culled)
{
list<RAS_MeshMaterial>::iterator it;
for(it = m_materials.begin();it!=m_materials.end();++it) {
RAS_MeshSlot **msp = it->m_slots[clientobj];
if(!msp)
continue;
RAS_MeshSlot *ms = *msp;
ms->m_mesh = this;
ms->m_OpenGLMatrix = oglmatrix;
ms->m_bObjectColor = useObjectColor;
ms->m_RGBAcolor = rgbavec;
ms->m_bVisible = visible;
ms->m_bCulled = culled || !visible;
if (!ms->m_bCulled)
ms->m_bucket->ActivateMesh(ms);
/* split if necessary */
#ifdef USE_SPLIT
ms->Split();
#endif
}
}
void RAS_MeshObject::RemoveFromBuckets(void *clientobj)
{
list<RAS_MeshMaterial>::iterator it;
@ -560,3 +553,64 @@ void RAS_MeshObject::SchedulePolygons(int drawingmode)
}
}
static int get_def_index(Object* ob, const char* vgroup)
{
bDeformGroup *curdef;
int index = 0;
for (curdef = (bDeformGroup*)ob->defbase.first; curdef; curdef=(bDeformGroup*)curdef->next, index++)
if (!strcmp(curdef->name, vgroup))
return index;
return -1;
}
void RAS_MeshObject::CheckWeightCache(Object* obj)
{
KeyBlock *kb;
int kbindex, defindex;
MDeformVert *dvert= NULL;
int totvert, i, j;
float *weights;
if (!m_mesh->key)
return;
for(kbindex=0, kb= (KeyBlock*)m_mesh->key->block.first; kb; kb= (KeyBlock*)kb->next, kbindex++)
{
// first check the cases where the weight must be cleared
if (kb->vgroup[0] == 0 ||
m_mesh->dvert == NULL ||
(defindex = get_def_index(obj, kb->vgroup)) == -1) {
if (kb->weights) {
MEM_freeN(kb->weights);
kb->weights = NULL;
}
m_cacheWeightIndex[kbindex] = -1;
} else if (m_cacheWeightIndex[kbindex] != defindex) {
// a weight array is required but the cache is not matching
if (kb->weights) {
MEM_freeN(kb->weights);
kb->weights = NULL;
}
dvert= m_mesh->dvert;
totvert= m_mesh->totvert;
weights= (float*)MEM_callocN(totvert*sizeof(float), "weights");
for (i=0; i < totvert; i++, dvert++) {
for(j=0; j<dvert->totweight; j++) {
if (dvert->dw[j].def_nr == defindex) {
weights[i]= dvert->dw[j].weight;
break;
}
}
}
kb->weights = weights;
m_cacheWeightIndex[kbindex] = defindex;
}
}
}

@ -70,9 +70,9 @@ private:
struct fronttoback;
protected:
vector<int> m_cacheWeightIndex;
list<RAS_MeshMaterial> m_materials;
Mesh* m_mesh;
bool m_bDeformed;
public:
// for now, meshes need to be in a certain layer (to avoid sorting on lights in realtime)
@ -80,7 +80,8 @@ public:
virtual ~RAS_MeshObject();
bool IsDeformed() { return (m_bDeformed && m_mesh); }
// for shape keys,
void CheckWeightCache(struct Object* obj);
/* materials */
int NumMaterials();
@ -132,13 +133,6 @@ public:
/* buckets */
virtual void AddMeshUser(void *clientobj, SG_QList *head, RAS_Deformer* deformer);
virtual void UpdateBuckets(
void* clientobj,
double* oglmatrix,
bool useObjectColor,
const MT_Vector4& rgbavec,
bool visible,
bool culled);
void RemoveFromBuckets(void *clientobj);
void EndConversion() {

@ -4,7 +4,7 @@ Import ('env')
sources = env.Glob('*.cpp')
incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna'
incs = '. #intern/guardedalloc #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/gameengine/SceneGraph #source/blender/blenkernel #source/blender/makesdna'
defs = [ 'GLEW_STATIC' ]