BGE: Support mesh modifiers in the game engine.
authorBenoit Bolsee <benoit.bolsee@online.be>
Tue, 21 Apr 2009 11:01:09 +0000 (11:01 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Tue, 21 Apr 2009 11:01:09 +0000 (11:01 +0000)
Realtime modifiers applied on mesh objects will be supported in
the game engine with the following limitations:

- Only real time modifiers are supported (basically all of them!)
- Virtual modifiers resulting from parenting are not supported:
  armature, curve, lattice. You can still use these modifiers
  (armature is really not recommended) but in non parent mode.
  The BGE has it's own parenting capability for armature.
- Modifiers are computed on the host (using blender modifier
  stack).
- Modifiers are statically evaluated: any possible time dependency
  in the modifiers is not supported (don't know enough about
  modifiers to be more specific).
- Modifiers are reevaluated if the underlying mesh is deformed
  due to shape action or armature action. Beware that this is
  very CPU intensive; modifiers should really be used for static
  objects only.
- Physics is still based on the original mesh: if you have a
  mirror modifier, the physic shape will be limited to one half
  of the resulting object. Therefore, the modifiers should
  preferably be used on graphic objects.
- Scripts have no access to the modified mesh.
- Modifiers that are based on objects interaction (boolean,..)
  will not be dependent on the objects position in the GE.
  What you see in the 3D view is what you get in the GE regardless
  on the object position, velocity, etc.

Besides that, the feature is compatible with all the BGE features
that affect meshes: armature action, shape action, relace mesh,
VideoTexture, add object, dupligroup.

Known problems:
- This feature is a bit hacky: the BGE uses the derived mesh draw
  functions to display the object. This drawing method is a
  bit slow and is not 100% compatible with the BGE. There may
  be some problems in multi-texture mode: the multi-texture
  coordinates are not sent to the GPU.
  Texface and GLSL on the other hand should be fully supported.
- Culling is still based on the extend of the original mesh.
  If you have a modifer that extends the size of the mesh,
  the object may disappear while still in the view frustrum.
- Derived mesh is not shared between replicas.
  The derived mesh is allocated and computed for each object
  with modifiers, regardless if they are static replicas.
- Display list are not created on objects with modifiers.

I should be able to fix the above problems before release.
However, the feature is already useful for game development.
Once you are ready to release the game, you can apply the modifiers
to get back display list support and mesh sharing capability.

MSVC, scons, Cmake, makefile updated.

Enjoy
/benoit

38 files changed:
projectfiles_vc9/blender/BPY_python/BPY_python.vcproj
projectfiles_vc9/gameengine/converter/KX_converter.vcproj
projectfiles_vc9/gameengine/rasterizer/RAS_rasterizer.vcproj
projectfiles_vc9/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/intern/DerivedMesh.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_ModifierDeformer.cpp [new file with mode: 0644]
source/gameengine/Converter/BL_ModifierDeformer.h [new file with mode: 0644]
source/gameengine/Converter/BL_ShapeDeformer.cpp
source/gameengine/Converter/BL_ShapeDeformer.h
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.h
source/gameengine/Converter/BL_SkinMeshObject.cpp
source/gameengine/Ketsji/BL_Material.cpp
source/gameengine/Ketsji/BL_Material.h
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_PolygonMaterial.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Rasterizer/CMakeLists.txt
source/gameengine/Rasterizer/Makefile
source/gameengine/Rasterizer/RAS_Deformer.h
source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
source/gameengine/Rasterizer/RAS_MaterialBucket.h
source/gameengine/Rasterizer/RAS_MeshObject.cpp
source/gameengine/Rasterizer/RAS_MeshObject.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/Makefile
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript

index ff5fe62..55ef074 100644 (file)
                                        RelativePath="..\..\..\source\blender\python\api2_2x\Particle.c"\r
                                        >\r
                                </File>\r
-                               <File\r
-                                       RelativePath="..\..\..\source\blender\python\api2_2x\point.c"\r
-                                       >\r
-                               </File>\r
                                <File\r
                                        RelativePath="..\..\..\source\blender\python\api2_2x\quat.c"\r
                                        >\r
                                        RelativePath="..\..\..\source\blender\python\api2_2x\Particle.h"\r
                                        >\r
                                </File>\r
-                               <File\r
-                                       RelativePath="..\..\..\source\blender\python\api2_2x\point.h"\r
-                                       >\r
-                               </File>\r
                                <File\r
                                        RelativePath="..\..\..\source\blender\python\api2_2x\quat.h"\r
                                        >\r
index 53a628e..4f5b344 100644 (file)
                                RelativePath="..\..\..\source\gameengine\Converter\BL_ActionActuator.cpp"\r
                                >\r
                        </File>\r
-                       <File\r
-                               RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureObject.cpp"\r
-                               >\r
-                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\gameengine\Converter\BL_BlenderDataConversion.cpp"\r
                                >\r
                                RelativePath="..\..\..\source\gameengine\Converter\BL_MeshDeformer.cpp"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\gameengine\Converter\BL_ModifierDeformer.cpp"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\gameengine\Converter\BL_ShapeActionActuator.cpp"\r
                                >\r
                                RelativePath="..\..\..\source\gameengine\Converter\BL_ActionActuator.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureObject.cpp"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\gameengine\Converter\BL_ArmatureObject.h"\r
                                >\r
                                RelativePath="..\..\..\source\gameengine\Converter\BL_MeshDeformer.h"\r
                                >\r
                        </File>\r
+                       <File\r
+                               RelativePath="..\..\..\source\gameengine\Converter\BL_ModifierDeformer.h"\r
+                               >\r
+                       </File>\r
                        <File\r
                                RelativePath="..\..\..\source\gameengine\Converter\BL_ShapeActionActuator.h"\r
                                >\r
index 924babf..d3d35ff 100644 (file)
@@ -4,6 +4,7 @@
        Version="9,00"\r
        Name="RAS_rasterizer"\r
        ProjectGUID="{51FB3D48-2467-4BFA-A321-D848252B437E}"\r
+       RootNamespace="RAS_rasterizer"\r
        TargetFrameworkVersion="131072"\r
        >\r
        <Platforms>\r
@@ -42,7 +43,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               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;..\..\..\..\lib\windows\python\include\python2.5"\r
+                               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;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system"\r
+                               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;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"\r
                                StringPooling="true"\r
                                RuntimeLibrary="2"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               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;..\..\..\..\lib\windows\python\include\python2.5"\r
+                               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;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\source\kernel\gen_system"\r
+                               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;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="3"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               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;..\..\..\..\lib\windows\python\include\python2.5"\r
+                               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;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               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;..\..\..\..\lib\windows\python\include\python2.5"\r
+                               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;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\makesdna"\r
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
index 155290e..7714207 100644 (file)
@@ -4,6 +4,7 @@
        Version="9,00"\r
        Name="RAS_openglrasterizer"\r
        ProjectGUID="{AB590CED-F71F-4A17-A89B-18583ECD633D}"\r
+       RootNamespace="RAS_openglrasterizer"\r
        TargetFrameworkVersion="131072"\r
        >\r
        <Platforms>\r
@@ -42,7 +43,7 @@
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               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\Rasterizer;..\..\..\..\source\blender\gpu"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="3"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               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\Rasterizer;..\..\..\..\source\blender\gpu"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               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\Rasterizer;..\..\..\..\source\blender\gpu"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB"\r
                                StringPooling="true"\r
                                RuntimeLibrary="2"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               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\Rasterizer;..\..\..\..\source\blender\gpu"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                Optimization="0"\r
-                               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\Rasterizer;..\..\..\..\source\blender\gpu"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                BasicRuntimeChecks="3"\r
                                RuntimeLibrary="1"\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
                                InlineFunctionExpansion="1"\r
-                               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\Rasterizer;..\..\..\..\source\blender\gpu"\r
+                               AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\source\blender\gpu;..\..\..\..\source\gameengine\Ketsji;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\blenlib"\r
                                PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"\r
                                StringPooling="true"\r
                                RuntimeLibrary="0"\r
index 232001c..a248e20 100644 (file)
                                ProgramDataBaseFileName="..\..\..\..\build\msvc_9\source\gameengine\videotexture\"\r
                                WarningLevel="2"\r
                                Detect64BitPortabilityProblems="false"\r
-                               DebugInformationFormat="0"\r
                                CompileAs="0"\r
                                ShowIncludes="false"\r
                        />\r
index 263b171..7ee8a42 100644 (file)
@@ -444,6 +444,9 @@ DerivedMesh *mesh_create_derived_no_deform(struct Object *ob,
 DerivedMesh *mesh_create_derived_no_deform_render(struct Object *ob,
                                                   float (*vertCos)[3],
                                                   CustomDataMask dataMask);
+/* for gameengine */
+DerivedMesh *mesh_create_derived_no_virtual(struct Object *ob, float (*vertCos)[3],
+                                            CustomDataMask dataMask);
 
 DerivedMesh *editmesh_get_derived_base(void);
 DerivedMesh *editmesh_get_derived_cage(CustomDataMask dataMask);
index d43cbde..eb2975b 100644 (file)
@@ -2111,6 +2111,11 @@ static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *
                DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
 }
 
+/* new value for useDeform -1  (hack for the gameengine):
+ * - apply only the modifier stack of the object, skipping the virtual modifiers,
+ * - don't apply the key
+ * - apply deform modifiers and input vertexco
+ */
 static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
                                 DerivedMesh **deform_r, DerivedMesh **final_r,
                                 int useRenderParams, int useDeform,
@@ -2125,7 +2130,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
        int numVerts = me->totvert;
        int required_mode;
 
-       md = firstmd = modifiers_getVirtualModifierList(ob);
+       md = firstmd = (useDeform<0) ? ob->modifiers.first : modifiers_getVirtualModifierList(ob);
 
        modifiers_clearErrors(ob);
 
@@ -2142,8 +2147,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
        else required_mode = eModifierMode_Realtime;
 
        if(useDeform) {
-               if(do_ob_key(ob)) /* shape key makes deform verts */
+               if(useDeform > 0 && do_ob_key(ob)) /* shape key makes deform verts */
                        deformedVerts = mesh_getVertexCos(me, &numVerts);
+               else if(inputVertexCos)
+                       deformedVerts = inputVertexCos;
                
                /* Apply all leading deforming modifiers */
                for(;md; md = md->next, curr = curr->next) {
@@ -2947,6 +2954,16 @@ DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3],
        return final;
 }
 
+DerivedMesh *mesh_create_derived_no_virtual(Object *ob, float (*vertCos)[3],
+                                            CustomDataMask dataMask)
+{
+       DerivedMesh *final;
+       
+       mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, -1, 0, dataMask, -1);
+
+       return final;
+}
+
 DerivedMesh *mesh_create_derived_no_deform_render(Object *ob,
                                                   float (*vertCos)[3],
                                                   CustomDataMask dataMask)
index 9f21472..b7f74d5 100644 (file)
@@ -90,6 +90,7 @@
 #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"
@@ -341,6 +342,7 @@ BL_Material* ConvertMaterial(
        
        material->IdMode = DEFAULT_BLENDER;
        material->glslmat = (validmat)? glslmat: false;
+       material->materialindex = mface->mat_nr;
 
        // --------------------------------
        if(validmat) {
@@ -747,7 +749,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
        }
 
        // Determine if we need to make a skinned mesh
-       if (mesh->dvert || mesh->key || ((blenderobj->gameflag & OB_SOFT_BODY) != 0)
+       if (mesh->dvert || mesh->key || ((blenderobj->gameflag & OB_SOFT_BODY) != 0) || BL_ModifierDeformer::HasCompatibleDeformer(blenderobj))
        {
                meshobj = new BL_SkinMeshObject(mesh, lightlayer);
                skinMesh = true;
@@ -853,8 +855,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
                                bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol,
                                        lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
 
-                               bl_mat->material_index =  (int)mface->mat_nr;
-
                                visible = ((bl_mat->ras_mode & POLY_VIS)!=0);
                                collider = ((bl_mat->ras_mode & COLLIDER)!=0);
                                twoside = ((bl_mat->mode & TF_TWOSIDE)!=0);
@@ -874,6 +874,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
                                
                                /* then the KX_BlenderMaterial */
                                polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer);
+
                        }
                        else {
                                /* do Texture Face materials */
@@ -956,7 +957,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
                                bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
                                bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
 
-                               polymat = new KX_PolygonMaterial(imastr, ma,
+                               polymat = new KX_PolygonMaterial(imastr, ma, (int)mface->mat_nr,
                                        tile, tilexrep, tileyrep, 
                                        mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol);
        
@@ -1689,8 +1690,15 @@ static KX_GameObject *gameobject_from_blenderobject(
                bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE;
                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);
 
-               if (bHasShapeKey) {
+               if (bHasModifier) {
+                       BL_ModifierDeformer *dcont = new BL_ModifierDeformer((BL_DeformableGameObject *)gameobj,
+                                                                                                                               ob,     (BL_SkinMeshObject *)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);
diff --git a/source/gameengine/Converter/BL_ModifierDeformer.cpp b/source/gameengine/Converter/BL_ModifierDeformer.cpp
new file mode 100644 (file)
index 0000000..6113f88
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+ * $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 "MEM_guardedalloc.h"
+#include "BL_ModifierDeformer.h"
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+#include "RAS_IPolygonMaterial.h"
+#include "BL_SkinMeshObject.h"
+
+//#include "BL_ArmatureController.h"
+#include "DNA_armature_types.h"
+#include "DNA_action_types.h"
+#include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_modifier_types.h"
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "BKE_key.h"
+#include "BKE_ipo.h"
+#include "MT_Point3.h"
+
+extern "C"{
+       #include "BKE_customdata.h"
+       #include "BKE_DerivedMesh.h"
+       #include "BKE_lattice.h"
+       #include "BKE_modifier.h"
+}
+ #include "BKE_utildefines.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#define __NLA_DEFNORMALS
+//#undef __NLA_DEFNORMALS
+
+
+BL_ModifierDeformer::~BL_ModifierDeformer()
+{
+       if (m_dm) {
+               m_dm->needsFree = 1;
+               m_dm->release(m_dm);
+       }
+};
+
+RAS_Deformer *BL_ModifierDeformer::GetReplica(class KX_GameObject* replica)
+{
+       BL_ModifierDeformer *result;
+
+       result = new BL_ModifierDeformer(*this);
+       result->ProcessReplica();
+       return result;
+}
+
+void BL_ModifierDeformer::ProcessReplica()
+{
+       BL_ShapeDeformer::ProcessReplica();
+       m_dm = NULL;
+       m_lastModifierUpdate = -1;
+}
+
+bool BL_ModifierDeformer::HasCompatibleDeformer(Object *ob)
+{
+       if (!ob->modifiers.first)
+               return false;
+       ModifierData* md;
+       for (md = (ModifierData*)ob->modifiers.first; md; md = (ModifierData*)md->next) {
+               if (md->mode & eModifierMode_Realtime)
+                       return true;
+       }
+       return false;
+}
+
+bool BL_ModifierDeformer::Update(void)
+{
+       bool bShapeUpdate = BL_ShapeDeformer::Update();
+
+       if (bShapeUpdate || m_lastModifierUpdate != m_gameobj->GetLastFrame()) {
+               /* execute the modifiers */
+               Object* blendobj = m_gameobj->GetBlendObject();
+               /* hack: the modifiers require that the mesh is attached to the object
+                  It may not be the case here because of replace mesh actuator */
+               Mesh *oldmesh = (Mesh*)blendobj->data;
+               blendobj->data = m_bmesh;
+               /* execute the modifiers */             
+               DerivedMesh *dm = mesh_create_derived_no_virtual(blendobj, m_transverts, CD_MASK_MESH);
+               /* restore object data */
+               blendobj->data = oldmesh;
+               /* free the current derived mesh and replace, (dm should never be NULL) */
+               if (m_dm != NULL) {
+                       m_dm->needsFree = 1;
+                       m_dm->release(m_dm);
+               }
+               m_dm = dm;
+               m_lastModifierUpdate=m_gameobj->GetLastFrame();
+               bShapeUpdate = true;
+       }
+       return bShapeUpdate;
+}
+
+bool BL_ModifierDeformer::Apply(RAS_IPolyMaterial *mat)
+{
+       if (!Update())
+               return false;
+
+       // drawing is based on derived mesh, must set it in the mesh slots
+       int nmat = m_pMeshObject->NumMaterials();
+       for (int imat=0; imat<nmat; imat++) {
+               RAS_MeshMaterial *mmat = m_pMeshObject->GetMeshMaterial(imat);
+               RAS_MeshSlot *slot = *mmat->m_slots[(void*)m_gameobj];
+               if(!slot)
+                       continue;
+               slot->m_pDerivedMesh = m_dm;
+       }
+       return true;
+}
diff --git a/source/gameengine/Converter/BL_ModifierDeformer.h b/source/gameengine/Converter/BL_ModifierDeformer.h
new file mode 100644 (file)
index 0000000..0caaabf
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+ * $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_MODIFIERDEFORMER
+#define BL_MODIFIERDEFORMER
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+#include "BL_ShapeDeformer.h"
+#include "BL_DeformableGameObject.h"
+#include <vector>
+
+struct DerivedMesh;
+struct Object;
+
+class BL_ModifierDeformer : public BL_ShapeDeformer  
+{
+public:
+       static bool HasCompatibleDeformer(Object *ob);
+
+
+       BL_ModifierDeformer(BL_DeformableGameObject *gameobj,
+                                               Object *bmeshobj,
+                                               BL_SkinMeshObject *mesh)
+                                               :       
+                                               BL_ShapeDeformer(gameobj,bmeshobj, mesh),
+                                               m_lastModifierUpdate(-1),
+                                               m_dm(NULL)
+       {
+               m_recalcNormal = false;
+       };
+
+       /* this second constructor is needed for making a mesh deformable on the fly. */
+       BL_ModifierDeformer(BL_DeformableGameObject *gameobj,
+                                               struct Object *bmeshobj_old,
+                                               struct Object *bmeshobj_new,
+                                               class BL_SkinMeshObject *mesh,
+                                               bool release_object,
+                                               BL_ArmatureObject* arma = NULL)
+                                               :
+                                               BL_ShapeDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, false, arma),
+                                               m_lastModifierUpdate(-1),
+                                               m_dm(NULL)
+       {
+       };
+
+       virtual void ProcessReplica();
+       virtual RAS_Deformer *GetReplica(class KX_GameObject* replica);
+       virtual ~BL_ModifierDeformer();
+       virtual bool UseVertexArray()
+       {
+               return false;
+       }
+
+       bool Update (void);
+       bool Apply(RAS_IPolyMaterial *mat);
+       void ForceUpdate()
+       {
+               m_lastModifierUpdate = -1.0;
+       };
+
+protected:
+       double                                   m_lastModifierUpdate;
+       DerivedMesh                             *m_dm;
+
+};
+
+#endif
+
index fc64985..499732c 100644 (file)
@@ -79,6 +79,7 @@ RAS_Deformer *BL_ShapeDeformer::GetReplica(class KX_GameObject* replica)
 
 void BL_ShapeDeformer::ProcessReplica()
 {
+       BL_SkinDeformer::ProcessReplica();
 }
 
 bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma)
@@ -87,7 +88,7 @@ bool BL_ShapeDeformer::LoadShapeDrivers(Object* arma)
 
        m_shapeDrivers.clear();
        // check if this mesh has armature driven shape keys
-       if (m_bmesh->key->ipo) {
+       if (m_bmesh->key && m_bmesh->key->ipo) {
                for(icu= (IpoCurve*)m_bmesh->key->ipo->curve.first; icu; icu= (IpoCurve*)icu->next) {
                        if(icu->driver && 
                                (icu->flag & IPO_MUTE) == 0 &&
@@ -147,7 +148,9 @@ bool BL_ShapeDeformer::Update(void)
                m_pMeshObject->CheckWeightCache(blendobj);
 
                /* we will blend the key directly in mvert array: it is used by armature as the start position */
-               do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0);
+               /* m_bmesh->key can be NULL in case of Modifier deformer */
+               if (m_bmesh->key)
+                       do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)m_bmesh->mvert->co, m_bmesh->key, 0);
 
                // Don't release the weight array as in Blender, it will most likely be reusable on next frame 
                // The weight array are ultimately deleted when the skin mesh is destroyed
@@ -174,7 +177,8 @@ bool BL_ShapeDeformer::Update(void)
                        VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
 
 #ifdef __NLA_DEFNORMALS
-               RecalcNormals();
+               if (m_recalcNormal)
+                       RecalcNormals();
 #endif
                bSkinUpdate = true;
        }
index 90b9f5c..901a1d8 100644 (file)
@@ -58,9 +58,10 @@ public:
                                        struct Object *bmeshobj_new,
                                        class BL_SkinMeshObject *mesh,
                                        bool release_object,
+                                       bool recalc_normal,
                                        BL_ArmatureObject* arma = NULL)
                                        :
-                                               BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, arma),
+                                               BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, recalc_normal, arma),
                                                m_lastShapeUpdate(-1)
        {
        };
index d856376..ae3e1a1 100644 (file)
@@ -65,9 +65,10 @@ BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
                                                        BL_MeshDeformer(gameobj, bmeshobj, mesh),
                                                        m_armobj(arma),
                                                        m_lastArmaUpdate(-1),
-                                                       m_defbase(&bmeshobj->defbase),
+                                                       //m_defbase(&bmeshobj->defbase),
                                                        m_releaseobject(false),
-                                                       m_poseApplied(false)
+                                                       m_poseApplied(false),
+                                                       m_recalcNormal(true)
 {
        Mat4CpyMat4(m_obmat, bmeshobj->obmat);
 };
@@ -78,12 +79,14 @@ BL_SkinDeformer::BL_SkinDeformer(
        struct Object *bmeshobj_new,    // Blender object that owns the original mesh
        class BL_SkinMeshObject *mesh,
        bool release_object,
+       bool recalc_normal,
        BL_ArmatureObject* arma)        :       
                BL_MeshDeformer(gameobj, bmeshobj_old, mesh),
                m_armobj(arma),
                m_lastArmaUpdate(-1),
-               m_defbase(&bmeshobj_old->defbase),
-               m_releaseobject(release_object)
+               //m_defbase(&bmeshobj_old->defbase),
+               m_releaseobject(release_object),
+               m_recalcNormal(recalc_normal)
        {
                // this is needed to ensure correct deformation of mesh:
                // the deformation is done with Blender's armature_deform_verts() function
@@ -118,31 +121,33 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
        RAS_MeshSlot::iterator it;
        RAS_MeshMaterial *mmat;
        RAS_MeshSlot *slot;
-       size_t i;
+       size_t i, nmat, imat;
 
        // 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(mat);
-       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)) {
-               // for each vertex
-               // copy the untransformed data from the original mvert
-               for(i=it.startvertex; i<it.endvertex; i++) {
-                       RAS_TexVert& v = it.vertex[i];
-                       v.SetXYZ(m_transverts[v.getOrigIndex()]);
+       if (!Update())
+               return false;
+
+       // the vertex cache is unique to this deformer, no need to update it
+       // if it wasn't updated! We must update all the materials at once
+       // because we will not get here again for the other material
+       nmat = m_pMeshObject->NumMaterials();
+       for (imat=0; imat<nmat; imat++) {
+               mmat = m_pMeshObject->GetMeshMaterial(imat);
+               if(!mmat->m_slots[(void*)m_gameobj])
+                       continue;
+
+               slot = *mmat->m_slots[(void*)m_gameobj];
+
+               // for each array
+               for(slot->begin(it); !slot->end(it); slot->next(it)) {
+                       // for each vertex
+                       // copy the untransformed data from the original mvert
+                       for(i=it.startvertex; i<it.endvertex; i++) {
+                               RAS_TexVert& v = it.vertex[i];
+                               v.SetXYZ(m_transverts[v.getOrigIndex()]);
+                       }
                }
        }
-
        return true;
 }
 
@@ -191,7 +196,8 @@ bool BL_SkinDeformer::Update(void)
                Mat4CpyMat4(m_objMesh->obmat, obmat);
 
 #ifdef __NLA_DEFNORMALS
-               RecalcNormals();
+               if (m_recalcNormal)
+                       RecalcNormals();
 #endif
 
                /* Update the current frame */
index f878600..c93188b 100644 (file)
@@ -64,6 +64,7 @@ public:
                                        struct Object *bmeshobj_new,
                                        class BL_SkinMeshObject *mesh,
                                        bool release_object,
+                                       bool recalc_normal,
                                        BL_ArmatureObject* arma = NULL);
 
        virtual void ProcessReplica();
@@ -88,10 +89,11 @@ protected:
        BL_ArmatureObject*              m_armobj;       //      Our parent object
        float                                   m_time;
        double                                  m_lastArmaUpdate;
-       ListBase*                               m_defbase;
+       //ListBase*                             m_defbase;
        float                                   m_obmat[4][4];  // the reference matrix for skeleton deform
        bool                                    m_releaseobject;
        bool                                    m_poseApplied;
+       bool                                    m_recalcNormal;
 
 };
 
index eb3f9d0..0a18296 100644 (file)
@@ -87,7 +87,7 @@ void BL_SkinMeshObject::UpdateBuckets(void* clientobj,double* oglmatrix,bool use
                        continue;
 
                RAS_MeshSlot *slot = *it->m_slots[clientobj];
-               slot->m_pDeformer = ((BL_DeformableGameObject*)clientobj)->GetDeformer();
+               slot->SetDeformer(((BL_DeformableGameObject*)clientobj)->GetDeformer());
        }
 
        RAS_MeshObject::UpdateBuckets(clientobj, oglmatrix, useObjectColor, rgbavec, visible, culled);
index 7e3d698..022ed71 100644 (file)
@@ -52,7 +52,7 @@ BL_Material::BL_Material()
        mode = 0;
        material = 0;
        tface = 0;
-       material_index = 0;
+       materialindex = 0;
        amb=0.5f;
        num_enabled = 0;
        num_users = 1;
index 0eaa234..a0ce37a 100644 (file)
@@ -54,6 +54,7 @@ public:
        int tile,tilexrep[MAXTEX],tileyrep[MAXTEX];
        STR_String matname;
        STR_String mtexname[MAXTEX];
+       int materialindex;
 
        float matcolor[4];
        float speccolor[3];
@@ -68,8 +69,6 @@ public:
        int      mode;
        int num_enabled;
        
-       int material_index;
-
        BL_Mapping      mapping[MAXTEX];
        STR_String      imageId[MAXTEX];
 
index 2edfe4b..7378113 100644 (file)
@@ -53,6 +53,7 @@ KX_BlenderMaterial::KX_BlenderMaterial(
        RAS_IPolyMaterial(
                STR_String( data->texname[0] ),
                STR_String( data->matname ), // needed for physics!
+               data->materialindex,
                data->tile,
                data->tilexrep[0],
                data->tileyrep[0],
@@ -120,6 +121,27 @@ unsigned int* KX_BlenderMaterial::GetMCol(void) const
        return mMaterial->rgb;
 }
 
+void KX_BlenderMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
+{
+       if (mMaterial) {
+               *rgba++ = (unsigned char) (mMaterial->matcolor[0]*255.0);
+               *rgba++ = (unsigned char) (mMaterial->matcolor[1]*255.0);
+               *rgba++ = (unsigned char) (mMaterial->matcolor[2]*255.0);
+               *rgba++ = (unsigned char) (mMaterial->matcolor[3]*255.0);
+       } else
+               RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
+}
+
+Material *KX_BlenderMaterial::GetBlenderMaterial() const
+{
+       return mMaterial->material;
+}
+
+Scene* KX_BlenderMaterial::GetBlenderScene() const
+{
+       return mScene->GetBlenderScene();
+}
+
 void KX_BlenderMaterial::OnConstruction()
 {
        if (mConstructed)
@@ -863,7 +885,7 @@ void KX_BlenderMaterial::SetBlenderGLSLShader(void)
 
 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")
 {
-       return PyInt_FromLong( mMaterial->material_index );
+       return PyInt_FromLong( GetMaterialIndex() );
 }
 
 KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getTexture, "getTexture( index )" )
index 57cdde3..eeb919a 100644 (file)
@@ -73,7 +73,6 @@ public:
        Image * getImage (unsigned int idx) { 
                return (idx < MAXTEX && mMaterial) ? mMaterial->img[idx] : NULL; 
        }
-
        // for ipos
        void UpdateIPO(
                MT_Vector4 rgba, MT_Vector3 specrgb,
@@ -117,6 +116,9 @@ private:
        void ActivateTexGen( RAS_IRasterizer *ras ) const;
 
        bool UsesLighting(RAS_IRasterizer *rasty) const;
+       void GetMaterialRGBAColor(unsigned char *rgba) const;
+       Material* GetBlenderMaterial() const;
+       Scene* GetBlenderScene() const;
 
        // message centers
        void    setTexData( bool enable,RAS_IRasterizer *ras);
index 2d5a5f9..a8105c1 100644 (file)
@@ -53,6 +53,7 @@
 
 KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname,
                                                                                           Material *material,
+                                                                                          int materialindex,
                                                                                           int tile,
                                                                                           int tilexrep,
                                                                                           int tileyrep,
@@ -67,6 +68,7 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname,
                : PyObjectPlus(T),
                  RAS_IPolyMaterial(texname,
                                                        STR_String(material?material->id.name:""),
+                                                       materialindex,
                                                        tile,
                                                        tilexrep,
                                                        tileyrep,
@@ -167,6 +169,18 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c
                rasty->SetPolygonOffset(-m_material->zoffs, 0.0);
 }
 
+void KX_PolygonMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
+{
+       if (m_material) {
+               *rgba++ = (unsigned char) (m_material->r*255.0);
+               *rgba++ = (unsigned char) (m_material->g*255.0);
+               *rgba++ = (unsigned char) (m_material->b*255.0);
+               *rgba++ = (unsigned char) (m_material->alpha*255.0);
+       } else
+               RAS_IPolyMaterial::GetMaterialRGBAColor(rgba);
+}
+
+
 //----------------------------------------------------------------------------
 //Python
 
index e581605..b6f5f37 100644 (file)
@@ -53,7 +53,6 @@ private:
        MTFace*                 m_tface;
        unsigned int*   m_mcol;
        Material*               m_material;
-       
        PyObject*               m_pymaterial;
 
        mutable int             m_pass;
@@ -61,6 +60,7 @@ public:
        
        KX_PolygonMaterial(const STR_String &texname,
                Material* ma,
+               int materialindex,
                int tile,
                int tilexrep,
                int tileyrep,
@@ -107,8 +107,8 @@ public:
        {
                return m_mcol;
        }
-       
-       
+       virtual void GetMaterialRGBAColor(unsigned char *rgba) const;
+
        KX_PYMETHOD_DOC(KX_PolygonMaterial, updateTexture);
        KX_PYMETHOD_DOC(KX_PolygonMaterial, setTexture);
        KX_PYMETHOD_DOC(KX_PolygonMaterial, activate);
index f91c467..f57a38d 100644 (file)
@@ -80,6 +80,7 @@
 #include "KX_BlenderSceneConverter.h"
 #include "KX_MotionState.h"
 
+#include "BL_ModifierDeformer.h"
 #include "BL_ShapeDeformer.h"
 #include "BL_DeformableGameObject.h"
 
@@ -1038,6 +1039,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
                        Object* oldblendobj = static_cast<struct Object*>(m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName()));
                        Mesh* blendmesh = mesh->GetMesh();
 
+                       bool bHasModifier = BL_ModifierDeformer::HasCompatibleDeformer(blendobj);
                        bool bHasShapeKey = blendmesh->key != NULL && blendmesh->key->type==KEY_RELATIVE;
                        bool bHasDvert = blendmesh->dvert != NULL;
                        bool bHasArmature = 
@@ -1053,10 +1055,37 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
                        
                        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= false;
+                               bHasShapeKey= bHasDvert= bHasArmature=bHasModifier= false;
                        }
                        
-                       if (bHasShapeKey)
+                       if (bHasModifier)
+                       {
+                               BL_ModifierDeformer* modifierDeformer;
+                               if (bHasShapeKey || bHasArmature)
+                               {
+                                       modifierDeformer = new BL_ModifierDeformer(
+                                               newobj,
+                                               oldblendobj, blendobj,
+                                               static_cast<BL_SkinMeshObject*>(mesh),
+                                               true,
+                                               static_cast<BL_ArmatureObject*>( parentobj )
+                                       );
+                                       releaseParent= false;
+                                       modifierDeformer->LoadShapeDrivers(blendobj->parent);
+                               }
+                               else
+                               {
+                                       modifierDeformer = new BL_ModifierDeformer(
+                                               newobj,
+                                               oldblendobj, blendobj,
+                                               static_cast<BL_SkinMeshObject*>(mesh),
+                                               false,
+                                               NULL
+                                       );
+                               }
+                               newobj->SetDeformer(modifierDeformer);
+                       } 
+                       else    if (bHasShapeKey)
                        {
                                BL_ShapeDeformer* shapeDeformer;
                                if (bHasArmature) 
@@ -1066,6 +1095,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
                                                oldblendobj, blendobj,
                                                static_cast<BL_SkinMeshObject*>(mesh),
                                                true,
+                                               true,
                                                static_cast<BL_ArmatureObject*>( parentobj )
                                        );
                                        releaseParent= false;
@@ -1078,6 +1108,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
                                                oldblendobj, blendobj,
                                                static_cast<BL_SkinMeshObject*>(mesh),
                                                false,
+                                               true,
                                                NULL
                                        );
                                }
@@ -1090,6 +1121,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
                                        oldblendobj, blendobj,
                                        static_cast<BL_SkinMeshObject*>(mesh),
                                        true,
+                                       true,
                                        static_cast<BL_ArmatureObject*>( parentobj )
                                );
                                releaseParent= false;
index 6d53ee5..69a167e 100644 (file)
@@ -29,6 +29,7 @@ FILE(GLOB SRC *.cpp)
 SET(INC
   .
   ../../../source/kernel/gen_system
+  ../../../source/blender/makesdna
   ../../../intern/string
   ../../../intern/moto/include
   ../../../extern/glew/include
index 917f70c..fa6cf94 100644 (file)
@@ -40,6 +40,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS)
 CPPFLAGS += -I$(NAN_STRING)/include    
 CPPFLAGS += -I$(NAN_MOTO)/include
 CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../../blender/makesdna
 CPPFLAGS += -I../BlenderRoutines
 CPPFLAGS += -I../Expressions
 
index 3332ac4..dc5a49a 100644 (file)
@@ -49,6 +49,10 @@ public:
        {
                return false;
        }
+       virtual bool UseVertexArray()
+       {
+               return true;
+       }
 protected:
        class RAS_MeshObject    *m_pMesh;
 };
index cd88112..e8f4513 100644 (file)
 #include "RAS_IPolygonMaterial.h"
 #include "RAS_IRasterizer.h"
 
+#include "DNA_image_types.h"
+#include "DNA_meshdata_types.h"
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
 RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
                                                                         const STR_String& matname,
+                                                                        int materialindex,
                                                                         int tile,
                                                                         int tilexrep,
                                                                         int tileyrep,
@@ -45,6 +49,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
                                                                         int lightlayer)
                : m_texturename(texname),
                m_materialname(matname),
+               m_materialindex(materialindex),
                m_tile(tile),
                m_tilexrep(tilexrep),
                m_tileyrep(tileyrep),
@@ -95,6 +100,15 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
        }
 }
 
+
+void RAS_IPolyMaterial::GetMaterialRGBAColor(unsigned char *rgba) const
+{
+       *rgba++ = 0xFF;
+       *rgba++ = 0xFF;
+       *rgba++ = 0xFF;
+       *rgba++ = 0xFF;
+}
+
 bool RAS_IPolyMaterial::Less(const RAS_IPolyMaterial& rhs) const
 {
        if (Equals(rhs))
@@ -143,6 +157,22 @@ const STR_String& RAS_IPolyMaterial::GetTextureName() const
        return m_texturename;
 }
 
+int RAS_IPolyMaterial::GetMaterialIndex() const
+{
+       return m_materialindex;
+}
+
+Material *RAS_IPolyMaterial::GetBlenderMaterial() const
+{
+       return NULL;
+}
+
+Scene* RAS_IPolyMaterial::GetBlenderScene() const
+{
+       return NULL;
+}
+
+
 unsigned int   RAS_IPolyMaterial::GetFlag() const
 {
        return m_flag;
index e5b2407..dcd8b53 100644 (file)
@@ -39,6 +39,9 @@
 #include "STR_HashedString.h"
 
 class RAS_IRasterizer;
+struct MTFace;
+struct Material;
+struct Scene;
 
 enum MaterialProps
 {
@@ -71,6 +74,7 @@ protected:
        bool                                    m_alpha;
        bool                                    m_zsort;
        int                                             m_lightlayer;
+       int                                             m_materialindex;
        
        unsigned int                    m_polymatid;
        static unsigned int             m_newpolymatid;
@@ -98,6 +102,7 @@ public:
 
        RAS_IPolyMaterial(const STR_String& texname,
                                          const STR_String& matname,
+                                         int materialindex,
                                          int tile,
                                          int tilexrep,
                                          int tileyrep,
@@ -139,10 +144,14 @@ public:
        dword                           GetMaterialNameHash() const;
        const STR_String&       GetTextureName() const;
        unsigned int            GetFlag() const;
+       int                                     GetMaterialIndex() const;
 
+       virtual Material*   GetBlenderMaterial() const;
+       virtual Scene*          GetBlenderScene() const;
+       virtual void            GetMaterialRGBAColor(unsigned char *rgba) const;
        virtual bool            UsesLighting(RAS_IRasterizer *rasty) const;
        virtual bool            UsesObjectColor() const;
-       
+
        /*
         * PreCalculate texture gen
         */
index 6beab28..d63e9c9 100644 (file)
@@ -56,6 +56,7 @@ RAS_MeshSlot::RAS_MeshSlot()
        m_DisplayList = NULL;
        m_bDisplayList = true;
        m_joinSlot = NULL;
+       m_pDerivedMesh = NULL;
 }
 
 RAS_MeshSlot::~RAS_MeshSlot()
@@ -87,6 +88,7 @@ RAS_MeshSlot::RAS_MeshSlot(const RAS_MeshSlot& slot)
 
        m_clientObj = NULL;
        m_pDeformer = NULL;
+       m_pDerivedMesh = NULL;
        m_OpenGLMatrix = NULL;
        m_mesh = slot.m_mesh;
        m_bucket = slot.m_bucket;
@@ -279,6 +281,43 @@ void RAS_MeshSlot::AddPolygonVertex(int offset)
                m_endindex++;
 }
 
+void RAS_MeshSlot::SetDeformer(RAS_Deformer* deformer)
+{
+       if (deformer && m_pDeformer != deformer) {
+               // we create local copy of RAS_DisplayArray when we have a deformer:
+               // this way we can avoid conflict between the vertex cache of duplicates
+               RAS_DisplayArrayList::iterator it;
+               for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
+                       if (deformer->UseVertexArray()) {
+                               // the deformer makes use of vertex array, make sure we have our local copy
+                               if ((*it)->m_users > 1) {
+                                       // only need to copy if there are other users
+                                       // note that this is the usual case as vertex arrays are held by the material base slot
+                                       RAS_DisplayArray *newarray = new RAS_DisplayArray(*(*it));
+                                       newarray->m_users = 1;
+                                       (*it)->m_users--;
+                                       *it = newarray;
+                               }
+                       } else {
+                               // the deformer is not using vertex array (Modifier), release them
+                               (*it)->m_users--;
+                               if((*it)->m_users == 0)
+                                       delete *it;
+                       }
+               }
+               if (!deformer->UseVertexArray()) {
+                       m_displayArrays.clear();
+                       m_startarray = 0;
+                       m_startvertex = 0;
+                       m_startindex = 0;
+                       m_endarray = 0;
+                       m_endvertex = 0;
+                       m_endindex = 0;
+               }
+       }
+       m_pDeformer = deformer;
+}
+
 bool RAS_MeshSlot::Equals(RAS_MeshSlot *target)
 {
        if(!m_OpenGLMatrix || !target->m_OpenGLMatrix)
index f5c8cd3..b07f86b 100644 (file)
@@ -69,6 +69,7 @@ class RAS_DisplayArray;
 class RAS_MeshSlot;
 class RAS_MeshMaterial;
 class RAS_MaterialBucket;
+struct DerivedMesh;
 
 /* An array with data used for OpenGL drawing */
 
@@ -110,6 +111,7 @@ public:
        RAS_MeshObject*                 m_mesh;
        void*                                   m_clientObj;
        RAS_Deformer*                   m_pDeformer;
+       DerivedMesh*                    m_pDerivedMesh;
        double*                                 m_OpenGLMatrix;
        // visibility
        bool                                    m_bVisible;
@@ -148,6 +150,7 @@ public:
        /* used during construction */
        void SetDisplayArray(int numverts);
        RAS_DisplayArray *CurrentDisplayArray();
+       void SetDeformer(RAS_Deformer* deformer);
 
        void AddPolygon(int numverts);
        int AddVertex(const RAS_TexVert& tv);
index 162f9a8..5625b17 100644 (file)
@@ -215,6 +215,19 @@ RAS_MeshMaterial *RAS_MeshObject::GetMeshMaterial(RAS_IPolyMaterial *mat)
        return NULL;
 }
 
+int RAS_MeshObject::GetMaterialId(RAS_IPolyMaterial *mat)
+{
+       list<RAS_MeshMaterial>::iterator mit;
+       int imat;
+
+       /* find a mesh material */
+       for(imat=0, mit = m_materials.begin(); mit != m_materials.end(); mit++, imat++)
+               if(mit->m_bucket->GetPolyMaterial() == mat)
+                       return imat;
+
+       return -1;
+}
+
 RAS_Polygon* RAS_MeshObject::AddPolygon(RAS_MaterialBucket *bucket, int numverts)
 {
        RAS_MeshMaterial *mmat;
index 404b7f1..cc50f9c 100644 (file)
@@ -89,6 +89,7 @@ public:
 
        RAS_MeshMaterial*       GetMeshMaterial(unsigned int matid);
        RAS_MeshMaterial*       GetMeshMaterial(RAS_IPolyMaterial *mat);
+       int                                     GetMaterialId(RAS_IPolyMaterial *mat);
 
        list<RAS_MeshMaterial>::iterator GetFirstMaterial();
        list<RAS_MeshMaterial>::iterator GetLastMaterial();
index e4403ac..322d7b7 100644 (file)
@@ -31,8 +31,12 @@ SET(INC
   ../../../../intern/string
   ../../../../intern/moto/include
   ../../../../source/gameengine/Rasterizer
+  ../../../../source/gameengine/Ketsji
   ../../../../extern/glew/include
   ../../../../source/blender/gpu
+  ../../../../source/blender/makesdna
+  ../../../../source/blender/blenkernel
+  ../../../../source/blender/blenlib
 )
 
 BLENDERLIB(bf_oglrasterizer "${SRC}" "${INC}")
index aee485a..b55f649 100644 (file)
@@ -42,8 +42,13 @@ CPPFLAGS += -I$(NAN_STRING)/include
 CPPFLAGS += -I$(NAN_MOTO)/include
 CPPFLAGS += -I../../../kernel/gen_system
 CPPFLAGS += -I../../../blender/gpu
+CPPFLAGS += -I../../../blender/makesdna
+CPPFLAGS += -I../../../blender/blenlib
+CPPFLAGS += -I../../../blender/blenkernel
 CPPFLAGS += -I../../BlenderRoutines
+CPPFLAGS += -I../../Ketsji
 CPPFLAGS += -I..
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
 
 ifeq ($(OS),darwin)
        CPPFLAGS += -fpascal-strings
index 65aadd6..06c61fb 100644 (file)
@@ -116,10 +116,13 @@ RAS_ListRasterizer::~RAS_ListRasterizer()
 
 void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list)
 {
-       RAS_Lists::iterator it = mLists.begin();
-       while(it != mLists.end()) {
+       if (list->m_flag & LIST_STANDALONE)
+               return ;
+       
+       RAS_ArrayLists::iterator it = mArrayLists.begin();
+       while(it != mArrayLists.end()) {
                if (it->second == list) {
-                       mLists.erase(it);
+                       mArrayLists.erase(it);
                        break;
                }
                it++;
@@ -136,12 +139,19 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms)
        */
        RAS_ListSlot* localSlot = (RAS_ListSlot*)ms.m_DisplayList;
        if(!localSlot) {
-               RAS_Lists::iterator it = mLists.find(ms.m_displayArrays);
-               if(it == mLists.end()) {
+               if (ms.m_pDerivedMesh) {
+                       // that means that we draw based on derived mesh, a display list is possible
+                       // but it's unique to this mesh slot
                        localSlot = new RAS_ListSlot(this);
-                       mLists.insert(std::pair<RAS_DisplayArrayList, RAS_ListSlot*>(ms.m_displayArrays, localSlot));
+                       localSlot->m_flag |= LIST_STANDALONE;
                } else {
-                       localSlot = static_cast<RAS_ListSlot*>(it->second->AddRef());
+                       RAS_ArrayLists::iterator it = mArrayLists.find(ms.m_displayArrays);
+                       if(it == mArrayLists.end()) {
+                               localSlot = new RAS_ListSlot(this);
+                               mArrayLists.insert(std::pair<RAS_DisplayArrayList, RAS_ListSlot*>(ms.m_displayArrays, localSlot));
+                       } else {
+                               localSlot = static_cast<RAS_ListSlot*>(it->second->AddRef());
+                       }
                }
        }
        MT_assert(localSlot);
@@ -150,12 +160,12 @@ RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms)
 
 void RAS_ListRasterizer::ReleaseAlloc()
 {
-       RAS_Lists::iterator it = mLists.begin();
-       while(it != mLists.end()) {
+       RAS_ArrayLists::iterator it = mArrayLists.begin();
+       while(it != mArrayLists.end()) {
                delete it->second;
                it++;
        }
-       mLists.clear();
+       mArrayLists.clear();
 }
 
 void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
@@ -172,8 +182,8 @@ void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
                        return;
                }
        }
-       
-       if (mUseVertexArrays)
+       // derived mesh cannot use vertex array
+       if (mUseVertexArrays && !ms.m_pDerivedMesh)
                RAS_VAOpenGLRasterizer::IndexPrimitives(ms);
        else
                RAS_OpenGLRasterizer::IndexPrimitives(ms);
@@ -204,7 +214,7 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
        // workaround: note how we do not use vertex arrays for making display
        // lists, since glVertexAttribPointerARB doesn't seem to work correct
        // in display lists on ATI? either a bug in the driver or in Blender ..
-       if (mUseVertexArrays && !localSlot)
+       if (mUseVertexArrays && !localSlot && !ms.m_pDerivedMesh)
                RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms);
        else
                RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms);
index 653bb43..1921189 100644 (file)
@@ -9,6 +9,7 @@
 class RAS_ListRasterizer;
 class RAS_ListSlot : public KX_ListSlot
 {
+       friend class RAS_ListRasterizer;
        unsigned int m_list;
        unsigned int m_flag;
        RAS_ListRasterizer* m_rasty;
@@ -32,15 +33,16 @@ enum RAS_ListSlotFlags      {
        LIST_NOCREATE   =8,
        LIST_BEGIN              =16,
        LIST_END                =32,
-       LIST_REGEN              =64
+       LIST_REGEN              =64,
+       LIST_STANDALONE =128,
 };
 
-typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_Lists;
+typedef std::map<RAS_DisplayArrayList, RAS_ListSlot*> RAS_ArrayLists;
 
 class RAS_ListRasterizer : public RAS_VAOpenGLRasterizer
 {
        bool mUseVertexArrays;
-       RAS_Lists mLists;
+       RAS_ArrayLists mArrayLists;
 
        RAS_ListSlot* FindOrAdd(class RAS_MeshSlot& ms);
        void ReleaseAlloc();
index 1a9a289..50f56db 100644 (file)
 
 #include "RAS_Rect.h"
 #include "RAS_TexVert.h"
+#include "RAS_MeshObject.h"
 #include "MT_CmMatrix4x4.h"
 #include "RAS_IRenderTools.h" // rendering text
 
 #include "GPU_draw.h"
 #include "GPU_material.h"
+#include "GPU_extensions.h"
+
+#include "DNA_image_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_material_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_DerivedMesh.h"
 
 /**
  *  32x32 bit masks for vinterlace stereo mode
@@ -703,6 +712,51 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
        IndexPrimitivesInternal(ms, true);
 }
 
+static bool current_wireframe;
+static RAS_MaterialBucket *current_bucket;
+static RAS_IPolyMaterial *current_polymat;
+static RAS_MeshSlot *current_ms;
+static RAS_MeshObject *current_mesh;
+static int current_blmat_nr;
+static GPUVertexAttribs current_gpu_attribs;
+static int CheckMaterialDM(int matnr, void *attribs)
+{
+       // only draw the current material
+       if (matnr != current_blmat_nr)
+               return 0;
+       GPUVertexAttribs *gattribs = (GPUVertexAttribs *)attribs;
+       if (gattribs)
+               memcpy(gattribs, &current_gpu_attribs, sizeof(GPUVertexAttribs));
+       return 1;
+}
+static int CheckTexfaceDM(void *mcol, int index)
+{
+
+       // index is the original face index, retrieve the polygon
+       RAS_Polygon* polygon = (index >= 0 && index < current_mesh->NumPolygons()) ?
+               current_mesh->GetPolygon(index) : NULL;
+       if (polygon && polygon->GetMaterial() == current_bucket) {
+               // must handle color.
+               if (current_wireframe)
+                       return 2;
+               if (current_ms->m_bObjectColor) {
+                       MT_Vector4& rgba = current_ms->m_RGBAcolor;
+                       glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]);
+                       // don't use mcol
+                       return 2;
+               }
+               if (!mcol) {
+                       // we have to set the color from the material
+                       unsigned char rgba[4];
+                       current_polymat->GetMaterialRGBAColor(rgba);
+                       glColor4ubv((const GLubyte *)rgba);
+                       return 2;
+               }
+               return 1;
+       }
+       return 0;
+}
+
 void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
 { 
        bool obcolor = ms.m_bObjectColor;
@@ -710,6 +764,31 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi)
        MT_Vector4& rgba = ms.m_RGBAcolor;
        RAS_MeshSlot::iterator it;
 
+       if (ms.m_pDerivedMesh) {
+               // mesh data is in derived mesh, 
+               current_bucket = ms.m_bucket;
+               current_polymat = current_bucket->GetPolyMaterial();
+               current_ms = &ms;
+               current_mesh = ms.m_mesh;
+               current_wireframe = wireframe;
+               MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL);
+               if (current_polymat->GetFlag() & RAS_BLENDERGLSL) {
+                       // GetMaterialIndex return the original mface material index, 
+                       // increment by 1 to match what derived mesh is doing
+                       current_blmat_nr = current_polymat->GetMaterialIndex()+1;
+                       // For GLSL we need to retrieve the GPU material attribute
+                       Material* blmat = current_polymat->GetBlenderMaterial();
+                       Scene* blscene = current_polymat->GetBlenderScene();
+                       if (!wireframe && blscene && blmat)
+                               GPU_material_vertex_attributes(GPU_material_from_blender(blscene, blmat), &current_gpu_attribs);
+                       else
+                               memset(&current_gpu_attribs, 0, sizeof(current_gpu_attribs));
+                       ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM);
+               } else {
+                       ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol);
+               }
+               return;
+       }
        // iterate over display arrays, each containing an index + vertex array
        for(ms.begin(it); !ms.end(it); ms.next(it)) {
                RAS_TexVert *vertex;
index 2cb3b52..00f0f27 100644 (file)
@@ -110,6 +110,12 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms)
        RAS_MeshSlot::iterator it;
        GLenum drawmode;
 
+       if (ms.m_pDerivedMesh) {
+               // cannot be handled here, pass to RAS_OpenGLRasterizer
+               RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false);
+               return;
+       }
+
        if(!wireframe)
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
@@ -167,6 +173,12 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms)
        RAS_MeshSlot::iterator it;
        GLenum drawmode;
 
+       if (ms.m_pDerivedMesh) {
+               // cannot be handled here, pass to RAS_OpenGLRasterizer
+               RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true);
+               return;
+       }
+
        if(!wireframe)
                EnableTextures(true);
 
index 6731da9..3146302 100644 (file)
@@ -5,6 +5,8 @@ sources = env.Glob('*.cpp')
 
 incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/gameengine/BlenderRoutines '
 incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC']
+incs += ' #source/blender/gameengine/Ketsji #source/blender/makesdna #source/blender/blenkernel'
+incs += ' #intern/guardedalloc #source/blender/blenlib'
 
 cxxflags = []
 if env['OURPLATFORM']=='win32-vc':