forked from bartvdbraak/blender
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:
parent
6c55047b40
commit
5b722b1e87
@ -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
|
||||
|
120
source/gameengine/Converter/KX_SoftBodyDeformer.cpp
Normal file
120
source/gameengine/Converter/KX_SoftBodyDeformer.cpp
Normal file
@ -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
|
102
source/gameengine/Converter/KX_SoftBodyDeformer.h
Normal file
102
source/gameengine/Converter/KX_SoftBodyDeformer.h
Normal file
@ -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' ]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user