2002-10-12 11:37:38 +00:00
/**
* $ Id $
*
2008-04-16 22:40:48 +00:00
* * * * * * BEGIN GPL LICENSE BLOCK * * * * *
2002-10-12 11:37:38 +00:00
*
* 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
2008-04-16 22:40:48 +00:00
* of the License , or ( at your option ) any later version .
2002-10-12 11:37:38 +00:00
*
* 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 .
*
2008-04-16 22:40:48 +00:00
* * * * * * END GPL LICENSE BLOCK * * * * *
2002-10-12 11:37:38 +00:00
* Convert blender data to ketsji
*/
2002-11-25 15:29:57 +00:00
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
2002-10-12 11:37:38 +00:00
# ifdef WIN32
# pragma warning (disable : 4786)
# endif
2004-05-21 09:21:15 +00:00
# include <math.h>
2002-10-12 11:37:38 +00:00
# include "BL_BlenderDataConversion.h"
# include "KX_BlenderGL.h"
# include "KX_BlenderScalarInterpolator.h"
# include "RAS_IPolygonMaterial.h"
2005-01-16 06:02:06 +00:00
# include "KX_PolygonMaterial.h"
2002-10-12 11:37:38 +00:00
// Expressions
# include "ListValue.h"
# include "IntValue.h"
// Collision & Fuzzics LTD
# include "PHY_Pro.h"
# include "KX_Scene.h"
# include "KX_GameObject.h"
# include "RAS_FramingManager.h"
# include "RAS_MeshObject.h"
# include "KX_ConvertActuators.h"
# include "KX_ConvertControllers.h"
# include "KX_ConvertSensors.h"
# include "SCA_LogicManager.h"
# include "SCA_EventManager.h"
# include "SCA_TimeEventManager.h"
# include "KX_Light.h"
# include "KX_Camera.h"
# include "KX_EmptyObject.h"
# include "MT_Point3.h"
# include "MT_Transform.h"
2004-03-22 22:02:18 +00:00
# include "MT_MinMax.h"
2002-10-12 11:37:38 +00:00
# include "SCA_IInputDevice.h"
# include "RAS_TexMatrix.h"
# include "RAS_ICanvas.h"
# include "RAS_MaterialBucket.h"
//#include "KX_BlenderPolyMaterial.h"
# include "RAS_Polygon.h"
# include "RAS_TexVert.h"
# include "RAS_BucketManager.h"
# include "RAS_IRenderTools.h"
2006-01-06 03:46:54 +00:00
# include "BL_Material.h"
# include "KX_BlenderMaterial.h"
# include "BL_Texture.h"
2002-10-12 11:37:38 +00:00
# include "DNA_action_types.h"
# include "BKE_main.h"
2004-12-29 01:31:17 +00:00
# include "BKE_global.h"
2008-05-24 08:34:04 +00:00
# include "BKE_object.h"
2008-06-14 20:42:15 +00:00
# include "BKE_scene.h"
2002-10-12 11:37:38 +00:00
# include "BL_SkinMeshObject.h"
BGE: Support mesh modifiers in the game engine.
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
2009-04-21 11:01:09 +00:00
# include "BL_ModifierDeformer.h"
2008-06-18 06:46:49 +00:00
# include "BL_ShapeDeformer.h"
2002-10-12 11:37:38 +00:00
# include "BL_SkinDeformer.h"
# include "BL_MeshDeformer.h"
//#include "BL_ArmatureController.h"
# include "BlenderWorldInfo.h"
# include "KX_KetsjiEngine.h"
# include "KX_BlenderSceneConverter.h"
# include"SND_Scene.h"
# include "SND_SoundListener.h"
/* This little block needed for linking to Blender... */
# ifdef WIN32
# include "BLI_winstuff.h"
# endif
/* This list includes only data type definitions */
# include "DNA_object_types.h"
# include "DNA_material_types.h"
2006-01-06 03:46:54 +00:00
# include "DNA_texture_types.h"
2002-10-12 11:37:38 +00:00
# include "DNA_image_types.h"
# include "DNA_lamp_types.h"
# include "DNA_group_types.h"
# include "DNA_scene_types.h"
# include "DNA_camera_types.h"
# include "DNA_property_types.h"
# include "DNA_text_types.h"
# include "DNA_sensor_types.h"
# include "DNA_controller_types.h"
# include "DNA_actuator_types.h"
# include "DNA_mesh_types.h"
2004-03-20 22:55:42 +00:00
# include "DNA_meshdata_types.h"
2002-10-12 11:37:38 +00:00
# include "DNA_view3d_types.h"
# include "DNA_world_types.h"
# include "DNA_sound_types.h"
# include "DNA_key_types.h"
2005-04-23 11:36:44 +00:00
# include "DNA_armature_types.h"
2008-09-25 16:48:25 +00:00
# include "DNA_object_force.h"
2002-10-12 11:37:38 +00:00
# include "MEM_guardedalloc.h"
# include "BKE_utildefines.h"
# include "BKE_key.h"
# include "BKE_mesh.h"
# include "MT_Point3.h"
2008-07-29 15:48:31 +00:00
# include "BLI_arithb.h"
2007-01-07 04:39:39 +00:00
extern " C " {
2008-07-29 15:48:31 +00:00
# include "BKE_customdata.h"
# include "BKE_cdderivedmesh.h"
# include "BKE_DerivedMesh.h"
2007-01-07 04:39:39 +00:00
}
2002-10-12 11:37:38 +00:00
# include "BKE_material.h" /* give_current_material */
/* end of blender include block */
# include "KX_BlenderInputDevice.h"
# include "KX_ConvertProperties.h"
# include "KX_HashedPtr.h"
# include "KX_ScalarInterpolator.h"
# include "KX_IpoConvert.h"
# include "SYS_System.h"
# include "SG_Node.h"
2004-05-16 12:52:08 +00:00
# include "SG_BBox.h"
# include "SG_Tree.h"
2002-10-12 11:37:38 +00:00
2002-10-18 14:36:34 +00:00
// defines USE_ODE to choose physics engine
2002-10-12 11:37:38 +00:00
# include "KX_ConvertPhysicsObject.h"
2009-04-07 22:14:06 +00:00
# ifdef USE_BULLET
# include "CcdPhysicsEnvironment.h"
# include "CcdGraphicController.h"
# endif
# include "KX_MotionState.h"
2002-10-12 11:37:38 +00:00
// This file defines relationships between parents and children
// in the game engine.
# include "KX_SG_NodeRelationships.h"
2005-04-23 11:36:44 +00:00
# include "KX_SG_BoneParentNodeRelationship.h"
2002-10-12 11:37:38 +00:00
# include "BL_ArmatureObject.h"
# include "BL_DeformableGameObject.h"
2006-12-16 05:50:38 +00:00
# ifdef __cplusplus
extern " C " {
# endif
# include "BSE_headerbuttons.h"
void update_for_newframe ( ) ;
//void scene_update_for_newframe(struct Scene *sce, unsigned int lay);
//#include "BKE_ipo.h"
//void do_all_data_ipos(void);
# ifdef __cplusplus
}
# endif
2004-12-01 08:43:02 +00:00
static int default_face_mode = TF_DYNAMIC ;
2002-10-12 11:37:38 +00:00
static unsigned int KX_rgbaint2uint_new ( unsigned int icol )
{
2004-11-25 08:09:18 +00:00
union
{
unsigned int integer ;
unsigned char cp [ 4 ] ;
2007-04-04 14:25:10 +00:00
} out_color , in_color ;
2004-11-25 08:09:18 +00:00
2007-04-04 13:18:41 +00:00
in_color . integer = icol ;
out_color . cp [ 0 ] = in_color . cp [ 3 ] ; // red
out_color . cp [ 1 ] = in_color . cp [ 2 ] ; // green
out_color . cp [ 2 ] = in_color . cp [ 1 ] ; // blue
out_color . cp [ 3 ] = in_color . cp [ 0 ] ; // alpha
2004-11-25 08:09:18 +00:00
2007-04-04 13:18:41 +00:00
return out_color . integer ;
2002-10-12 11:37:38 +00:00
}
/* Now the real converting starts... */
static unsigned int KX_Mcol2uint_new ( MCol col )
{
/* color has to be converted without endian sensitivity. So no shifting! */
2004-11-25 08:09:18 +00:00
union
{
MCol col ;
unsigned int integer ;
unsigned char cp [ 4 ] ;
2007-04-04 13:18:41 +00:00
} out_color , in_color ;
2004-11-25 08:09:18 +00:00
2007-04-04 13:18:41 +00:00
in_color . col = col ;
out_color . cp [ 0 ] = in_color . cp [ 3 ] ; // red
out_color . cp [ 1 ] = in_color . cp [ 2 ] ; // green
out_color . cp [ 2 ] = in_color . cp [ 1 ] ; // blue
out_color . cp [ 3 ] = in_color . cp [ 0 ] ; // alpha
2004-11-25 08:09:18 +00:00
2007-04-04 13:18:41 +00:00
return out_color . integer ;
2002-10-12 11:37:38 +00:00
}
2004-12-01 08:43:02 +00:00
static void SetDefaultFaceType ( Scene * scene )
{
default_face_mode = TF_DYNAMIC ;
2008-06-18 06:46:49 +00:00
Scene * sce ;
Base * base ;
for ( SETLOOPER ( scene , base ) )
2004-12-01 08:43:02 +00:00
{
if ( base - > object - > type = = OB_LAMP )
{
default_face_mode = TF_DYNAMIC | TF_LIGHT ;
return ;
}
}
}
2006-01-06 03:46:54 +00:00
// --
static void GetRGB ( short type ,
MFace * mface ,
MCol * mmcol ,
Material * mat ,
unsigned int & c0 ,
unsigned int & c1 ,
unsigned int & c2 ,
unsigned int & c3 )
{
2007-04-04 13:18:41 +00:00
unsigned int color = 0xFFFFFFFFL ;
2006-01-06 03:46:54 +00:00
switch ( type )
{
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
case 0 : // vertex colors
2006-01-06 03:46:54 +00:00
{
if ( mmcol ) {
c0 = KX_Mcol2uint_new ( mmcol [ 0 ] ) ;
c1 = KX_Mcol2uint_new ( mmcol [ 1 ] ) ;
c2 = KX_Mcol2uint_new ( mmcol [ 2 ] ) ;
if ( mface - > v4 )
c3 = KX_Mcol2uint_new ( mmcol [ 3 ] ) ;
} else // backup white
{
2007-04-04 13:18:41 +00:00
c0 = KX_rgbaint2uint_new ( color ) ;
c1 = KX_rgbaint2uint_new ( color ) ;
c2 = KX_rgbaint2uint_new ( color ) ;
2006-01-06 03:46:54 +00:00
if ( mface - > v4 )
2007-04-04 13:18:41 +00:00
c3 = KX_rgbaint2uint_new ( color ) ;
2006-01-06 03:46:54 +00:00
}
} break ;
case 1 : // material rgba
{
if ( mat ) {
union {
unsigned char cp [ 4 ] ;
unsigned int integer ;
} col_converter ;
col_converter . cp [ 3 ] = ( unsigned char ) ( mat - > r * 255.0 ) ;
col_converter . cp [ 2 ] = ( unsigned char ) ( mat - > g * 255.0 ) ;
col_converter . cp [ 1 ] = ( unsigned char ) ( mat - > b * 255.0 ) ;
col_converter . cp [ 0 ] = ( unsigned char ) ( mat - > alpha * 255.0 ) ;
2007-04-04 13:18:41 +00:00
color = col_converter . integer ;
2006-01-06 03:46:54 +00:00
}
2007-04-04 13:18:41 +00:00
c0 = KX_rgbaint2uint_new ( color ) ;
c1 = KX_rgbaint2uint_new ( color ) ;
c2 = KX_rgbaint2uint_new ( color ) ;
2006-01-06 03:46:54 +00:00
if ( mface - > v4 )
2007-04-04 13:18:41 +00:00
c3 = KX_rgbaint2uint_new ( color ) ;
2006-01-06 03:46:54 +00:00
} break ;
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
default : // white
2006-01-06 03:46:54 +00:00
{
2007-04-04 13:18:41 +00:00
c0 = KX_rgbaint2uint_new ( color ) ;
c1 = KX_rgbaint2uint_new ( color ) ;
c2 = KX_rgbaint2uint_new ( color ) ;
2006-01-06 03:46:54 +00:00
if ( mface - > v4 )
2007-04-04 13:18:41 +00:00
c3 = KX_rgbaint2uint_new ( color ) ;
2006-01-06 03:46:54 +00:00
} break ;
}
}
2007-01-07 04:39:39 +00:00
typedef struct MTF_localLayer
{
MTFace * face ;
2008-09-20 11:08:35 +00:00
const char * name ;
2007-01-07 04:39:39 +00:00
} MTF_localLayer ;
2006-01-06 03:46:54 +00:00
// ------------------------------------
2009-04-29 10:06:38 +00:00
bool ConvertMaterial (
BL_Material * material ,
2007-01-07 04:39:39 +00:00
Material * mat ,
MTFace * tface ,
2008-07-10 12:47:20 +00:00
const char * tfaceName ,
2007-01-07 04:39:39 +00:00
MFace * mface ,
MCol * mmcol ,
int lightlayer ,
Object * blenderobj ,
2008-07-10 12:47:20 +00:00
MTF_localLayer * layers ,
bool glslmat )
2006-01-06 03:46:54 +00:00
{
2009-04-29 10:06:38 +00:00
material - > Initialize ( ) ;
2008-07-29 15:48:31 +00:00
int numchan = - 1 , texalpha = 0 ;
2006-01-06 03:46:54 +00:00
bool validmat = ( mat ! = 0 ) ;
2008-07-29 15:48:31 +00:00
bool validface = ( tface ! = 0 ) ;
2006-04-13 05:11:34 +00:00
2006-01-06 03:46:54 +00:00
short type = 0 ;
if ( validmat )
type = 1 ; // material color
material - > IdMode = DEFAULT_BLENDER ;
2008-07-29 15:48:31 +00:00
material - > glslmat = ( validmat ) ? glslmat : false ;
BGE: Support mesh modifiers in the game engine.
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
2009-04-21 11:01:09 +00:00
material - > materialindex = mface - > mat_nr ;
2006-01-06 03:46:54 +00:00
// --------------------------------
if ( validmat ) {
// use vertex colors by explicitly setting
2008-07-10 12:47:20 +00:00
if ( mat - > mode & MA_VERTEXCOLP | | glslmat )
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
type = 0 ;
2006-01-06 03:46:54 +00:00
// use lighting?
material - > ras_mode | = ( mat - > mode & MA_SHLESS ) ? 0 : USE_LIGHT ;
MTex * mttmp = 0 ;
numchan = getNumTexChannels ( mat ) ;
int valid_index = 0 ;
2006-04-13 05:11:34 +00:00
// use the face texture if
// 1) it is set in the buttons
// 2) we have a face texture and a material but no valid texture in slot 1
bool facetex = false ;
if ( validface & & mat - > mode & MA_FACETEXTURE )
facetex = true ;
if ( validface & & ! mat - > mtex [ 0 ] )
facetex = true ;
if ( validface & & mat - > mtex [ 0 ] ) {
MTex * tmp = mat - > mtex [ 0 ] ;
2009-02-19 13:42:07 +00:00
if ( ! tmp - > tex | | ( tmp - > tex & & ! tmp - > tex - > ima ) )
2006-04-13 05:11:34 +00:00
facetex = true ;
}
numchan = numchan > MAXTEX ? MAXTEX : numchan ;
2006-01-06 03:46:54 +00:00
// foreach MTex
for ( int i = 0 ; i < numchan ; i + + ) {
// use face tex
2007-01-07 04:39:39 +00:00
2006-01-06 03:46:54 +00:00
if ( i = = 0 & & facetex ) {
Image * tmp = ( Image * ) ( tface - > tpage ) ;
2008-07-29 15:48:31 +00:00
2006-01-06 03:46:54 +00:00
if ( tmp ) {
material - > img [ i ] = tmp ;
material - > texname [ i ] = material - > img [ i ] - > id . name ;
material - > flag [ i ] | = ( tface - > transp & TF_ALPHA ) ? USEALPHA : 0 ;
material - > flag [ i ] | = ( tface - > transp & TF_ADD ) ? CALCALPHA : 0 ;
2008-09-14 01:10:45 +00:00
material - > flag [ i ] | = MIPMAP ;
2008-07-29 15:48:31 +00:00
2006-02-13 05:45:32 +00:00
if ( material - > img [ i ] - > flag & IMA_REFLECT )
material - > mapping [ i ] . mapping | = USEREFL ;
else
2007-01-07 04:39:39 +00:00
{
mttmp = getImageFromMaterial ( mat , i ) ;
if ( mttmp & & mttmp - > texco & TEXCO_UV )
{
STR_String uvName = mttmp - > uvname ;
if ( ! uvName . IsEmpty ( ) )
material - > mapping [ i ] . uvCoName = mttmp - > uvname ;
else
material - > mapping [ i ] . uvCoName = " " ;
}
2006-02-13 05:45:32 +00:00
material - > mapping [ i ] . mapping | = USEUV ;
2007-01-07 04:39:39 +00:00
}
2006-04-13 05:11:34 +00:00
if ( material - > ras_mode & USE_LIGHT )
material - > ras_mode & = ~ USE_LIGHT ;
if ( tface - > mode & TF_LIGHT )
material - > ras_mode | = USE_LIGHT ;
2006-01-06 03:46:54 +00:00
valid_index + + ;
}
2006-04-13 05:11:34 +00:00
else {
material - > img [ i ] = 0 ;
material - > texname [ i ] = " " ;
}
continue ;
2006-01-06 03:46:54 +00:00
}
mttmp = getImageFromMaterial ( mat , i ) ;
if ( mttmp ) {
if ( mttmp - > tex ) {
if ( mttmp - > tex - > type = = TEX_IMAGE ) {
material - > mtexname [ i ] = mttmp - > tex - > id . name ;
material - > img [ i ] = mttmp - > tex - > ima ;
if ( material - > img [ i ] ) {
material - > texname [ i ] = material - > img [ i ] - > id . name ;
material - > flag [ i ] | = ( mttmp - > tex - > imaflag & TEX_MIPMAP ) ? MIPMAP : 0 ;
// -----------------------
if ( mttmp - > tex - > imaflag & TEX_USEALPHA ) {
material - > flag [ i ] | = USEALPHA ;
}
// -----------------------
else if ( mttmp - > tex - > imaflag & TEX_CALCALPHA ) {
material - > flag [ i ] | = CALCALPHA ;
2006-01-15 11:34:55 +00:00
}
else if ( mttmp - > tex - > flag & TEX_NEGALPHA ) {
material - > flag [ i ] | = USENEGALPHA ;
2006-01-06 03:46:54 +00:00
}
material - > color_blend [ i ] = mttmp - > colfac ;
material - > flag [ i ] | = ( mttmp - > mapto & MAP_ALPHA ) ? TEXALPHA : 0 ;
material - > flag [ i ] | = ( mttmp - > texflag & MTEX_NEGATIVE ) ? TEXNEG : 0 ;
2008-07-29 15:48:31 +00:00
if ( ! glslmat & & ( material - > flag [ i ] & TEXALPHA ) )
texalpha = 1 ;
2006-01-06 03:46:54 +00:00
}
}
else if ( mttmp - > tex - > type = = TEX_ENVMAP ) {
if ( mttmp - > tex - > env - > stype = = ENV_LOAD ) {
2007-01-13 08:30:08 +00:00
material - > mtexname [ i ] = mttmp - > tex - > id . name ;
EnvMap * env = mttmp - > tex - > env ;
env - > ima = mttmp - > tex - > ima ;
material - > cubemap [ i ] = env ;
if ( material - > cubemap [ i ] )
{
if ( ! material - > cubemap [ i ] - > cube [ 0 ] )
BL_Texture : : SplitEnvMap ( material - > cubemap [ i ] ) ;
material - > texname [ i ] = material - > cubemap [ i ] - > ima - > id . name ;
2006-01-06 03:46:54 +00:00
material - > mapping [ i ] . mapping | = USEENV ;
}
}
}
material - > flag [ i ] | = ( mat - > ipo ! = 0 ) ? HASIPO : 0 ;
/// --------------------------------
// mapping methods
material - > mapping [ i ] . mapping | = ( mttmp - > texco & TEXCO_REFL ) ? USEREFL : 0 ;
if ( mttmp - > texco & TEXCO_OBJECT ) {
material - > mapping [ i ] . mapping | = USEOBJ ;
if ( mttmp - > object )
material - > mapping [ i ] . objconame = mttmp - > object - > id . name ;
}
2006-02-13 05:45:32 +00:00
else if ( mttmp - > texco & TEXCO_REFL )
material - > mapping [ i ] . mapping | = USEREFL ;
else if ( mttmp - > texco & ( TEXCO_ORCO | TEXCO_GLOB ) )
material - > mapping [ i ] . mapping | = USEORCO ;
else if ( mttmp - > texco & TEXCO_UV )
2007-01-07 04:39:39 +00:00
{
STR_String uvName = mttmp - > uvname ;
if ( ! uvName . IsEmpty ( ) )
material - > mapping [ i ] . uvCoName = mttmp - > uvname ;
else
material - > mapping [ i ] . uvCoName = " " ;
2006-02-13 05:45:32 +00:00
material - > mapping [ i ] . mapping | = USEUV ;
2007-01-07 04:39:39 +00:00
}
2006-02-13 05:45:32 +00:00
else if ( mttmp - > texco & TEXCO_NORM )
material - > mapping [ i ] . mapping | = USENORM ;
2006-04-02 21:04:20 +00:00
else if ( mttmp - > texco & TEXCO_TANGENT )
material - > mapping [ i ] . mapping | = USETANG ;
2006-02-13 05:45:32 +00:00
else
material - > mapping [ i ] . mapping | = DISABLE ;
2006-01-06 03:46:54 +00:00
material - > mapping [ i ] . scale [ 0 ] = mttmp - > size [ 0 ] ;
material - > mapping [ i ] . scale [ 1 ] = mttmp - > size [ 1 ] ;
material - > mapping [ i ] . scale [ 2 ] = mttmp - > size [ 2 ] ;
material - > mapping [ i ] . offsets [ 0 ] = mttmp - > ofs [ 0 ] ;
material - > mapping [ i ] . offsets [ 1 ] = mttmp - > ofs [ 1 ] ;
material - > mapping [ i ] . offsets [ 2 ] = mttmp - > ofs [ 2 ] ;
material - > mapping [ i ] . projplane [ 0 ] = mttmp - > projx ;
material - > mapping [ i ] . projplane [ 1 ] = mttmp - > projy ;
material - > mapping [ i ] . projplane [ 2 ] = mttmp - > projz ;
/// --------------------------------
switch ( mttmp - > blendtype ) {
case MTEX_BLEND :
material - > blend_mode [ i ] = BLEND_MIX ;
break ;
case MTEX_MUL :
material - > blend_mode [ i ] = BLEND_MUL ;
break ;
case MTEX_ADD :
material - > blend_mode [ i ] = BLEND_ADD ;
break ;
case MTEX_SUB :
material - > blend_mode [ i ] = BLEND_SUB ;
break ;
case MTEX_SCREEN :
material - > blend_mode [ i ] = BLEND_SCR ;
break ;
}
valid_index + + ;
}
}
}
Merge of apricot branch game engine changes into trunk, excluding GLSL.
GLEW
====
Added the GLEW opengl extension library into extern/, always compiled
into Blender now. This is much nicer than doing this kind of extension
management manually, and will be used in the game engine, for GLSL, and
other opengl extensions.
* According to the GLEW website it works on Windows, Linux, Mac OS X,
FreeBSD, Irix, and Solaris. There might still be platform specific
issues due to this commit, so let me know and I'll look into it.
* This means also that all extensions will now always be compiled in,
regardless of the glext.h on the platform where compilation happens.
Game Engine
===========
Refactoring of the use of opengl extensions and other drawing code
in the game engine, and cleaning up some hacks related to GLSL
integration. These changes will be merged into trunk too after this.
The game engine graphics demos & apricot level survived my tests,
but this could use some good testing of course.
For users: please test with the options "Generate Display Lists" and
"Vertex Arrays" enabled, these should be the fastest and are supposed
to be "unreliable", but if that's the case that's probably due to bugs
that can be fixed.
* The game engine now also uses GLEW for extensions, replacing the
custom opengl extensions code that was there. Removes a lot of
#ifdef's, but the runtime checks stay of course.
* Removed the WITHOUT_GLEXT environment variable. This was added to
work around a specific bug and only disabled multitexturing anyway.
It might also have caused a slowdown since it was retrieving the
environment variable for every vertex in immediate mode (bug #13680).
* Refactored the code to allow drawing skinned meshes with vertex
arrays too, removing some specific immediate mode drawing functions
for this that only did extra normal calculation. Now it always splits
vertices of flat faces instead.
* Refactored normal recalculation with some minor optimizations,
required for the above change.
* Removed some outdated code behind the __NLA_OLDDEFORM #ifdef.
* Fixed various bugs in setting of multitexture coordinates and vertex
attributes for vertex arrays. These were not being enabled/disabled
correct according to the opengl spec, leading to crashes. Also tangent
attributes used an immediate mode call for vertex arrays, which can't
work.
* Fixed use of uninitialized variable in RAS_TexVert.
* Exporting skinned meshes was doing O(n^2) lookups for vertices and
deform weights, now uses same trick as regular meshes.
2008-06-17 10:27:34 +00:00
2006-01-06 03:46:54 +00:00
// above one tex the switches here
// are not used
switch ( valid_index ) {
case 0 :
material - > IdMode = DEFAULT_BLENDER ;
break ;
case 1 :
material - > IdMode = ONETEX ;
break ;
default :
material - > IdMode = GREATERTHAN2 ;
break ;
}
2006-02-13 05:45:32 +00:00
material - > SetUsers ( mat - > id . us ) ;
2006-01-06 03:46:54 +00:00
material - > num_enabled = valid_index ;
material - > speccolor [ 0 ] = mat - > specr ;
material - > speccolor [ 1 ] = mat - > specg ;
material - > speccolor [ 2 ] = mat - > specb ;
material - > hard = ( float ) mat - > har / 4.0f ;
material - > matcolor [ 0 ] = mat - > r ;
material - > matcolor [ 1 ] = mat - > g ;
material - > matcolor [ 2 ] = mat - > b ;
material - > matcolor [ 3 ] = mat - > alpha ;
material - > alpha = mat - > alpha ;
material - > emit = mat - > emit ;
material - > spec_f = mat - > spec ;
material - > ref = mat - > ref ;
material - > amb = mat - > amb ;
2006-04-11 05:57:30 +00:00
2008-07-29 15:48:31 +00:00
material - > ras_mode | = ( mat - > mode & MA_WIRE ) ? WIRE : 0 ;
2006-01-06 03:46:54 +00:00
}
else {
int valid = 0 ;
2008-07-10 12:47:20 +00:00
2006-01-06 03:46:54 +00:00
// check for tface tex to fallback on
2006-04-13 05:11:34 +00:00
if ( validface ) {
// no light bugfix
if ( tface - > mode ) material - > ras_mode | = USE_LIGHT ;
2006-01-06 03:46:54 +00:00
material - > img [ 0 ] = ( Image * ) ( tface - > tpage ) ;
// ------------------------
if ( material - > img [ 0 ] ) {
material - > texname [ 0 ] = material - > img [ 0 ] - > id . name ;
material - > mapping [ 0 ] . mapping | = ( ( material - > img [ 0 ] - > flag & IMA_REFLECT ) ! = 0 ) ? USEREFL : 0 ;
material - > flag [ 0 ] | = ( tface - > transp & TF_ALPHA ) ? USEALPHA : 0 ;
material - > flag [ 0 ] | = ( tface - > transp & TF_ADD ) ? CALCALPHA : 0 ;
valid + + ;
}
}
2006-02-13 05:45:32 +00:00
material - > SetUsers ( - 1 ) ;
2006-01-06 03:46:54 +00:00
material - > num_enabled = valid ;
material - > IdMode = TEXFACE ;
material - > speccolor [ 0 ] = 1.f ;
material - > speccolor [ 1 ] = 1.f ;
material - > speccolor [ 2 ] = 1.f ;
material - > hard = 35.f ;
material - > matcolor [ 0 ] = 0.5f ;
material - > matcolor [ 1 ] = 0.5f ;
material - > matcolor [ 2 ] = 0.5f ;
material - > spec_f = 0.5f ;
material - > ref = 0.8f ;
}
MT_Point2 uv [ 4 ] ;
2007-01-07 04:39:39 +00:00
MT_Point2 uv2 [ 4 ] ;
2008-07-10 12:47:20 +00:00
const char * uvName = " " , * uv2Name = " " ;
2006-01-06 03:46:54 +00:00
2009-02-25 06:43:03 +00:00
Merge of apricot branch game engine changes into trunk, excluding GLSL.
GLEW
====
Added the GLEW opengl extension library into extern/, always compiled
into Blender now. This is much nicer than doing this kind of extension
management manually, and will be used in the game engine, for GLSL, and
other opengl extensions.
* According to the GLEW website it works on Windows, Linux, Mac OS X,
FreeBSD, Irix, and Solaris. There might still be platform specific
issues due to this commit, so let me know and I'll look into it.
* This means also that all extensions will now always be compiled in,
regardless of the glext.h on the platform where compilation happens.
Game Engine
===========
Refactoring of the use of opengl extensions and other drawing code
in the game engine, and cleaning up some hacks related to GLSL
integration. These changes will be merged into trunk too after this.
The game engine graphics demos & apricot level survived my tests,
but this could use some good testing of course.
For users: please test with the options "Generate Display Lists" and
"Vertex Arrays" enabled, these should be the fastest and are supposed
to be "unreliable", but if that's the case that's probably due to bugs
that can be fixed.
* The game engine now also uses GLEW for extensions, replacing the
custom opengl extensions code that was there. Removes a lot of
#ifdef's, but the runtime checks stay of course.
* Removed the WITHOUT_GLEXT environment variable. This was added to
work around a specific bug and only disabled multitexturing anyway.
It might also have caused a slowdown since it was retrieving the
environment variable for every vertex in immediate mode (bug #13680).
* Refactored the code to allow drawing skinned meshes with vertex
arrays too, removing some specific immediate mode drawing functions
for this that only did extra normal calculation. Now it always splits
vertices of flat faces instead.
* Refactored normal recalculation with some minor optimizations,
required for the above change.
* Removed some outdated code behind the __NLA_OLDDEFORM #ifdef.
* Fixed various bugs in setting of multitexture coordinates and vertex
attributes for vertex arrays. These were not being enabled/disabled
correct according to the opengl spec, leading to crashes. Also tangent
attributes used an immediate mode call for vertex arrays, which can't
work.
* Fixed use of uninitialized variable in RAS_TexVert.
* Exporting skinned meshes was doing O(n^2) lookups for vertices and
deform weights, now uses same trick as regular meshes.
2008-06-17 10:27:34 +00:00
uv2 [ 0 ] = uv2 [ 1 ] = uv2 [ 2 ] = uv2 [ 3 ] = MT_Point2 ( 0.0f , 0.0f ) ;
2006-04-13 05:11:34 +00:00
if ( validface ) {
2006-01-06 03:46:54 +00:00
2009-04-19 06:29:15 +00:00
material - > ras_mode | = ( tface - > mode & TF_INVISIBLE ) ? 0 : POLY_VIS ;
2006-01-06 03:46:54 +00:00
material - > transp = tface - > transp ;
material - > tile = tface - > tile ;
material - > mode = tface - > mode ;
2009-02-25 06:43:03 +00:00
uv [ 0 ] . setValue ( tface - > uv [ 0 ] ) ;
uv [ 1 ] . setValue ( tface - > uv [ 1 ] ) ;
uv [ 2 ] . setValue ( tface - > uv [ 2 ] ) ;
2006-01-06 03:46:54 +00:00
if ( mface - > v4 )
2009-02-25 06:43:03 +00:00
uv [ 3 ] . setValue ( tface - > uv [ 3 ] ) ;
2008-07-10 12:47:20 +00:00
uvName = tfaceName ;
2006-01-06 03:46:54 +00:00
}
else {
// nothing at all
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
material - > ras_mode | = ( POLY_VIS | ( validmat ? 0 : USE_LIGHT ) ) ;
2006-01-06 03:46:54 +00:00
material - > mode = default_face_mode ;
material - > transp = TF_SOLID ;
material - > tile = 0 ;
2009-02-25 06:43:03 +00:00
uv [ 0 ] = uv [ 1 ] = uv [ 2 ] = uv [ 3 ] = MT_Point2 ( 0.0f , 0.0f ) ;
2006-01-06 03:46:54 +00:00
}
2007-01-07 04:39:39 +00:00
2008-07-29 15:48:31 +00:00
// with ztransp enabled, enforce alpha blending mode
if ( validmat & & ( mat - > mode & MA_ZTRA ) & & ( material - > transp = = TF_SOLID ) )
material - > transp = TF_ALPHA ;
2007-01-07 04:39:39 +00:00
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
// always zsort alpha + add
2008-09-14 00:32:18 +00:00
if ( ( material - > transp = = TF_ALPHA | | material - > transp = = TF_ADD | | texalpha ) & & ( material - > transp ! = TF_CLIP ) ) {
2008-07-29 15:48:31 +00:00
material - > ras_mode | = ALPHA ;
material - > ras_mode | = ( material - > mode & TF_ALPHASORT ) ? ZSORT : 0 ;
}
2007-01-07 04:39:39 +00:00
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
// collider or not?
material - > ras_mode | = ( material - > mode & TF_DYNAMIC ) ? COLLIDER : 0 ;
// these flags are irrelevant at this point, remove so they
// don't hurt material bucketing
material - > mode & = ~ ( TF_DYNAMIC | TF_ALPHASORT | TF_TEX ) ;
2007-01-07 04:39:39 +00:00
// get uv sets
if ( validmat )
{
bool isFirstSet = true ;
// only two sets implemented, but any of the eight
// sets can make up the two layers
for ( int vind = 0 ; vind < material - > num_enabled ; vind + + )
{
BL_Mapping & map = material - > mapping [ vind ] ;
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
2007-01-07 04:39:39 +00:00
if ( map . uvCoName . IsEmpty ( ) )
isFirstSet = false ;
else
{
for ( int lay = 0 ; lay < MAX_MTFACE ; lay + + )
{
MTF_localLayer & layer = layers [ lay ] ;
if ( layer . face = = 0 ) break ;
if ( strcmp ( map . uvCoName . ReadPtr ( ) , layer . name ) = = 0 )
{
2008-07-10 12:47:20 +00:00
MT_Point2 uvSet [ 4 ] ;
2009-02-25 06:43:03 +00:00
uvSet [ 0 ] . setValue ( layer . face - > uv [ 0 ] ) ;
uvSet [ 1 ] . setValue ( layer . face - > uv [ 1 ] ) ;
uvSet [ 2 ] . setValue ( layer . face - > uv [ 2 ] ) ;
2007-01-07 04:39:39 +00:00
if ( mface - > v4 )
2009-02-25 06:43:03 +00:00
uvSet [ 3 ] . setValue ( layer . face - > uv [ 3 ] ) ;
2008-07-10 12:47:20 +00:00
else
2009-02-25 06:43:03 +00:00
uvSet [ 3 ] . setValue ( 0.0f , 0.0f ) ;
2007-01-07 04:39:39 +00:00
2008-07-10 12:47:20 +00:00
if ( isFirstSet )
{
uv [ 0 ] = uvSet [ 0 ] ; uv [ 1 ] = uvSet [ 1 ] ;
uv [ 2 ] = uvSet [ 2 ] ; uv [ 3 ] = uvSet [ 3 ] ;
isFirstSet = false ;
uvName = layer . name ;
}
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
else if ( strcmp ( layer . name , uvName ) ! = 0 )
2008-07-10 12:47:20 +00:00
{
uv2 [ 0 ] = uvSet [ 0 ] ; uv2 [ 1 ] = uvSet [ 1 ] ;
uv2 [ 2 ] = uvSet [ 2 ] ; uv2 [ 3 ] = uvSet [ 3 ] ;
map . mapping | = USECUSTOMUV ;
uv2Name = layer . name ;
}
2007-01-07 04:39:39 +00:00
}
}
}
}
}
2006-01-06 03:46:54 +00:00
unsigned int rgb [ 4 ] ;
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
GetRGB ( type , mface , mmcol , mat , rgb [ 0 ] , rgb [ 1 ] , rgb [ 2 ] , rgb [ 3 ] ) ;
2007-02-05 05:48:09 +00:00
// swap the material color, so MCol on TF_BMFONT works
2007-02-05 08:07:55 +00:00
if ( validmat & & type = = 1 & & ( tface & & tface - > mode & TF_BMFONT ) )
2007-02-05 05:48:09 +00:00
{
rgb [ 0 ] = KX_rgbaint2uint_new ( rgb [ 0 ] ) ;
rgb [ 1 ] = KX_rgbaint2uint_new ( rgb [ 1 ] ) ;
rgb [ 2 ] = KX_rgbaint2uint_new ( rgb [ 2 ] ) ;
rgb [ 3 ] = KX_rgbaint2uint_new ( rgb [ 3 ] ) ;
}
2006-01-06 03:46:54 +00:00
material - > SetConversionRGB ( rgb ) ;
2008-07-10 12:47:20 +00:00
material - > SetConversionUV ( uvName , uv ) ;
material - > SetConversionUV2 ( uv2Name , uv2 ) ;
2006-01-06 03:46:54 +00:00
if ( validmat )
material - > matname = ( mat - > id . name ) ;
material - > tface = tface ;
material - > material = mat ;
2009-04-29 10:06:38 +00:00
return true ;
2006-01-06 03:46:54 +00:00
}
2004-04-24 06:40:15 +00:00
RAS_MeshObject * BL_ConvertMesh ( Mesh * mesh , Object * blenderobj , RAS_IRenderTools * rendertools , KX_Scene * scene , KX_BlenderSceneConverter * converter )
2002-10-12 11:37:38 +00:00
{
RAS_MeshObject * meshobj ;
2008-07-29 15:48:31 +00:00
bool skinMesh = false ;
2002-10-12 11:37:38 +00:00
int lightlayer = blenderobj - > lay ;
2008-07-29 15:48:31 +00:00
2009-05-23 14:46:43 +00:00
if ( ( meshobj = converter - > FindGameMesh ( mesh /*, ob->lay*/ ) ) ! = NULL )
return meshobj ;
2008-07-29 15:48:31 +00:00
// Get DerivedMesh data
DerivedMesh * dm = CDDM_from_mesh ( mesh , blenderobj ) ;
MVert * mvert = dm - > getVertArray ( dm ) ;
int totvert = dm - > getNumVerts ( dm ) ;
MFace * mface = dm - > getFaceArray ( dm ) ;
MTFace * tface = static_cast < MTFace * > ( dm - > getFaceDataArray ( dm , CD_MTFACE ) ) ;
MCol * mcol = static_cast < MCol * > ( dm - > getFaceDataArray ( dm , CD_MCOL ) ) ;
float ( * tangent ) [ 3 ] = NULL ;
int totface = dm - > getNumFaces ( dm ) ;
2008-07-10 12:47:20 +00:00
const char * tfaceName = " " ;
2007-01-07 04:39:39 +00:00
2008-07-29 15:48:31 +00:00
if ( tface ) {
DM_add_tangent_layer ( dm ) ;
tangent = ( float ( * ) [ 3 ] ) dm - > getFaceDataArray ( dm , CD_TANGENT ) ;
}
2007-01-07 04:39:39 +00:00
2002-10-12 11:37:38 +00:00
// Determine if we need to make a skinned mesh
BGE: Support mesh modifiers in the game engine.
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
2009-04-21 11:01:09 +00:00
if ( mesh - > dvert | | mesh - > key | | ( ( blenderobj - > gameflag & OB_SOFT_BODY ) ! = 0 ) | | BL_ModifierDeformer : : HasCompatibleDeformer ( blenderobj ) )
2008-09-24 03:12:10 +00:00
{
2008-06-18 06:46:49 +00:00
meshobj = new BL_SkinMeshObject ( mesh , lightlayer ) ;
2002-10-12 11:37:38 +00:00
skinMesh = true ;
}
2008-07-29 15:48:31 +00:00
else
2008-06-18 06:46:49 +00:00
meshobj = new RAS_MeshObject ( mesh , lightlayer ) ;
2007-01-07 04:39:39 +00:00
// Extract avaiable layers
MTF_localLayer * layers = new MTF_localLayer [ MAX_MTFACE ] ;
2008-07-29 15:48:31 +00:00
for ( int lay = 0 ; lay < MAX_MTFACE ; lay + + ) {
2007-01-07 04:39:39 +00:00
layers [ lay ] . face = 0 ;
layers [ lay ] . name = " " ;
}
int validLayers = 0 ;
2008-07-29 15:48:31 +00:00
for ( int i = 0 ; i < dm - > faceData . totlayer ; i + + )
2007-01-07 04:39:39 +00:00
{
2008-07-29 15:48:31 +00:00
if ( dm - > faceData . layers [ i ] . type = = CD_MTFACE )
2007-01-07 04:39:39 +00:00
{
assert ( validLayers < = 8 ) ;
2008-07-29 15:48:31 +00:00
layers [ validLayers ] . face = ( MTFace * ) ( dm - > faceData . layers [ i ] . data ) ;
layers [ validLayers ] . name = dm - > faceData . layers [ i ] . name ;
2008-07-10 12:47:20 +00:00
if ( tface = = layers [ validLayers ] . face )
tfaceName = layers [ validLayers ] . name ;
2007-01-07 04:39:39 +00:00
validLayers + + ;
}
}
2002-10-12 11:37:38 +00:00
meshobj - > SetName ( mesh - > id . name ) ;
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
meshobj - > m_sharedvertex_map . resize ( totvert ) ;
2009-04-29 10:06:38 +00:00
RAS_IPolyMaterial * polymat = NULL ;
STR_String imastr ;
// These pointers will hold persistent material structure during the conversion
// to avoid countless allocation/deallocation of memory.
BL_Material * bl_mat = NULL ;
KX_BlenderMaterial * kx_blmat = NULL ;
KX_PolygonMaterial * kx_polymat = NULL ;
2008-07-29 15:48:31 +00:00
for ( int f = 0 ; f < totface ; f + + , mface + + )
2002-10-12 11:37:38 +00:00
{
2008-07-29 15:48:31 +00:00
Material * ma = 0 ;
2002-10-12 11:37:38 +00:00
bool collider = true ;
2008-07-29 15:48:31 +00:00
MT_Point2 uv0 ( 0.0 , 0.0 ) , uv1 ( 0.0 , 0.0 ) , uv2 ( 0.0 , 0.0 ) , uv3 ( 0.0 , 0.0 ) ;
MT_Point2 uv20 ( 0.0 , 0.0 ) , uv21 ( 0.0 , 0.0 ) , uv22 ( 0.0 , 0.0 ) , uv23 ( 0.0 , 0.0 ) ;
unsigned int rgb0 , rgb1 , rgb2 , rgb3 = 0 ;
MT_Point3 pt0 , pt1 , pt2 , pt3 ;
2008-09-14 17:59:22 +00:00
MT_Vector3 no0 ( 0 , 0 , 0 ) , no1 ( 0 , 0 , 0 ) , no2 ( 0 , 0 , 0 ) , no3 ( 0 , 0 , 0 ) ;
MT_Vector4 tan0 ( 0 , 0 , 0 , 0 ) , tan1 ( 0 , 0 , 0 , 0 ) , tan2 ( 0 , 0 , 0 , 0 ) , tan3 ( 0 , 0 , 0 , 0 ) ;
2008-07-29 15:48:31 +00:00
/* get coordinates, normals and tangents */
2009-02-25 06:43:03 +00:00
pt0 . setValue ( mvert [ mface - > v1 ] . co ) ;
pt1 . setValue ( mvert [ mface - > v2 ] . co ) ;
pt2 . setValue ( mvert [ mface - > v3 ] . co ) ;
if ( mface - > v4 ) pt3 . setValue ( mvert [ mface - > v4 ] . co ) ;
2008-07-29 15:48:31 +00:00
if ( mface - > flag & ME_SMOOTH ) {
float n0 [ 3 ] , n1 [ 3 ] , n2 [ 3 ] , n3 [ 3 ] ;
NormalShortToFloat ( n0 , mvert [ mface - > v1 ] . no ) ;
NormalShortToFloat ( n1 , mvert [ mface - > v2 ] . no ) ;
NormalShortToFloat ( n2 , mvert [ mface - > v3 ] . no ) ;
no0 = n0 ;
no1 = n1 ;
no2 = n2 ;
if ( mface - > v4 ) {
NormalShortToFloat ( n3 , mvert [ mface - > v4 ] . no ) ;
no3 = n3 ;
2002-10-12 11:37:38 +00:00
}
2008-07-29 15:48:31 +00:00
}
else {
float fno [ 3 ] ;
if ( mface - > v4 )
CalcNormFloat4 ( mvert [ mface - > v1 ] . co , mvert [ mface - > v2 ] . co ,
mvert [ mface - > v3 ] . co , mvert [ mface - > v4 ] . co , fno ) ;
else
CalcNormFloat ( mvert [ mface - > v1 ] . co , mvert [ mface - > v2 ] . co ,
mvert [ mface - > v3 ] . co , fno ) ;
no0 = no1 = no2 = no3 = MT_Vector3 ( fno ) ;
}
if ( tangent ) {
tan0 = tangent [ f * 4 + 0 ] ;
tan1 = tangent [ f * 4 + 1 ] ;
tan2 = tangent [ f * 4 + 2 ] ;
if ( mface - > v4 )
tan3 = tangent [ f * 4 + 3 ] ;
}
/* get material */
ma = give_current_material ( blenderobj , mface - > mat_nr + 1 ) ;
2002-10-12 11:37:38 +00:00
2008-07-29 15:48:31 +00:00
{
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
bool visible = true ;
2009-04-13 20:08:33 +00:00
bool twoside = false ;
2008-07-29 15:48:31 +00:00
if ( converter - > GetMaterials ( ) ) {
/* do Blender Multitexture and Blender GLSL materials */
unsigned int rgb [ 4 ] ;
MT_Point2 uv [ 4 ] ;
/* first is the BL_Material */
2009-04-29 10:06:38 +00:00
if ( ! bl_mat )
bl_mat = new BL_Material ( ) ;
ConvertMaterial ( bl_mat , ma , tface , tfaceName , mface , mcol ,
2008-07-29 15:48:31 +00:00
lightlayer , blenderobj , layers , converter - > GetGLSLMaterials ( ) ) ;
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
visible = ( ( bl_mat - > ras_mode & POLY_VIS ) ! = 0 ) ;
2008-07-29 15:48:31 +00:00
collider = ( ( bl_mat - > ras_mode & COLLIDER ) ! = 0 ) ;
2009-04-13 20:08:33 +00:00
twoside = ( ( bl_mat - > mode & TF_TWOSIDE ) ! = 0 ) ;
2008-07-29 15:48:31 +00:00
/* vertex colors and uv's were stored in bl_mat temporarily */
bl_mat - > GetConversionRGB ( rgb ) ;
rgb0 = rgb [ 0 ] ; rgb1 = rgb [ 1 ] ;
rgb2 = rgb [ 2 ] ; rgb3 = rgb [ 3 ] ;
bl_mat - > GetConversionUV ( uv ) ;
uv0 = uv [ 0 ] ; uv1 = uv [ 1 ] ;
uv2 = uv [ 2 ] ; uv3 = uv [ 3 ] ;
bl_mat - > GetConversionUV2 ( uv ) ;
uv20 = uv [ 0 ] ; uv21 = uv [ 1 ] ;
uv22 = uv [ 2 ] ; uv23 = uv [ 3 ] ;
/* then the KX_BlenderMaterial */
2009-04-29 10:06:38 +00:00
if ( kx_blmat = = NULL )
kx_blmat = new KX_BlenderMaterial ( ) ;
BGE: Support mesh modifiers in the game engine.
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
2009-04-21 11:01:09 +00:00
2009-04-29 10:06:38 +00:00
kx_blmat - > Initialize ( scene , bl_mat , skinMesh , lightlayer ) ;
polymat = static_cast < RAS_IPolyMaterial * > ( kx_blmat ) ;
2002-10-12 11:37:38 +00:00
}
2008-07-29 15:48:31 +00:00
else {
/* do Texture Face materials */
Image * bima = ( tface ) ? ( Image * ) tface - > tpage : NULL ;
2009-04-29 10:06:38 +00:00
imastr = ( tface ) ? ( bima ? ( bima ) - > id . name : " " ) : " " ;
2002-10-12 11:37:38 +00:00
2008-07-29 15:48:31 +00:00
char transp = 0 ;
short mode = 0 , tile = 0 ;
int tilexrep = 4 , tileyrep = 4 ;
if ( bima ) {
tilexrep = bima - > xrep ;
tileyrep = bima - > yrep ;
}
/* get tface properties if available */
if ( tface ) {
/* TF_DYNAMIC means the polygon is a collision face */
collider = ( ( tface - > mode & TF_DYNAMIC ) ! = 0 ) ;
transp = tface - > transp ;
tile = tface - > tile ;
mode = tface - > mode ;
2002-10-12 11:37:38 +00:00
2009-04-19 06:29:15 +00:00
visible = ! ( tface - > mode & TF_INVISIBLE ) ;
2009-04-13 20:08:33 +00:00
twoside = ( ( tface - > mode & TF_TWOSIDE ) ! = 0 ) ;
2002-10-12 11:37:38 +00:00
2009-02-25 06:43:03 +00:00
uv0 . setValue ( tface - > uv [ 0 ] ) ;
uv1 . setValue ( tface - > uv [ 1 ] ) ;
uv2 . setValue ( tface - > uv [ 2 ] ) ;
2008-07-29 15:48:31 +00:00
if ( mface - > v4 )
2009-02-25 06:43:03 +00:00
uv3 . setValue ( tface - > uv [ 3 ] ) ;
2008-07-29 15:48:31 +00:00
}
else {
/* no texfaces, set COLLSION true and everything else FALSE */
mode = default_face_mode ;
transp = TF_SOLID ;
tile = 0 ;
2006-01-06 03:46:54 +00:00
}
2008-07-29 15:48:31 +00:00
/* get vertex colors */
if ( mcol ) {
/* we have vertex colors */
rgb0 = KX_Mcol2uint_new ( mcol [ 0 ] ) ;
rgb1 = KX_Mcol2uint_new ( mcol [ 1 ] ) ;
rgb2 = KX_Mcol2uint_new ( mcol [ 2 ] ) ;
2006-01-06 03:46:54 +00:00
2008-07-29 15:48:31 +00:00
if ( mface - > v4 )
rgb3 = KX_Mcol2uint_new ( mcol [ 3 ] ) ;
}
else {
/* no vertex colors, take from material, otherwise white */
unsigned int color = 0xFFFFFFFFL ;
2006-01-06 03:46:54 +00:00
2008-07-29 15:48:31 +00:00
if ( ma )
2002-10-12 11:37:38 +00:00
{
2008-07-29 15:48:31 +00:00
union
{
unsigned char cp [ 4 ] ;
unsigned int integer ;
} col_converter ;
2002-10-12 11:37:38 +00:00
2008-07-29 15:48:31 +00:00
col_converter . cp [ 3 ] = ( unsigned char ) ( ma - > r * 255.0 ) ;
col_converter . cp [ 2 ] = ( unsigned char ) ( ma - > g * 255.0 ) ;
col_converter . cp [ 1 ] = ( unsigned char ) ( ma - > b * 255.0 ) ;
col_converter . cp [ 0 ] = ( unsigned char ) ( ma - > alpha * 255.0 ) ;
2002-10-12 11:37:38 +00:00
2008-07-29 15:48:31 +00:00
color = col_converter . integer ;
2006-12-22 08:23:25 +00:00
}
2008-07-29 15:48:31 +00:00
rgb0 = KX_rgbaint2uint_new ( color ) ;
rgb1 = KX_rgbaint2uint_new ( color ) ;
rgb2 = KX_rgbaint2uint_new ( color ) ;
if ( mface - > v4 )
rgb3 = KX_rgbaint2uint_new ( color ) ;
}
// only zsort alpha + add
bool alpha = ( transp = = TF_ALPHA | | transp = = TF_ADD ) ;
bool zsort = ( mode & TF_ALPHASORT ) ? alpha : 0 ;
2009-04-29 10:06:38 +00:00
if ( kx_polymat = = NULL )
kx_polymat = new KX_PolygonMaterial ( ) ;
kx_polymat - > Initialize ( imastr , ma , ( int ) mface - > mat_nr ,
2008-07-29 15:48:31 +00:00
tile , tilexrep , tileyrep ,
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
mode , transp , alpha , zsort , lightlayer , tface , ( unsigned int * ) mcol ) ;
2009-04-29 10:06:38 +00:00
polymat = static_cast < RAS_IPolyMaterial * > ( kx_polymat ) ;
2006-12-22 08:23:25 +00:00
2008-07-29 15:48:31 +00:00
if ( ma ) {
polymat - > m_specular = MT_Vector3 ( ma - > specr , ma - > specg , ma - > specb ) * ma - > spec ;
polymat - > m_shininess = ( float ) ma - > har / 4.0 ; // 0 < ma->har <= 512
polymat - > m_diffuse = MT_Vector3 ( ma - > r , ma - > g , ma - > b ) * ( ma - > emit + ma - > ref ) ;
}
else {
2009-02-25 06:43:03 +00:00
polymat - > m_specular . setValue ( 0.0f , 0.0f , 0.0f ) ;
2008-07-29 15:48:31 +00:00
polymat - > m_shininess = 35.0 ;
}
}
2002-10-12 11:37:38 +00:00
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
/* mark face as flat, so vertices are split */
bool flat = ( mface - > flag & ME_SMOOTH ) = = 0 ;
2008-07-29 15:48:31 +00:00
// see if a bucket was reused or a new one was created
// this way only one KX_BlenderMaterial object has to exist per bucket
bool bucketCreated ;
RAS_MaterialBucket * bucket = scene - > FindBucket ( polymat , bucketCreated ) ;
if ( bucketCreated ) {
// this is needed to free up memory afterwards
converter - > RegisterPolyMaterial ( polymat ) ;
if ( converter - > GetMaterials ( ) ) {
converter - > RegisterBlenderMaterial ( bl_mat ) ;
2009-04-29 10:06:38 +00:00
// the poly material has been stored in the bucket, next time we must create a new one
bl_mat = NULL ;
kx_blmat = NULL ;
} else {
// the poly material has been stored in the bucket, next time we must create a new one
kx_polymat = NULL ;
2008-03-23 23:12:40 +00:00
}
2008-07-29 15:48:31 +00:00
} else {
// from now on, use the polygon material from the material bucket
polymat = bucket - > GetPolyMaterial ( ) ;
2009-04-29 10:06:38 +00:00
// keep the material pointers, they will be reused for next face
2008-07-29 15:48:31 +00:00
}
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
int nverts = ( mface - > v4 ) ? 4 : 3 ;
RAS_Polygon * poly = meshobj - > AddPolygon ( bucket , nverts ) ;
2008-07-10 12:47:20 +00:00
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
poly - > SetVisible ( visible ) ;
2008-07-29 15:48:31 +00:00
poly - > SetCollider ( collider ) ;
2009-04-13 20:08:33 +00:00
poly - > SetTwoside ( twoside ) ;
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
//poly->SetEdgeCode(mface->edcode);
meshobj - > AddVertex ( poly , 0 , pt0 , uv0 , uv20 , tan0 , rgb0 , no0 , flat , mface - > v1 ) ;
meshobj - > AddVertex ( poly , 1 , pt1 , uv1 , uv21 , tan1 , rgb1 , no1 , flat , mface - > v2 ) ;
meshobj - > AddVertex ( poly , 2 , pt2 , uv2 , uv22 , tan2 , rgb2 , no2 , flat , mface - > v3 ) ;
if ( nverts = = 4 )
meshobj - > AddVertex ( poly , 3 , pt3 , uv3 , uv23 , tan3 , rgb3 , no3 , flat , mface - > v4 ) ;
2002-10-12 11:37:38 +00:00
}
2008-07-29 15:48:31 +00:00
2004-05-16 12:52:08 +00:00
if ( tface )
tface + + ;
2008-07-29 15:48:31 +00:00
if ( mcol )
mcol + = 4 ;
2007-01-07 04:39:39 +00:00
for ( int lay = 0 ; lay < MAX_MTFACE ; lay + + )
{
MTF_localLayer & layer = layers [ lay ] ;
if ( layer . face = = 0 ) break ;
layer . face + + ;
}
2002-10-12 11:37:38 +00:00
}
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
meshobj - > m_sharedvertex_map . clear ( ) ;
2006-01-06 03:46:54 +00:00
// pre calculate texture generation
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
for ( list < RAS_MeshMaterial > : : iterator mit = meshobj - > GetFirstMaterial ( ) ;
2006-01-15 11:34:55 +00:00
mit ! = meshobj - > GetLastMaterial ( ) ; + + mit ) {
2009-05-23 14:46:43 +00:00
mit - > m_bucket - > GetPolyMaterial ( ) - > OnConstruction ( lightlayer ) ;
2006-01-15 11:34:55 +00:00
}
2006-02-13 05:45:32 +00:00
2007-01-07 04:39:39 +00:00
if ( layers )
delete [ ] layers ;
2008-07-29 15:48:31 +00:00
dm - > release ( dm ) ;
2009-04-29 10:06:38 +00:00
// cleanup material
if ( bl_mat )
delete bl_mat ;
if ( kx_blmat )
delete kx_blmat ;
if ( kx_polymat )
delete kx_polymat ;
2009-05-23 14:46:43 +00:00
converter - > RegisterGameMesh ( meshobj , mesh ) ;
2002-10-12 11:37:38 +00:00
return meshobj ;
}
static PHY_MaterialProps * CreateMaterialFromBlenderObject ( struct Object * blenderobject ,
KX_Scene * kxscene )
{
PHY_MaterialProps * materialProps = new PHY_MaterialProps ;
2005-01-16 06:02:06 +00:00
MT_assert ( materialProps & & " Create physics material properties failed " ) ;
2002-10-12 11:37:38 +00:00
Material * blendermat = give_current_material ( blenderobject , 0 ) ;
if ( blendermat )
{
2005-01-16 06:02:06 +00:00
MT_assert ( 0.0f < = blendermat - > reflect & & blendermat - > reflect < = 1.0f ) ;
2002-10-12 11:37:38 +00:00
materialProps - > m_restitution = blendermat - > reflect ;
materialProps - > m_friction = blendermat - > friction ;
materialProps - > m_fh_spring = blendermat - > fh ;
materialProps - > m_fh_damping = blendermat - > xyfrict ;
materialProps - > m_fh_distance = blendermat - > fhdist ;
materialProps - > m_fh_normal = ( blendermat - > dynamode & MA_FH_NOR ) ! = 0 ;
}
else {
2006-04-17 01:33:10 +00:00
//give some defaults
materialProps - > m_restitution = 0.f ;
materialProps - > m_friction = 0.5 ;
materialProps - > m_fh_spring = 0.f ;
materialProps - > m_fh_damping = 0.f ;
materialProps - > m_fh_distance = 0.f ;
materialProps - > m_fh_normal = false ;
2002-10-12 11:37:38 +00:00
}
return materialProps ;
}
static PHY_ShapeProps * CreateShapePropsFromBlenderObject ( struct Object * blenderobject ,
KX_Scene * kxscene )
{
PHY_ShapeProps * shapeProps = new PHY_ShapeProps ;
2005-01-16 06:02:06 +00:00
MT_assert ( shapeProps ) ;
2002-10-12 11:37:38 +00:00
shapeProps - > m_mass = blenderobject - > mass ;
// This needs to be fixed in blender. For now, we use:
// in Blender, inertia stands for the size value which is equivalent to
// the sphere radius
2004-04-16 06:26:33 +00:00
shapeProps - > m_inertia = blenderobject - > formfactor ;
2002-10-12 11:37:38 +00:00
2005-01-16 06:02:06 +00:00
MT_assert ( 0.0f < = blenderobject - > damping & & blenderobject - > damping < = 1.0f ) ;
MT_assert ( 0.0f < = blenderobject - > rdamping & & blenderobject - > rdamping < = 1.0f ) ;
2002-10-12 11:37:38 +00:00
shapeProps - > m_lin_drag = 1.0 - blenderobject - > damping ;
shapeProps - > m_ang_drag = 1.0 - blenderobject - > rdamping ;
shapeProps - > m_friction_scaling [ 0 ] = blenderobject - > anisotropicFriction [ 0 ] ;
shapeProps - > m_friction_scaling [ 1 ] = blenderobject - > anisotropicFriction [ 1 ] ;
shapeProps - > m_friction_scaling [ 2 ] = blenderobject - > anisotropicFriction [ 2 ] ;
shapeProps - > m_do_anisotropic = ( ( blenderobject - > gameflag & OB_ANISOTROPIC_FRICTION ) ! = 0 ) ;
shapeProps - > m_do_fh = ( blenderobject - > gameflag & OB_DO_FH ) ! = 0 ;
shapeProps - > m_do_rot_fh = ( blenderobject - > gameflag & OB_ROT_FH ) ! = 0 ;
2009-04-14 12:34:39 +00:00
// velocity clamping XXX
shapeProps - > m_clamp_vel_min = blenderobject - > min_vel ;
shapeProps - > m_clamp_vel_max = blenderobject - > max_vel ;
2002-10-12 11:37:38 +00:00
return shapeProps ;
}
//////////////////////////////////////////////////////////
2004-07-16 00:08:06 +00:00
static float my_boundbox_mesh ( Mesh * me , float * loc , float * size )
2004-05-21 09:21:15 +00:00
{
2002-10-12 11:37:38 +00:00
MVert * mvert ;
BoundBox * bb ;
2004-05-21 09:21:15 +00:00
MT_Point3 min , max ;
2002-10-12 11:37:38 +00:00
float mloc [ 3 ] , msize [ 3 ] ;
2009-04-08 17:40:09 +00:00
float radius = 0.0f , vert_radius , * co ;
2002-10-12 11:37:38 +00:00
int a ;
if ( me - > bb = = 0 ) me - > bb = ( struct BoundBox * ) MEM_callocN ( sizeof ( BoundBox ) , " boundbox " ) ;
bb = me - > bb ;
INIT_MINMAX ( min , max ) ;
if ( ! loc ) loc = mloc ;
if ( ! size ) size = msize ;
mvert = me - > mvert ;
for ( a = 0 ; a < me - > totvert ; a + + , mvert + + ) {
2009-04-08 17:40:09 +00:00
co = mvert - > co ;
/* bounds */
DO_MINMAX ( co , min , max ) ;
/* radius */
vert_radius = co [ 0 ] * co [ 0 ] + co [ 1 ] * co [ 1 ] + co [ 2 ] * co [ 2 ] ;
if ( vert_radius > radius )
radius = vert_radius ;
2004-05-21 09:21:15 +00:00
}
2002-10-12 11:37:38 +00:00
if ( me - > totvert ) {
loc [ 0 ] = ( min [ 0 ] + max [ 0 ] ) / 2.0 ;
loc [ 1 ] = ( min [ 1 ] + max [ 1 ] ) / 2.0 ;
loc [ 2 ] = ( min [ 2 ] + max [ 2 ] ) / 2.0 ;
size [ 0 ] = ( max [ 0 ] - min [ 0 ] ) / 2.0 ;
size [ 1 ] = ( max [ 1 ] - min [ 1 ] ) / 2.0 ;
size [ 2 ] = ( max [ 2 ] - min [ 2 ] ) / 2.0 ;
}
else {
loc [ 0 ] = loc [ 1 ] = loc [ 2 ] = 0.0 ;
size [ 0 ] = size [ 1 ] = size [ 2 ] = 0.0 ;
}
bb - > vec [ 0 ] [ 0 ] = bb - > vec [ 1 ] [ 0 ] = bb - > vec [ 2 ] [ 0 ] = bb - > vec [ 3 ] [ 0 ] = loc [ 0 ] - size [ 0 ] ;
bb - > vec [ 4 ] [ 0 ] = bb - > vec [ 5 ] [ 0 ] = bb - > vec [ 6 ] [ 0 ] = bb - > vec [ 7 ] [ 0 ] = loc [ 0 ] + size [ 0 ] ;
bb - > vec [ 0 ] [ 1 ] = bb - > vec [ 1 ] [ 1 ] = bb - > vec [ 4 ] [ 1 ] = bb - > vec [ 5 ] [ 1 ] = loc [ 1 ] - size [ 1 ] ;
bb - > vec [ 2 ] [ 1 ] = bb - > vec [ 3 ] [ 1 ] = bb - > vec [ 6 ] [ 1 ] = bb - > vec [ 7 ] [ 1 ] = loc [ 1 ] + size [ 1 ] ;
bb - > vec [ 0 ] [ 2 ] = bb - > vec [ 3 ] [ 2 ] = bb - > vec [ 4 ] [ 2 ] = bb - > vec [ 7 ] [ 2 ] = loc [ 2 ] - size [ 2 ] ;
bb - > vec [ 1 ] [ 2 ] = bb - > vec [ 2 ] [ 2 ] = bb - > vec [ 5 ] [ 2 ] = bb - > vec [ 6 ] [ 2 ] = loc [ 2 ] + size [ 2 ] ;
2004-05-21 09:21:15 +00:00
return sqrt ( radius ) ;
}
2002-10-12 11:37:38 +00:00
2004-07-16 00:08:06 +00:00
static void my_tex_space_mesh ( Mesh * me )
2002-10-12 11:37:38 +00:00
{
KeyBlock * kb ;
float * fp , loc [ 3 ] , size [ 3 ] , min [ 3 ] , max [ 3 ] ;
int a ;
my_boundbox_mesh ( me , loc , size ) ;
2004-03-22 22:02:18 +00:00
if ( me - > texflag & AUTOSPACE ) {
2002-10-12 11:37:38 +00:00
if ( me - > key ) {
kb = me - > key - > refkey ;
if ( kb ) {
INIT_MINMAX ( min , max ) ;
fp = ( float * ) kb - > data ;
for ( a = 0 ; a < kb - > totelem ; a + + , fp + = 3 ) {
DO_MINMAX ( fp , min , max ) ;
}
if ( kb - > totelem ) {
loc [ 0 ] = ( min [ 0 ] + max [ 0 ] ) / 2.0 ; loc [ 1 ] = ( min [ 1 ] + max [ 1 ] ) / 2.0 ; loc [ 2 ] = ( min [ 2 ] + max [ 2 ] ) / 2.0 ;
size [ 0 ] = ( max [ 0 ] - min [ 0 ] ) / 2.0 ; size [ 1 ] = ( max [ 1 ] - min [ 1 ] ) / 2.0 ; size [ 2 ] = ( max [ 2 ] - min [ 2 ] ) / 2.0 ;
}
else {
loc [ 0 ] = loc [ 1 ] = loc [ 2 ] = 0.0 ;
size [ 0 ] = size [ 1 ] = size [ 2 ] = 0.0 ;
}
}
}
VECCOPY ( me - > loc , loc ) ;
VECCOPY ( me - > size , size ) ;
me - > rot [ 0 ] = me - > rot [ 1 ] = me - > rot [ 2 ] = 0.0 ;
if ( me - > size [ 0 ] = = 0.0 ) me - > size [ 0 ] = 1.0 ;
else if ( me - > size [ 0 ] > 0.0 & & me - > size [ 0 ] < 0.00001 ) me - > size [ 0 ] = 0.00001 ;
else if ( me - > size [ 0 ] < 0.0 & & me - > size [ 0 ] > - 0.00001 ) me - > size [ 0 ] = - 0.00001 ;
if ( me - > size [ 1 ] = = 0.0 ) me - > size [ 1 ] = 1.0 ;
else if ( me - > size [ 1 ] > 0.0 & & me - > size [ 1 ] < 0.00001 ) me - > size [ 1 ] = 0.00001 ;
else if ( me - > size [ 1 ] < 0.0 & & me - > size [ 1 ] > - 0.00001 ) me - > size [ 1 ] = - 0.00001 ;
if ( me - > size [ 2 ] = = 0.0 ) me - > size [ 2 ] = 1.0 ;
else if ( me - > size [ 2 ] > 0.0 & & me - > size [ 2 ] < 0.00001 ) me - > size [ 2 ] = 0.00001 ;
else if ( me - > size [ 2 ] < 0.0 & & me - > size [ 2 ] > - 0.00001 ) me - > size [ 2 ] = - 0.00001 ;
}
}
2009-05-14 13:47:08 +00:00
static void my_get_local_bounds ( Object * ob , DerivedMesh * dm , float * center , float * size )
2004-05-16 12:52:08 +00:00
{
2002-10-12 11:37:38 +00:00
BoundBox * bb = NULL ;
/* uses boundbox, function used by Ketsji */
2004-07-16 00:08:06 +00:00
switch ( ob - > type )
{
case OB_MESH :
2009-05-14 13:47:08 +00:00
if ( dm )
{
float min_r [ 3 ] , max_r [ 3 ] ;
INIT_MINMAX ( min_r , max_r ) ;
dm - > getMinMax ( dm , min_r , max_r ) ;
size [ 0 ] = 0.5 * fabs ( max_r [ 0 ] - min_r [ 0 ] ) ;
size [ 1 ] = 0.5 * fabs ( max_r [ 1 ] - min_r [ 1 ] ) ;
size [ 2 ] = 0.5 * fabs ( max_r [ 2 ] - min_r [ 2 ] ) ;
center [ 0 ] = 0.5 * ( max_r [ 0 ] + min_r [ 0 ] ) ;
center [ 1 ] = 0.5 * ( max_r [ 1 ] + min_r [ 1 ] ) ;
center [ 2 ] = 0.5 * ( max_r [ 2 ] + min_r [ 2 ] ) ;
return ;
} else
2004-07-16 00:08:06 +00:00
{
bb = ( ( Mesh * ) ob - > data ) - > bb ;
2009-05-14 13:47:08 +00:00
if ( bb = = 0 )
{
my_tex_space_mesh ( ( struct Mesh * ) ob - > data ) ;
bb = ( ( Mesh * ) ob - > data ) - > bb ;
}
2004-07-16 00:08:06 +00:00
}
break ;
case OB_CURVE :
case OB_SURF :
case OB_FONT :
2007-04-04 13:18:41 +00:00
center [ 0 ] = center [ 1 ] = center [ 2 ] = 0.0 ;
2004-07-16 00:08:06 +00:00
size [ 0 ] = size [ 1 ] = size [ 2 ] = 0.0 ;
break ;
case OB_MBALL :
bb = ob - > bb ;
break ;
2002-10-12 11:37:38 +00:00
}
2004-07-16 00:08:06 +00:00
if ( bb = = NULL )
{
2007-04-04 13:18:41 +00:00
center [ 0 ] = center [ 1 ] = center [ 2 ] = 0.0 ;
2004-07-16 00:08:06 +00:00
size [ 0 ] = size [ 1 ] = size [ 2 ] = 1.0 ;
2002-10-12 11:37:38 +00:00
}
2004-07-16 00:08:06 +00:00
else
{
2002-10-12 11:37:38 +00:00
size [ 0 ] = 0.5 * fabs ( bb - > vec [ 0 ] [ 0 ] - bb - > vec [ 4 ] [ 0 ] ) ;
size [ 1 ] = 0.5 * fabs ( bb - > vec [ 0 ] [ 1 ] - bb - > vec [ 2 ] [ 1 ] ) ;
size [ 2 ] = 0.5 * fabs ( bb - > vec [ 0 ] [ 2 ] - bb - > vec [ 1 ] [ 2 ] ) ;
2007-04-04 13:18:41 +00:00
center [ 0 ] = 0.5 * ( bb - > vec [ 0 ] [ 0 ] + bb - > vec [ 4 ] [ 0 ] ) ;
center [ 1 ] = 0.5 * ( bb - > vec [ 0 ] [ 1 ] + bb - > vec [ 2 ] [ 1 ] ) ;
center [ 2 ] = 0.5 * ( bb - > vec [ 0 ] [ 2 ] + bb - > vec [ 1 ] [ 2 ] ) ;
2004-07-16 00:08:06 +00:00
}
2002-10-12 11:37:38 +00:00
}
//////////////////////////////////////////////////////
2009-04-07 22:14:06 +00:00
void BL_CreateGraphicObjectNew ( KX_GameObject * gameobj ,
const MT_Point3 & localAabbMin ,
const MT_Point3 & localAabbMax ,
KX_Scene * kxscene ,
bool isActive ,
e_PhysicsEngine physics_engine )
{
if ( gameobj - > GetMeshCount ( ) > 0 )
{
switch ( physics_engine )
{
# ifdef USE_BULLET
case UseBullet :
{
CcdPhysicsEnvironment * env = ( CcdPhysicsEnvironment * ) kxscene - > GetPhysicsEnvironment ( ) ;
assert ( env ) ;
PHY_IMotionState * motionstate = new KX_MotionState ( gameobj - > GetSGNode ( ) ) ;
CcdGraphicController * ctrl = new CcdGraphicController ( env , motionstate ) ;
gameobj - > SetGraphicController ( ctrl ) ;
ctrl - > setNewClientInfo ( gameobj - > getClientInfo ( ) ) ;
ctrl - > setLocalAabb ( localAabbMin , localAabbMax ) ;
2009-04-25 12:20:59 +00:00
if ( isActive ) {
2009-05-29 17:09:20 +00:00
// add first, this will create the proxy handle, only if the object is visible
if ( gameobj - > GetVisible ( ) )
env - > addCcdGraphicController ( ctrl ) ;
2009-04-25 12:20:59 +00:00
// update the mesh if there is a deformer, this will also update the bounding box for modifiers
RAS_Deformer * deformer = gameobj - > GetDeformer ( ) ;
if ( deformer )
deformer - > UpdateBuckets ( ) ;
}
2009-04-07 22:14:06 +00:00
}
break ;
# endif
default :
break ;
}
}
}
2002-10-12 11:37:38 +00:00
void BL_CreatePhysicsObjectNew ( KX_GameObject * gameobj ,
struct Object * blenderobject ,
RAS_MeshObject * meshobj ,
KX_Scene * kxscene ,
int activeLayerBitInfo ,
e_PhysicsEngine physics_engine ,
2006-12-01 01:04:27 +00:00
KX_BlenderSceneConverter * converter ,
bool processCompoundChildren
2002-10-12 11:37:38 +00:00
)
2004-04-24 06:40:15 +00:00
{
2005-03-09 19:45:59 +00:00
//SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
2002-10-12 11:37:38 +00:00
//int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
//bool bRigidBody = (userigidbody == 0);
BGE patch: new Physics button and margin parameter in Logic panel. Change subversion.
The Physics button controls the creation of a physics representation
of the object when starting the game. If the button is not selected,
the object is a pure graphical object with no physics representation
and all the other physics buttons are hidden.
Selecting this button gives access to the usual physics buttons.
The physics button is enabled by default to match previous Blender
behavior.
The margin parameter allows to control the collision margin from
the UI. Previously, this parameter was only accessible through
Python. By default, the collision margin is set to 0.0 on static
objects and 0.06 on dynamic objects.
To maintain compatibility with older games, the collision margin
is set to 0.06 on all objects when loading older blend file.
Note about the collision algorithms in Bullet 2.71
--------------------------------------------------
Bullet 2.71 handles the collision margin differently than Bullet 2.53
(the previous Bullet version in Blender). The collision margin is
now kept "inside" the object for box, sphere and cylinder bound
shapes. This means that two objects bound to any of these shape will
come in close contact when colliding.
The static mesh, convex hull and cone shapes still have their
collision margin "outside" the object, which leaves a space of 1
or 2 times the collision margin between objects.
The situation with Bullet 2.53 was more complicated, generally
leading to more space between objects, except for box-box collisions.
This means that running a old game under Bullet 2.71 may cause
visual problems, especially if the objects are small. You can fix
these problems by changing some visual aspect of the objects:
center, shape, size, position of children, etc.
2008-09-14 19:34:06 +00:00
// object has physics representation?
2008-09-16 22:52:42 +00:00
if ( ! ( blenderobject - > gameflag & OB_COLLISION ) )
BGE patch: new Physics button and margin parameter in Logic panel. Change subversion.
The Physics button controls the creation of a physics representation
of the object when starting the game. If the button is not selected,
the object is a pure graphical object with no physics representation
and all the other physics buttons are hidden.
Selecting this button gives access to the usual physics buttons.
The physics button is enabled by default to match previous Blender
behavior.
The margin parameter allows to control the collision margin from
the UI. Previously, this parameter was only accessible through
Python. By default, the collision margin is set to 0.0 on static
objects and 0.06 on dynamic objects.
To maintain compatibility with older games, the collision margin
is set to 0.06 on all objects when loading older blend file.
Note about the collision algorithms in Bullet 2.71
--------------------------------------------------
Bullet 2.71 handles the collision margin differently than Bullet 2.53
(the previous Bullet version in Blender). The collision margin is
now kept "inside" the object for box, sphere and cylinder bound
shapes. This means that two objects bound to any of these shape will
come in close contact when colliding.
The static mesh, convex hull and cone shapes still have their
collision margin "outside" the object, which leaves a space of 1
or 2 times the collision margin between objects.
The situation with Bullet 2.53 was more complicated, generally
leading to more space between objects, except for box-box collisions.
This means that running a old game under Bullet 2.71 may cause
visual problems, especially if the objects are small. You can fix
these problems by changing some visual aspect of the objects:
center, shape, size, position of children, etc.
2008-09-14 19:34:06 +00:00
return ;
2006-12-01 01:04:27 +00:00
// get Root Parent of blenderobject
struct Object * parent = blenderobject - > parent ;
while ( parent & & parent - > parent ) {
parent = parent - > parent ;
}
bool isCompoundChild = false ;
BGE: user control to compound shape and setParent.
Compound shape control
======================
1) GUI control
It is now possible to control which child shape is added to
a parent compound shape in the Physics buttons. The "Compound"
shape button becomes "Add to parent" on child objects and
determines whether the child shape is to be added to the top
parent compound shape when the game is stated.
Notes: * "Compound" is only available to top parent objects
(objects without parent).
* Nesting of compound shape is not possible: a child
object with "Add to parent" button set will be added
to the top parent compound shape, regardless of its
position in the parent-child hierarchy and even if its
immediate parent doesn't have the "Add to parent" button set.
2) runtime control
It is now possible to control the compound shape at runtime:
The SetParent actuator has a new "Compound" button that indicates
whether the object shape should be added to the compound shape
of the parent object, provided the parent has a compound shape
of course. If not, the object retain it's individual state
while parented.
Similarly, the KX_GameObject.setParent() python function has
a new compound parameter.
Notes: * When an object is dynamically added to a compound
shape, it looses temporarily all its physics capability
to the benefit of the parent: it cannot register collisions
and the characteristics of its shape are lost (ghost, sensor,
dynamic, etc.).
* Nested compound shape is not supported: if the object
being parented is already a compound shape, it is not
added to the compound parent (as if the Compound option
was not set in the actuator or the setParent function).
* To ensure compatibility with old blend files, the Blender
subversion is changed to 2.48.5 and the old blend files
are automatically converted to match the old behavior:
all children of a Compound object will have the "Add to
parent" button set automatically.
Child ghost control
===================
It is now possible to control if an object should becomes ghost
or solid when parented. This is only applicable if the object
is not added to the parent compound shape (see above).
A new "Ghost" button is available on the SetParent actuator to
that effect. Similarly the KX_GameObject.setParent() python function
has a new compound parameter.
Notes: * This option is not applicable to sensor objects: they stay
ghost all the time.
* Make sure the child object does not enter in collision with
the parent shape when the Ghost option if off and the parent is
dynamic: the collision creates a reaction force but the parent
cannot escape the child, so the force builds up and produces
eratic movements.
* The collision capability of an ordinary object (dynamic or static)
is limited when it is parented: it becomes automatically static
and can only detect dynamic and sensor objects.
* A sensor object retain its full collision capability when parented:
it can detect static and dynamic object.
Python control
==============
KX_GameObject.setParent(parent,compound,ghost):
Sets this object's parent.
Control the shape status with the optional compound and ghost parameters:
compound=1: the object shape should be added to the parent compound shape (default)
compound=0: the object should keep its individual shape.
In that case you can control if it should be ghost or not:
ghost=1 if the object should be made ghost while parented (default)
ghost=0 if the object should be solid while parented
Note: if the object type is sensor, it stays ghost regardless of ghost parameter
parent: KX_GameObject reference or string (object name w/o OB prefix)
2009-05-21 13:32:15 +00:00
bool hasCompoundChildren = ! parent & & ( blenderobject - > gameflag & OB_CHILD ) ;
2006-12-01 01:04:27 +00:00
BGE: user control to compound shape and setParent.
Compound shape control
======================
1) GUI control
It is now possible to control which child shape is added to
a parent compound shape in the Physics buttons. The "Compound"
shape button becomes "Add to parent" on child objects and
determines whether the child shape is to be added to the top
parent compound shape when the game is stated.
Notes: * "Compound" is only available to top parent objects
(objects without parent).
* Nesting of compound shape is not possible: a child
object with "Add to parent" button set will be added
to the top parent compound shape, regardless of its
position in the parent-child hierarchy and even if its
immediate parent doesn't have the "Add to parent" button set.
2) runtime control
It is now possible to control the compound shape at runtime:
The SetParent actuator has a new "Compound" button that indicates
whether the object shape should be added to the compound shape
of the parent object, provided the parent has a compound shape
of course. If not, the object retain it's individual state
while parented.
Similarly, the KX_GameObject.setParent() python function has
a new compound parameter.
Notes: * When an object is dynamically added to a compound
shape, it looses temporarily all its physics capability
to the benefit of the parent: it cannot register collisions
and the characteristics of its shape are lost (ghost, sensor,
dynamic, etc.).
* Nested compound shape is not supported: if the object
being parented is already a compound shape, it is not
added to the compound parent (as if the Compound option
was not set in the actuator or the setParent function).
* To ensure compatibility with old blend files, the Blender
subversion is changed to 2.48.5 and the old blend files
are automatically converted to match the old behavior:
all children of a Compound object will have the "Add to
parent" button set automatically.
Child ghost control
===================
It is now possible to control if an object should becomes ghost
or solid when parented. This is only applicable if the object
is not added to the parent compound shape (see above).
A new "Ghost" button is available on the SetParent actuator to
that effect. Similarly the KX_GameObject.setParent() python function
has a new compound parameter.
Notes: * This option is not applicable to sensor objects: they stay
ghost all the time.
* Make sure the child object does not enter in collision with
the parent shape when the Ghost option if off and the parent is
dynamic: the collision creates a reaction force but the parent
cannot escape the child, so the force builds up and produces
eratic movements.
* The collision capability of an ordinary object (dynamic or static)
is limited when it is parented: it becomes automatically static
and can only detect dynamic and sensor objects.
* A sensor object retain its full collision capability when parented:
it can detect static and dynamic object.
Python control
==============
KX_GameObject.setParent(parent,compound,ghost):
Sets this object's parent.
Control the shape status with the optional compound and ghost parameters:
compound=1: the object shape should be added to the parent compound shape (default)
compound=0: the object should keep its individual shape.
In that case you can control if it should be ghost or not:
ghost=1 if the object should be made ghost while parented (default)
ghost=0 if the object should be solid while parented
Note: if the object type is sensor, it stays ghost regardless of ghost parameter
parent: KX_GameObject reference or string (object name w/o OB prefix)
2009-05-21 13:32:15 +00:00
if ( parent /* && (parent->gameflag & OB_DYNAMIC)*/ ) {
2006-12-01 01:04:27 +00:00
BGE: user control to compound shape and setParent.
Compound shape control
======================
1) GUI control
It is now possible to control which child shape is added to
a parent compound shape in the Physics buttons. The "Compound"
shape button becomes "Add to parent" on child objects and
determines whether the child shape is to be added to the top
parent compound shape when the game is stated.
Notes: * "Compound" is only available to top parent objects
(objects without parent).
* Nesting of compound shape is not possible: a child
object with "Add to parent" button set will be added
to the top parent compound shape, regardless of its
position in the parent-child hierarchy and even if its
immediate parent doesn't have the "Add to parent" button set.
2) runtime control
It is now possible to control the compound shape at runtime:
The SetParent actuator has a new "Compound" button that indicates
whether the object shape should be added to the compound shape
of the parent object, provided the parent has a compound shape
of course. If not, the object retain it's individual state
while parented.
Similarly, the KX_GameObject.setParent() python function has
a new compound parameter.
Notes: * When an object is dynamically added to a compound
shape, it looses temporarily all its physics capability
to the benefit of the parent: it cannot register collisions
and the characteristics of its shape are lost (ghost, sensor,
dynamic, etc.).
* Nested compound shape is not supported: if the object
being parented is already a compound shape, it is not
added to the compound parent (as if the Compound option
was not set in the actuator or the setParent function).
* To ensure compatibility with old blend files, the Blender
subversion is changed to 2.48.5 and the old blend files
are automatically converted to match the old behavior:
all children of a Compound object will have the "Add to
parent" button set automatically.
Child ghost control
===================
It is now possible to control if an object should becomes ghost
or solid when parented. This is only applicable if the object
is not added to the parent compound shape (see above).
A new "Ghost" button is available on the SetParent actuator to
that effect. Similarly the KX_GameObject.setParent() python function
has a new compound parameter.
Notes: * This option is not applicable to sensor objects: they stay
ghost all the time.
* Make sure the child object does not enter in collision with
the parent shape when the Ghost option if off and the parent is
dynamic: the collision creates a reaction force but the parent
cannot escape the child, so the force builds up and produces
eratic movements.
* The collision capability of an ordinary object (dynamic or static)
is limited when it is parented: it becomes automatically static
and can only detect dynamic and sensor objects.
* A sensor object retain its full collision capability when parented:
it can detect static and dynamic object.
Python control
==============
KX_GameObject.setParent(parent,compound,ghost):
Sets this object's parent.
Control the shape status with the optional compound and ghost parameters:
compound=1: the object shape should be added to the parent compound shape (default)
compound=0: the object should keep its individual shape.
In that case you can control if it should be ghost or not:
ghost=1 if the object should be made ghost while parented (default)
ghost=0 if the object should be solid while parented
Note: if the object type is sensor, it stays ghost regardless of ghost parameter
parent: KX_GameObject reference or string (object name w/o OB prefix)
2009-05-21 13:32:15 +00:00
if ( ( parent - > gameflag & OB_CHILD ) ! = 0 & & ( blenderobject - > gameflag & OB_CHILD ) )
2006-12-01 01:04:27 +00:00
{
isCompoundChild = true ;
}
}
if ( processCompoundChildren ! = isCompoundChild )
return ;
2002-10-12 11:37:38 +00:00
PHY_ShapeProps * shapeprops =
CreateShapePropsFromBlenderObject ( blenderobject ,
kxscene ) ;
PHY_MaterialProps * smmaterial =
CreateMaterialFromBlenderObject ( blenderobject , kxscene ) ;
KX_ObjectProperties objprop ;
2009-03-09 07:12:16 +00:00
objprop . m_lockXaxis = ( blenderobject - > gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS ) ! = 0 ;
objprop . m_lockYaxis = ( blenderobject - > gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS ) ! = 0 ;
objprop . m_lockZaxis = ( blenderobject - > gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS ) ! = 0 ;
objprop . m_lockXRotaxis = ( blenderobject - > gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS ) ! = 0 ;
objprop . m_lockYRotaxis = ( blenderobject - > gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS ) ! = 0 ;
objprop . m_lockZRotaxis = ( blenderobject - > gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS ) ! = 0 ;
2006-12-01 01:04:27 +00:00
objprop . m_isCompoundChild = isCompoundChild ;
BGE: user control to compound shape and setParent.
Compound shape control
======================
1) GUI control
It is now possible to control which child shape is added to
a parent compound shape in the Physics buttons. The "Compound"
shape button becomes "Add to parent" on child objects and
determines whether the child shape is to be added to the top
parent compound shape when the game is stated.
Notes: * "Compound" is only available to top parent objects
(objects without parent).
* Nesting of compound shape is not possible: a child
object with "Add to parent" button set will be added
to the top parent compound shape, regardless of its
position in the parent-child hierarchy and even if its
immediate parent doesn't have the "Add to parent" button set.
2) runtime control
It is now possible to control the compound shape at runtime:
The SetParent actuator has a new "Compound" button that indicates
whether the object shape should be added to the compound shape
of the parent object, provided the parent has a compound shape
of course. If not, the object retain it's individual state
while parented.
Similarly, the KX_GameObject.setParent() python function has
a new compound parameter.
Notes: * When an object is dynamically added to a compound
shape, it looses temporarily all its physics capability
to the benefit of the parent: it cannot register collisions
and the characteristics of its shape are lost (ghost, sensor,
dynamic, etc.).
* Nested compound shape is not supported: if the object
being parented is already a compound shape, it is not
added to the compound parent (as if the Compound option
was not set in the actuator or the setParent function).
* To ensure compatibility with old blend files, the Blender
subversion is changed to 2.48.5 and the old blend files
are automatically converted to match the old behavior:
all children of a Compound object will have the "Add to
parent" button set automatically.
Child ghost control
===================
It is now possible to control if an object should becomes ghost
or solid when parented. This is only applicable if the object
is not added to the parent compound shape (see above).
A new "Ghost" button is available on the SetParent actuator to
that effect. Similarly the KX_GameObject.setParent() python function
has a new compound parameter.
Notes: * This option is not applicable to sensor objects: they stay
ghost all the time.
* Make sure the child object does not enter in collision with
the parent shape when the Ghost option if off and the parent is
dynamic: the collision creates a reaction force but the parent
cannot escape the child, so the force builds up and produces
eratic movements.
* The collision capability of an ordinary object (dynamic or static)
is limited when it is parented: it becomes automatically static
and can only detect dynamic and sensor objects.
* A sensor object retain its full collision capability when parented:
it can detect static and dynamic object.
Python control
==============
KX_GameObject.setParent(parent,compound,ghost):
Sets this object's parent.
Control the shape status with the optional compound and ghost parameters:
compound=1: the object shape should be added to the parent compound shape (default)
compound=0: the object should keep its individual shape.
In that case you can control if it should be ghost or not:
ghost=1 if the object should be made ghost while parented (default)
ghost=0 if the object should be solid while parented
Note: if the object type is sensor, it stays ghost regardless of ghost parameter
parent: KX_GameObject reference or string (object name w/o OB prefix)
2009-05-21 13:32:15 +00:00
objprop . m_hasCompoundChildren = hasCompoundChildren ;
BGE patch: new Physics button and margin parameter in Logic panel. Change subversion.
The Physics button controls the creation of a physics representation
of the object when starting the game. If the button is not selected,
the object is a pure graphical object with no physics representation
and all the other physics buttons are hidden.
Selecting this button gives access to the usual physics buttons.
The physics button is enabled by default to match previous Blender
behavior.
The margin parameter allows to control the collision margin from
the UI. Previously, this parameter was only accessible through
Python. By default, the collision margin is set to 0.0 on static
objects and 0.06 on dynamic objects.
To maintain compatibility with older games, the collision margin
is set to 0.06 on all objects when loading older blend file.
Note about the collision algorithms in Bullet 2.71
--------------------------------------------------
Bullet 2.71 handles the collision margin differently than Bullet 2.53
(the previous Bullet version in Blender). The collision margin is
now kept "inside" the object for box, sphere and cylinder bound
shapes. This means that two objects bound to any of these shape will
come in close contact when colliding.
The static mesh, convex hull and cone shapes still have their
collision margin "outside" the object, which leaves a space of 1
or 2 times the collision margin between objects.
The situation with Bullet 2.53 was more complicated, generally
leading to more space between objects, except for box-box collisions.
This means that running a old game under Bullet 2.71 may cause
visual problems, especially if the objects are small. You can fix
these problems by changing some visual aspect of the objects:
center, shape, size, position of children, etc.
2008-09-14 19:34:06 +00:00
objprop . m_margin = blenderobject - > margin ;
2009-05-23 22:35:47 +00:00
2008-09-19 20:41:38 +00:00
// ACTOR is now a separate feature
objprop . m_isactor = ( blenderobject - > gameflag & OB_ACTOR ) ! = 0 ;
objprop . m_dyna = ( blenderobject - > gameflag & OB_DYNAMIC ) ! = 0 ;
2008-09-21 15:17:50 +00:00
objprop . m_softbody = ( blenderobject - > gameflag & OB_SOFT_BODY ) ! = 0 ;
2008-09-19 20:41:38 +00:00
objprop . m_angular_rigidbody = ( blenderobject - > gameflag & OB_RIGID_BODY ) ! = 0 ;
2009-05-23 22:35:47 +00:00
///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
if ( objprop . m_angular_rigidbody | | ! objprop . m_dyna )
{
2009-05-24 06:31:47 +00:00
objprop . m_contactProcessingThreshold = blenderobject - > m_contactProcessingThreshold ;
2009-05-23 22:35:47 +00:00
} else
{
objprop . m_contactProcessingThreshold = 0.f ;
}
BGE: new sensor object to generalize Near and Radar sensor, static-static collision capbility.
A new type of "Sensor" physics object is available in the GE for advanced
collision management. It's called Sensor for its similarities with the
physics objects that underlie the Near and Radar sensors.
Like the Near and Radar object it is:
- static and ghost
- invisible by default
- always active to ensure correct collision detection
- capable of detecting both static and dynamic objects
- ignoring collision with their parent
- capable of broadphase filtering based on:
* Actor option: the collisioning object must have the Actor flag set to be detected
* property/material: as specified in the collision sensors attached to it
Broadphase filtering is important for performance reason: the collision points
will be computed only for the objects that pass the broahphase filter.
- automatically removed from the simulation when no collision sensor is active on it
Unlike the Near and Radar object it can:
- take any shape, including triangle mesh
- be made visible for debugging (just use the Visible actuator)
- have multiple collision sensors using it
Other than that, the sensor objects are ordinary objects. You can move them
freely or parent them. When parented to a dynamic object, they can provide
advanced collision control to this object.
The type of collision capability depends on the shape:
- box, sphere, cylinder, cone, convex hull provide volume detection.
- triangle mesh provides surface detection but you can give some volume
to the suface by increasing the margin in the Advanced Settings panel.
The margin applies on both sides of the surface.
Performance tip:
- Sensor objects perform better than Near and Radar: they do less synchronizations
because of the Scenegraph optimizations and they can have multiple collision sensors
on them (with different property filtering for example).
- Always prefer simple shape (box, sphere) to complex shape whenever possible.
- Always use broadphase filtering (avoid collision sensor with empty propery/material)
- Use collision sensor only when you need them. When no collision sensor is active
on the sensor object, it is removed from the simulation and consume no CPU.
Known limitations:
- When running Blender in debug mode, you will see one warning line of the console:
"warning btCollisionDispatcher::needsCollision: static-static collision!"
In release mode this message is not printed.
- Collision margin has no effect on sphere, cone and cylinder shape.
Other performance improvements:
- Remove unnecessary interpolation for Near and Radar objects and by extension
sensor objects.
- Use direct matrix copy instead of quaternion to synchronize orientation.
Other bug fix:
- Fix Near/Radar position error on newly activated objects. This was causing
several detection problems in YoFrankie
- Fix margin not passed correctly to gImpact shape.
- Disable force/velocity actions on static objects
2009-05-17 12:51:51 +00:00
objprop . m_sensor = ( blenderobject - > gameflag & OB_SENSOR ) ! = 0 ;
2008-09-25 03:02:30 +00:00
2008-09-28 03:07:13 +00:00
if ( objprop . m_softbody )
2008-09-25 16:48:25 +00:00
{
2008-09-28 03:07:13 +00:00
///for game soft bodies
if ( blenderobject - > bsoft )
{
objprop . m_gamesoftFlag = blenderobject - > bsoft - > flag ;
///////////////////
objprop . m_soft_linStiff = blenderobject - > bsoft - > linStiff ;
objprop . m_soft_angStiff = blenderobject - > bsoft - > angStiff ; /* angular stiffness 0..1 */
objprop . m_soft_volume = blenderobject - > bsoft - > volume ; /* volume preservation 0..1 */
objprop . m_soft_viterations = blenderobject - > bsoft - > viterations ; /* Velocities solver iterations */
objprop . m_soft_piterations = blenderobject - > bsoft - > piterations ; /* Positions solver iterations */
objprop . m_soft_diterations = blenderobject - > bsoft - > diterations ; /* Drift solver iterations */
objprop . m_soft_citerations = blenderobject - > bsoft - > citerations ; /* Cluster solver iterations */
objprop . m_soft_kSRHR_CL = blenderobject - > bsoft - > kSRHR_CL ; /* Soft vs rigid hardness [0,1] (cluster only) */
objprop . m_soft_kSKHR_CL = blenderobject - > bsoft - > kSKHR_CL ; /* Soft vs kinetic hardness [0,1] (cluster only) */
objprop . m_soft_kSSHR_CL = blenderobject - > bsoft - > kSSHR_CL ; /* Soft vs soft hardness [0,1] (cluster only) */
objprop . m_soft_kSR_SPLT_CL = blenderobject - > bsoft - > kSR_SPLT_CL ; /* Soft vs rigid impulse split [0,1] (cluster only) */
objprop . m_soft_kSK_SPLT_CL = blenderobject - > bsoft - > kSK_SPLT_CL ; /* Soft vs rigid impulse split [0,1] (cluster only) */
objprop . m_soft_kSS_SPLT_CL = blenderobject - > bsoft - > kSS_SPLT_CL ; /* Soft vs rigid impulse split [0,1] (cluster only) */
objprop . m_soft_kVCF = blenderobject - > bsoft - > kVCF ; /* Velocities correction factor (Baumgarte) */
objprop . m_soft_kDP = blenderobject - > bsoft - > kDP ; /* Damping coefficient [0,1] */
objprop . m_soft_kDG = blenderobject - > bsoft - > kDG ; /* Drag coefficient [0,+inf] */
objprop . m_soft_kLF = blenderobject - > bsoft - > kLF ; /* Lift coefficient [0,+inf] */
objprop . m_soft_kPR = blenderobject - > bsoft - > kPR ; /* Pressure coefficient [-inf,+inf] */
objprop . m_soft_kVC = blenderobject - > bsoft - > kVC ; /* Volume conversation coefficient [0,+inf] */
objprop . m_soft_kDF = blenderobject - > bsoft - > kDF ; /* Dynamic friction coefficient [0,1] */
objprop . m_soft_kMT = blenderobject - > bsoft - > kMT ; /* Pose matching coefficient [0,1] */
objprop . m_soft_kCHR = blenderobject - > bsoft - > kCHR ; /* Rigid contacts hardness [0,1] */
objprop . m_soft_kKHR = blenderobject - > bsoft - > kKHR ; /* Kinetic contacts hardness [0,1] */
objprop . m_soft_kSHR = blenderobject - > bsoft - > kSHR ; /* Soft contacts hardness [0,1] */
objprop . m_soft_kAHR = blenderobject - > bsoft - > kAHR ; /* Anchors hardness [0,1] */
objprop . m_soft_collisionflags = blenderobject - > bsoft - > collisionflags ; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
objprop . m_soft_numclusteriterations = blenderobject - > bsoft - > numclusteriterations ; /* number of iterations to refine collision clusters*/
2009-04-27 22:21:42 +00:00
objprop . m_soft_welding = blenderobject - > bsoft - > welding ; /* welding */
2009-05-18 21:32:03 +00:00
objprop . m_margin = blenderobject - > bsoft - > margin ;
2009-05-23 22:35:47 +00:00
objprop . m_contactProcessingThreshold = 0.f ;
2008-09-28 03:07:13 +00:00
} else
{
objprop . m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT ;
objprop . m_soft_linStiff = 0.5 ; ;
objprop . m_soft_angStiff = 1.f ; /* angular stiffness 0..1 */
objprop . m_soft_volume = 1.f ; /* volume preservation 0..1 */
objprop . m_soft_viterations = 0 ;
objprop . m_soft_piterations = 1 ;
objprop . m_soft_diterations = 0 ;
objprop . m_soft_citerations = 4 ;
objprop . m_soft_kSRHR_CL = 0.1f ;
objprop . m_soft_kSKHR_CL = 1.f ;
objprop . m_soft_kSSHR_CL = 0.5 ;
objprop . m_soft_kSR_SPLT_CL = 0.5f ;
objprop . m_soft_kSK_SPLT_CL = 0.5f ;
objprop . m_soft_kSS_SPLT_CL = 0.5f ;
objprop . m_soft_kVCF = 1 ;
objprop . m_soft_kDP = 0 ;
objprop . m_soft_kDG = 0 ;
objprop . m_soft_kLF = 0 ;
objprop . m_soft_kPR = 0 ;
objprop . m_soft_kVC = 0 ;
objprop . m_soft_kDF = 0.2f ;
2008-09-28 03:17:45 +00:00
objprop . m_soft_kMT = 0.05f ;
2008-09-28 03:07:13 +00:00
objprop . m_soft_kCHR = 1.0f ;
objprop . m_soft_kKHR = 0.1f ;
objprop . m_soft_kSHR = 1.f ;
objprop . m_soft_kAHR = 0.7f ;
objprop . m_soft_collisionflags = OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS ;
objprop . m_soft_numclusteriterations = 16 ;
2009-04-27 22:21:42 +00:00
objprop . m_soft_welding = 0.f ;
2009-05-18 21:32:03 +00:00
objprop . m_margin = 0.f ;
2009-05-23 22:35:47 +00:00
objprop . m_contactProcessingThreshold = 0.f ;
2008-09-28 03:07:13 +00:00
}
2008-09-25 16:48:25 +00:00
}
2008-09-25 03:02:30 +00:00
2008-09-19 20:41:38 +00:00
objprop . m_ghost = ( blenderobject - > gameflag & OB_GHOST ) ! = 0 ;
objprop . m_disableSleeping = ( blenderobject - > gameflag & OB_COLLISION_RESPONSE ) ! = 0 ; //abuse the OB_COLLISION_RESPONSE flag
2002-10-12 11:37:38 +00:00
//mmm, for now, taks this for the size of the dynamicobject
// Blender uses inertia for radius of dynamic object
objprop . m_radius = blenderobject - > inertia ;
objprop . m_in_active_layer = ( blenderobject - > lay & activeLayerBitInfo ) ! = 0 ;
objprop . m_dynamic_parent = NULL ;
objprop . m_isdeformable = ( ( blenderobject - > gameflag2 & 2 ) ) ! = 0 ;
2004-03-22 22:02:18 +00:00
objprop . m_boundclass = objprop . m_dyna ? KX_BOUNDSPHERE : KX_BOUNDMESH ;
2008-09-29 04:14:47 +00:00
if ( ( blenderobject - > gameflag & OB_SOFT_BODY ) & & ! ( blenderobject - > gameflag & OB_BOUNDS ) )
{
objprop . m_boundclass = KX_BOUNDMESH ;
}
2004-03-22 22:02:18 +00:00
KX_BoxBounds bb ;
2009-05-14 13:47:08 +00:00
DerivedMesh * dm = NULL ;
if ( gameobj - > GetDeformer ( ) )
dm = gameobj - > GetDeformer ( ) - > GetFinalMesh ( ) ;
my_get_local_bounds ( blenderobject , dm , objprop . m_boundobject . box . m_center , bb . m_extends ) ;
2004-03-22 22:02:18 +00:00
if ( blenderobject - > gameflag & OB_BOUNDS )
2002-10-12 11:37:38 +00:00
{
2004-03-22 22:02:18 +00:00
switch ( blenderobject - > boundtype )
{
case OB_BOUND_BOX :
objprop . m_boundclass = KX_BOUNDBOX ;
//mmm, has to be divided by 2 to be proper extends
objprop . m_boundobject . box . m_extends [ 0 ] = 2.f * bb . m_extends [ 0 ] ;
objprop . m_boundobject . box . m_extends [ 1 ] = 2.f * bb . m_extends [ 1 ] ;
objprop . m_boundobject . box . m_extends [ 2 ] = 2.f * bb . m_extends [ 2 ] ;
break ;
2004-11-22 10:19:19 +00:00
case OB_BOUND_POLYT :
if ( blenderobject - > type = = OB_MESH )
{
objprop . m_boundclass = KX_BOUNDPOLYTOPE ;
break ;
}
// Object is not a mesh... fall through OB_BOUND_POLYH to
// OB_BOUND_SPHERE
2004-07-16 00:08:06 +00:00
case OB_BOUND_POLYH :
if ( blenderobject - > type = = OB_MESH )
{
objprop . m_boundclass = KX_BOUNDMESH ;
break ;
}
// Object is not a mesh... can't use polyheder.
// Fall through and become a sphere.
2004-03-22 22:02:18 +00:00
case OB_BOUND_SPHERE :
{
objprop . m_boundclass = KX_BOUNDSPHERE ;
objprop . m_boundobject . c . m_radius = MT_max ( bb . m_extends [ 0 ] , MT_max ( bb . m_extends [ 1 ] , bb . m_extends [ 2 ] ) ) ;
break ;
}
case OB_BOUND_CYLINDER :
{
objprop . m_boundclass = KX_BOUNDCYLINDER ;
objprop . m_boundobject . c . m_radius = MT_max ( bb . m_extends [ 0 ] , bb . m_extends [ 1 ] ) ;
objprop . m_boundobject . c . m_height = 2.f * bb . m_extends [ 2 ] ;
break ;
}
case OB_BOUND_CONE :
{
objprop . m_boundclass = KX_BOUNDCONE ;
objprop . m_boundobject . c . m_radius = MT_max ( bb . m_extends [ 0 ] , bb . m_extends [ 1 ] ) ;
objprop . m_boundobject . c . m_height = 2.f * bb . m_extends [ 2 ] ;
break ;
}
}
2002-10-12 11:37:38 +00:00
}
2006-12-01 01:04:27 +00:00
2009-05-20 21:34:50 +00:00
if ( parent /* && (parent->gameflag & OB_DYNAMIC)*/ ) {
// parented object cannot be dynamic
2002-10-12 11:37:38 +00:00
KX_GameObject * parentgameobject = converter - > FindGameObject ( parent ) ;
objprop . m_dynamic_parent = parentgameobject ;
2006-12-01 01:04:27 +00:00
//cannot be dynamic:
objprop . m_dyna = false ;
2009-04-23 21:19:42 +00:00
objprop . m_softbody = false ;
2006-12-01 01:04:27 +00:00
shapeprops - > m_mass = 0.f ;
2002-10-12 11:37:38 +00:00
}
2006-12-01 01:04:27 +00:00
2002-10-12 11:37:38 +00:00
objprop . m_concave = ( blenderobject - > boundtype & 4 ) ! = 0 ;
switch ( physics_engine )
2004-04-24 06:40:15 +00:00
{
2005-07-16 21:47:54 +00:00
# ifdef USE_BULLET
case UseBullet :
2009-05-14 13:47:08 +00:00
KX_ConvertBulletObject ( gameobj , meshobj , dm , kxscene , shapeprops , smmaterial , & objprop ) ;
2005-07-16 21:47:54 +00:00
break ;
# endif
2002-10-12 11:37:38 +00:00
# ifdef USE_SUMO_SOLID
2004-04-24 06:40:15 +00:00
case UseSumo :
KX_ConvertSumoObject ( gameobj , meshobj , kxscene , shapeprops , smmaterial , & objprop ) ;
break ;
2002-10-12 11:37:38 +00:00
# endif
2004-04-24 06:40:15 +00:00
2002-10-12 11:37:38 +00:00
# ifdef USE_ODE
2004-04-24 06:40:15 +00:00
case UseODE :
KX_ConvertODEEngineObject ( gameobj , meshobj , kxscene , shapeprops , smmaterial , & objprop ) ;
break ;
2002-10-12 11:37:38 +00:00
# endif //USE_ODE
2004-04-24 06:40:15 +00:00
case UseDynamo :
//KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
break ;
case UseNone :
default :
break ;
2002-10-12 11:37:38 +00:00
}
2008-03-01 19:46:50 +00:00
delete shapeprops ;
delete smmaterial ;
2002-10-12 11:37:38 +00:00
}
2008-07-10 12:47:20 +00:00
static KX_LightObject * gamelight_from_blamp ( Object * ob , Lamp * la , unsigned int layerflag , KX_Scene * kxscene , RAS_IRenderTools * rendertools , KX_BlenderSceneConverter * converter ) {
2002-10-12 11:37:38 +00:00
RAS_LightObject lightobj ;
KX_LightObject * gamelight ;
lightobj . m_att1 = la - > att1 ;
2004-06-07 11:01:31 +00:00
lightobj . m_att2 = ( la - > mode & LA_QUAD ) ? la - > att2 : 0.0 ;
2002-10-12 11:37:38 +00:00
lightobj . m_red = la - > r ;
lightobj . m_green = la - > g ;
lightobj . m_blue = la - > b ;
lightobj . m_distance = la - > dist ;
lightobj . m_energy = la - > energy ;
lightobj . m_layer = layerflag ;
lightobj . m_spotblend = la - > spotblend ;
lightobj . m_spotsize = la - > spotsize ;
2004-06-07 11:01:31 +00:00
lightobj . m_nodiffuse = ( la - > mode & LA_NO_DIFF ) ! = 0 ;
lightobj . m_nospecular = ( la - > mode & LA_NO_SPEC ) ! = 0 ;
if ( la - > mode & LA_NEG )
{
lightobj . m_red = - lightobj . m_red ;
lightobj . m_green = - lightobj . m_green ;
lightobj . m_blue = - lightobj . m_blue ;
}
2002-10-12 11:37:38 +00:00
if ( la - > type = = LA_SUN ) {
lightobj . m_type = RAS_LightObject : : LIGHT_SUN ;
} else if ( la - > type = = LA_SPOT ) {
lightobj . m_type = RAS_LightObject : : LIGHT_SPOT ;
} else {
lightobj . m_type = RAS_LightObject : : LIGHT_NORMAL ;
}
2008-07-10 12:47:20 +00:00
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
gamelight = new KX_LightObject ( kxscene , KX_Scene : : m_callbacks , rendertools ,
lightobj , converter - > GetGLSLMaterials ( ) ) ;
2002-10-12 11:37:38 +00:00
BL_ConvertLampIpos ( la , gamelight , converter ) ;
return gamelight ;
}
2008-05-24 08:34:04 +00:00
static KX_Camera * gamecamera_from_bcamera ( Object * ob , KX_Scene * kxscene , KX_BlenderSceneConverter * converter ) {
Camera * ca = static_cast < Camera * > ( ob - > data ) ;
2009-04-26 12:23:30 +00:00
RAS_CameraData camdata ( ca - > lens , ca - > ortho_scale , ca - > clipsta , ca - > clipend , ca - > type = = CAM_PERSP , dof_camera ( ob ) ) ;
2002-10-12 11:37:38 +00:00
KX_Camera * gamecamera ;
gamecamera = new KX_Camera ( kxscene , KX_Scene : : m_callbacks , camdata ) ;
gamecamera - > SetName ( ca - > id . name + 2 ) ;
BL_ConvertCameraIpos ( ca , gamecamera , converter ) ;
return gamecamera ;
}
static KX_GameObject * gameobject_from_blenderobject (
Object * ob ,
KX_Scene * kxscene ,
RAS_IRenderTools * rendertools ,
KX_BlenderSceneConverter * converter ,
Scene * blenderscene )
{
KX_GameObject * gameobj = NULL ;
switch ( ob - > type )
{
case OB_LAMP :
{
2008-07-10 12:47:20 +00:00
KX_LightObject * gamelight = gamelight_from_blamp ( ob , static_cast < Lamp * > ( ob - > data ) , ob - > lay , kxscene , rendertools , converter ) ;
2002-10-12 11:37:38 +00:00
gameobj = gamelight ;
gamelight - > AddRef ( ) ;
kxscene - > GetLightList ( ) - > Add ( gamelight ) ;
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
2002-10-12 11:37:38 +00:00
break ;
}
case OB_CAMERA :
{
2008-05-24 08:34:04 +00:00
KX_Camera * gamecamera = gamecamera_from_bcamera ( ob , kxscene , converter ) ;
2002-10-12 11:37:38 +00:00
gameobj = gamecamera ;
2008-03-01 19:46:50 +00:00
//don't add a reference: the camera list in kxscene->m_cameras is not released at the end
//gamecamera->AddRef();
2002-10-12 11:37:38 +00:00
kxscene - > AddCamera ( gamecamera ) ;
break ;
}
case OB_MESH :
{
Mesh * mesh = static_cast < Mesh * > ( ob - > data ) ;
2007-04-04 13:18:41 +00:00
float center [ 3 ] , extents [ 3 ] ;
float radius = my_boundbox_mesh ( ( Mesh * ) ob - > data , center , extents ) ;
2009-05-23 14:46:43 +00:00
RAS_MeshObject * meshobj = BL_ConvertMesh ( mesh , ob , rendertools , kxscene , converter ) ;
2002-10-12 11:37:38 +00:00
// needed for python scripting
kxscene - > GetLogicManager ( ) - > RegisterMeshName ( meshobj - > GetName ( ) , meshobj ) ;
2008-06-18 06:46:49 +00:00
gameobj = new BL_DeformableGameObject ( ob , kxscene , KX_Scene : : m_callbacks ) ;
2002-10-12 11:37:38 +00:00
// set transformation
gameobj - > AddMesh ( meshobj ) ;
// for all objects: check whether they want to
// respond to updates
bool ignoreActivityCulling =
( ( ob - > gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING ) ! = 0 ) ;
gameobj - > SetIgnoreActivityCulling ( ignoreActivityCulling ) ;
2009-04-13 20:08:33 +00:00
gameobj - > SetOccluder ( ( ob - > gameflag & OB_OCCLUDER ) ! = 0 , false ) ;
2002-10-12 11:37:38 +00:00
2008-06-18 06:46:49 +00:00
// two options exists for deform: shape keys and armature
// only support relative shape key
bool bHasShapeKey = mesh - > key ! = NULL & & mesh - > key - > type = = KEY_RELATIVE ;
2008-07-10 12:47:20 +00:00
bool bHasDvert = mesh - > dvert ! = NULL & & ob - > defbase . first ;
2008-06-18 06:46:49 +00:00
bool bHasArmature = ( ob - > parent & & ob - > parent - > type = = OB_ARMATURE & & ob - > partype = = PARSKEL & & bHasDvert ) ;
BGE: Support mesh modifiers in the game engine.
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
2009-04-21 11:01:09 +00:00
bool bHasModifier = BL_ModifierDeformer : : HasCompatibleDeformer ( ob ) ;
2008-06-18 06:46:49 +00:00
BGE: Support mesh modifiers in the game engine.
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
2009-04-21 11:01:09 +00:00
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 ) {
2008-06-18 06:46:49 +00:00
// not that we can have shape keys without dvert!
BL_ShapeDeformer * dcont = new BL_ShapeDeformer ( ( BL_DeformableGameObject * ) gameobj ,
ob , ( BL_SkinMeshObject * ) meshobj ) ;
2008-09-24 03:12:10 +00:00
( ( BL_DeformableGameObject * ) gameobj ) - > SetDeformer ( dcont ) ;
2008-06-24 22:19:00 +00:00
if ( bHasArmature )
dcont - > LoadShapeDrivers ( ob - > parent ) ;
2008-06-18 06:46:49 +00:00
} else if ( bHasArmature ) {
2008-07-10 12:47:20 +00:00
BL_SkinDeformer * dcont = new BL_SkinDeformer ( ( BL_DeformableGameObject * ) gameobj ,
ob , ( BL_SkinMeshObject * ) meshobj ) ;
2008-09-24 03:12:10 +00:00
( ( BL_DeformableGameObject * ) gameobj ) - > SetDeformer ( dcont ) ;
2008-06-18 06:46:49 +00:00
} 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!
2008-07-10 12:47:20 +00:00
BL_MeshDeformer * dcont = new BL_MeshDeformer ( ( BL_DeformableGameObject * ) gameobj ,
ob , ( BL_SkinMeshObject * ) meshobj ) ;
2008-09-24 03:12:10 +00:00
( ( BL_DeformableGameObject * ) gameobj ) - > SetDeformer ( dcont ) ;
2002-10-12 11:37:38 +00:00
}
2004-05-16 12:52:08 +00:00
2007-04-04 13:18:41 +00:00
MT_Point3 min = MT_Point3 ( center ) - MT_Vector3 ( extents ) ;
MT_Point3 max = MT_Point3 ( center ) + MT_Vector3 ( extents ) ;
2004-05-16 12:52:08 +00:00
SG_BBox bbox = SG_BBox ( min , max ) ;
gameobj - > GetSGNode ( ) - > SetBBox ( bbox ) ;
2004-05-21 09:21:15 +00:00
gameobj - > GetSGNode ( ) - > SetRadius ( radius ) ;
2002-10-12 11:37:38 +00:00
break ;
}
case OB_ARMATURE :
{
2006-01-06 03:46:54 +00:00
gameobj = new BL_ArmatureObject (
kxscene ,
KX_Scene : : m_callbacks ,
ob // handle
) ;
2002-10-12 11:37:38 +00:00
/* Get the current pose from the armature object and apply it as the rest pose */
break ;
}
case OB_EMPTY :
{
gameobj = new KX_EmptyObject ( kxscene , KX_Scene : : m_callbacks ) ;
// set transformation
break ;
}
}
2008-04-30 19:58:44 +00:00
if ( gameobj )
{
2008-03-21 22:44:12 +00:00
gameobj - > SetPhysicsEnvironment ( kxscene - > GetPhysicsEnvironment ( ) ) ;
2008-04-30 19:58:44 +00:00
gameobj - > SetLayer ( ob - > lay ) ;
2008-06-18 06:46:49 +00:00
gameobj - > SetBlenderObject ( ob ) ;
2008-09-21 04:39:40 +00:00
/* set the visibility state based on the objects render option in the outliner */
if ( ob - > restrictflag & OB_RESTRICT_RENDER ) gameobj - > SetVisible ( 0 , 0 ) ;
2008-04-30 19:58:44 +00:00
}
2002-10-12 11:37:38 +00:00
return gameobj ;
}
struct parentChildLink {
struct Object * m_blenderchild ;
SG_Node * m_gamechildnode ;
} ;
2006-11-30 00:19:27 +00:00
# include "DNA_constraint_types.h"
# include "BIF_editconstraint.h"
bPoseChannel * get_active_posechannel2 ( Object * ob )
{
bArmature * arm = ( bArmature * ) ob - > data ;
bPoseChannel * pchan ;
/* find active */
for ( pchan = ( bPoseChannel * ) ob - > pose - > chanbase . first ; pchan ; pchan = pchan - > next ) {
if ( pchan - > bone & & ( pchan - > bone - > flag & BONE_ACTIVE ) & & ( pchan - > bone - > layer & arm - > layer ) )
return pchan ;
}
return NULL ;
}
ListBase * get_active_constraints2 ( Object * ob )
{
if ( ! ob )
return NULL ;
if ( ob - > flag & OB_POSEMODE ) {
bPoseChannel * pchan ;
pchan = get_active_posechannel2 ( ob ) ;
if ( pchan )
return & pchan - > constraints ;
}
else
return & ob - > constraints ;
return NULL ;
}
void RBJconstraints ( Object * ob ) //not used
{
ListBase * conlist ;
bConstraint * curcon ;
conlist = get_active_constraints2 ( ob ) ;
if ( conlist ) {
for ( curcon = ( bConstraint * ) conlist - > first ; curcon ; curcon = ( bConstraint * ) curcon - > next ) {
printf ( " %i \n " , curcon - > type ) ;
}
}
}
# include "PHY_IPhysicsEnvironment.h"
# include "KX_IPhysicsController.h"
# include "PHY_DynamicTypes.h"
KX_IPhysicsController * getPhId ( CListValue * sumolist , STR_String busc ) { //not used
for ( int j = 0 ; j < sumolist - > GetCount ( ) ; j + + )
{
KX_GameObject * gameobje = ( KX_GameObject * ) sumolist - > GetValue ( j ) ;
if ( gameobje - > GetName ( ) = = busc )
return gameobje - > GetPhysicsController ( ) ;
}
2006-12-12 13:24:45 +00:00
return 0 ;
2006-11-30 00:19:27 +00:00
}
KX_GameObject * getGameOb ( STR_String busc , CListValue * sumolist ) {
for ( int j = 0 ; j < sumolist - > GetCount ( ) ; j + + )
{
KX_GameObject * gameobje = ( KX_GameObject * ) sumolist - > GetValue ( j ) ;
if ( gameobje - > GetName ( ) = = busc )
return gameobje ;
}
2006-12-12 13:24:45 +00:00
return 0 ;
2006-11-30 00:19:27 +00:00
}
2008-07-29 15:48:31 +00:00
2002-10-12 11:37:38 +00:00
// convert blender objects into ketsji gameobjects
void BL_ConvertBlenderObjects ( struct Main * maggie ,
const STR_String & scenename ,
KX_Scene * kxscene ,
KX_KetsjiEngine * ketsjiEngine ,
e_PhysicsEngine physics_engine ,
PyObject * pythondictionary ,
SCA_IInputDevice * keydev ,
RAS_IRenderTools * rendertools ,
RAS_ICanvas * canvas ,
KX_BlenderSceneConverter * converter ,
bool alwaysUseExpandFraming
)
{
2005-08-23 13:16:02 +00:00
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
Scene * blenderscene = converter - > GetBlenderSceneForName ( scenename ) ;
2008-06-14 20:42:15 +00:00
// for SETLOOPER
Scene * sce ;
Base * base ;
2002-10-12 11:37:38 +00:00
// Get the frame settings of the canvas.
// Get the aspect ratio of the canvas as designed by the user.
RAS_FrameSettings : : RAS_FrameType frame_type ;
int aspect_width ;
int aspect_height ;
2006-12-16 05:50:38 +00:00
vector < MT_Vector3 > inivel , iniang ;
2008-07-15 20:05:23 +00:00
set < Group * > grouplist ; // list of groups to be converted
set < Object * > allblobj ; // all objects converted
set < Object * > groupobj ; // objects from groups (never in active layer)
2002-10-12 11:37:38 +00:00
if ( alwaysUseExpandFraming ) {
frame_type = RAS_FrameSettings : : e_frame_extend ;
aspect_width = canvas - > GetWidth ( ) ;
aspect_height = canvas - > GetHeight ( ) ;
} else {
if ( blenderscene - > framing . type = = SCE_GAMEFRAMING_BARS ) {
frame_type = RAS_FrameSettings : : e_frame_bars ;
} else if ( blenderscene - > framing . type = = SCE_GAMEFRAMING_EXTEND ) {
frame_type = RAS_FrameSettings : : e_frame_extend ;
} else {
frame_type = RAS_FrameSettings : : e_frame_scale ;
}
aspect_width = blenderscene - > r . xsch ;
aspect_height = blenderscene - > r . ysch ;
}
RAS_FrameSettings frame_settings (
frame_type ,
blenderscene - > framing . col [ 0 ] ,
blenderscene - > framing . col [ 1 ] ,
blenderscene - > framing . col [ 2 ] ,
aspect_width ,
aspect_height
) ;
kxscene - > SetFramingType ( frame_settings ) ;
kxscene - > SetGravity ( MT_Vector3 ( 0 , 0 , ( blenderscene - > world ! = NULL ) ? - blenderscene - > world - > gravity : - 9.8 ) ) ;
/* set activity culling parameters */
if ( blenderscene - > world ) {
kxscene - > SetActivityCulling ( ( blenderscene - > world - > mode & WO_ACTIVITY_CULLING ) ! = 0 ) ;
kxscene - > SetActivityCullingRadius ( blenderscene - > world - > activityBoxRadius ) ;
2009-04-13 20:08:33 +00:00
kxscene - > SetDbvtCulling ( ( blenderscene - > world - > mode & WO_DBVT_CULLING ) ! = 0 ) ;
2002-10-12 11:37:38 +00:00
} else {
kxscene - > SetActivityCulling ( false ) ;
2009-04-13 20:08:33 +00:00
kxscene - > SetDbvtCulling ( false ) ;
2002-10-12 11:37:38 +00:00
}
2009-04-13 20:08:33 +00:00
// no occlusion culling by default
kxscene - > SetDbvtOcclusionRes ( 0 ) ;
2002-10-12 11:37:38 +00:00
int activeLayerBitInfo = blenderscene - > lay ;
2009-05-14 13:47:08 +00:00
// list of all object converted, active and inactive
2002-10-12 11:37:38 +00:00
CListValue * sumolist = new CListValue ( ) ;
vector < parentChildLink > vec_parent_child ;
CListValue * objectlist = kxscene - > GetObjectList ( ) ;
2008-03-01 19:46:50 +00:00
CListValue * inactivelist = kxscene - > GetInactiveList ( ) ;
2002-10-12 11:37:38 +00:00
CListValue * parentlist = kxscene - > GetRootParentList ( ) ;
SCA_LogicManager * logicmgr = kxscene - > GetLogicManager ( ) ;
SCA_TimeEventManager * timemgr = kxscene - > GetTimeEventManager ( ) ;
CListValue * logicbrick_conversionlist = new CListValue ( ) ;
2008-03-01 19:46:50 +00:00
//SG_TreeFactory tf;
2004-05-16 12:52:08 +00:00
2002-10-12 11:37:38 +00:00
// Convert actions to actionmap
bAction * curAct ;
for ( curAct = ( bAction * ) maggie - > action . first ; curAct ; curAct = ( bAction * ) curAct - > id . next )
{
logicmgr - > RegisterActionName ( curAct - > id . name , curAct ) ;
}
2006-01-06 03:46:54 +00:00
2004-12-01 08:43:02 +00:00
SetDefaultFaceType ( blenderscene ) ;
2008-06-14 20:42:15 +00:00
// Let's support scene set.
// Beware of name conflict in linked data, it will not crash but will create confusion
// in Python scripting and in certain actuators (replace mesh). Linked scene *should* have
// no conflicting name for Object, Object data and Action.
for ( SETLOOPER ( blenderscene , base ) )
2002-10-12 11:37:38 +00:00
{
Object * blenderobject = base - > object ;
2008-07-15 20:05:23 +00:00
allblobj . insert ( blenderobject ) ;
2002-10-12 11:37:38 +00:00
KX_GameObject * gameobj = gameobject_from_blenderobject (
base - > object ,
kxscene ,
rendertools ,
converter ,
blenderscene ) ;
2007-01-07 04:54:29 +00:00
bool isInActiveLayer = ( blenderobject - > lay & activeLayerBitInfo ) ! = 0 ;
bool addobj = true ;
if ( converter - > addInitFromFrame )
if ( ! isInActiveLayer )
addobj = false ;
2008-07-30 16:15:15 +00:00
2007-01-07 04:54:29 +00:00
if ( gameobj & & addobj )
2002-10-12 11:37:38 +00:00
{
2006-12-16 05:50:38 +00:00
MT_Point3 posPrev ;
MT_Matrix3x3 angor ;
if ( converter - > addInitFromFrame ) blenderscene - > r . cfra = blenderscene - > r . sfra ;
2009-02-25 06:43:03 +00:00
MT_Point3 pos ;
pos . setValue (
2002-10-12 11:37:38 +00:00
blenderobject - > loc [ 0 ] + blenderobject - > dloc [ 0 ] ,
blenderobject - > loc [ 1 ] + blenderobject - > dloc [ 1 ] ,
blenderobject - > loc [ 2 ] + blenderobject - > dloc [ 2 ]
) ;
2009-02-25 06:43:03 +00:00
MT_Vector3 eulxyz ( blenderobject - > rot ) ;
MT_Vector3 scale ( blenderobject - > size ) ;
2006-12-16 05:50:38 +00:00
if ( converter - > addInitFromFrame ) { //rcruiz
float eulxyzPrev [ 3 ] ;
blenderscene - > r . cfra = blenderscene - > r . sfra - 1 ;
update_for_newframe ( ) ;
MT_Vector3 tmp = pos - MT_Point3 ( blenderobject - > loc [ 0 ] + blenderobject - > dloc [ 0 ] ,
blenderobject - > loc [ 1 ] + blenderobject - > dloc [ 1 ] ,
blenderobject - > loc [ 2 ] + blenderobject - > dloc [ 2 ]
) ;
eulxyzPrev [ 0 ] = blenderobject - > rot [ 0 ] ;
eulxyzPrev [ 1 ] = blenderobject - > rot [ 1 ] ;
eulxyzPrev [ 2 ] = blenderobject - > rot [ 2 ] ;
== Core ==
This adds fractional FPS support to blender and should finally
make NTSC work correctly.
NTSC has an FPS of 30.0/1.001 which is approximately 29.97 FPS.
Therefore, it is not enough to simply make frs_sec a float, since
you can't represent this accurately enough.
I added a seperate variable frs_sec_base and FPS is now
frs_sec / frs_sec_base.
I changed all the places, where frs_sec was used to my best knowledge.
For convenience sake, I added several macros, that should make life
easier in the future:
FRA2TIME(a) : convert frame number to a double precision time in seconds
TIME2FRA(a) : the same in the opposite direction
FPS : return current FPS as a double precision number
(last resort)
This closes bug #6715
Standard framerates not supported / breaks sync -- 23.967 29.967 etc.
https://projects.blender.org/tracker/?func=detail&aid=6715&group_id=9&atid=125
Please give this heavy testing with NTSC files, quicktime in/export
and the python interface.
Errors are most probably only spotted on longer timelines, so that is
also important.
The patch was tested by Troy Sobotka and me, so it most probably should
work out of the box, but wider testing is important, since errors are
very subtle.
Enjoy!
2007-10-21 15:42:08 +00:00
double fps = ( double ) blenderscene - > r . frs_sec /
( double ) blenderscene - > r . frs_sec_base ;
tmp . scale ( fps , fps , fps ) ;
2006-12-16 05:50:38 +00:00
inivel . push_back ( tmp ) ;
tmp = eulxyz - eulxyzPrev ;
== Core ==
This adds fractional FPS support to blender and should finally
make NTSC work correctly.
NTSC has an FPS of 30.0/1.001 which is approximately 29.97 FPS.
Therefore, it is not enough to simply make frs_sec a float, since
you can't represent this accurately enough.
I added a seperate variable frs_sec_base and FPS is now
frs_sec / frs_sec_base.
I changed all the places, where frs_sec was used to my best knowledge.
For convenience sake, I added several macros, that should make life
easier in the future:
FRA2TIME(a) : convert frame number to a double precision time in seconds
TIME2FRA(a) : the same in the opposite direction
FPS : return current FPS as a double precision number
(last resort)
This closes bug #6715
Standard framerates not supported / breaks sync -- 23.967 29.967 etc.
https://projects.blender.org/tracker/?func=detail&aid=6715&group_id=9&atid=125
Please give this heavy testing with NTSC files, quicktime in/export
and the python interface.
Errors are most probably only spotted on longer timelines, so that is
also important.
The patch was tested by Troy Sobotka and me, so it most probably should
work out of the box, but wider testing is important, since errors are
very subtle.
Enjoy!
2007-10-21 15:42:08 +00:00
tmp . scale ( fps , fps , fps ) ;
2006-12-16 05:50:38 +00:00
iniang . push_back ( tmp ) ;
blenderscene - > r . cfra = blenderscene - > r . sfra ;
update_for_newframe ( ) ;
}
2002-10-12 11:37:38 +00:00
gameobj - > NodeSetLocalPosition ( pos ) ;
gameobj - > NodeSetLocalOrientation ( MT_Matrix3x3 ( eulxyz ) ) ;
gameobj - > NodeSetLocalScale ( scale ) ;
2009-04-07 22:14:06 +00:00
gameobj - > NodeUpdateGS ( 0 ) ;
2002-10-12 11:37:38 +00:00
BL_ConvertIpos ( blenderobject , gameobj , converter ) ;
2008-07-25 13:45:57 +00:00
BL_ConvertMaterialIpos ( blenderobject , gameobj , converter ) ;
2002-10-12 11:37:38 +00:00
sumolist - > Add ( gameobj - > AddRef ( ) ) ;
BL_ConvertProperties ( blenderobject , gameobj , timemgr , kxscene , isInActiveLayer ) ;
gameobj - > SetName ( blenderobject - > id . name ) ;
// update children/parent hierarchy
2006-12-16 05:50:38 +00:00
if ( ( blenderobject - > parent ! = 0 ) & & ( ! converter - > addInitFromFrame ) )
2002-10-12 11:37:38 +00:00
{
// blender has an additional 'parentinverse' offset in each object
2009-05-04 08:17:18 +00:00
SG_Callbacks callback ( NULL , NULL , NULL , KX_Scene : : KX_ScenegraphUpdateFunc , KX_Scene : : KX_ScenegraphRescheduleFunc ) ;
SG_Node * parentinversenode = new SG_Node ( NULL , kxscene , callback ) ;
2002-10-12 11:37:38 +00:00
// define a normal parent relationship for this node.
KX_NormalParentRelation * parent_relation = KX_NormalParentRelation : : New ( ) ;
parentinversenode - > SetParentRelation ( parent_relation ) ;
parentChildLink pclink ;
pclink . m_blenderchild = blenderobject ;
pclink . m_gamechildnode = parentinversenode ;
vec_parent_child . push_back ( pclink ) ;
2005-04-23 11:36:44 +00:00
2002-10-12 11:37:38 +00:00
float * fl = ( float * ) blenderobject - > parentinv ;
MT_Transform parinvtrans ( fl ) ;
parentinversenode - > SetLocalPosition ( parinvtrans . getOrigin ( ) ) ;
2008-08-08 09:57:17 +00:00
// problem here: the parent inverse transform combines scaling and rotation
// in the basis but the scenegraph needs separate rotation and scaling.
// This is not important for OpenGL (it uses 4x4 matrix) but it is important
// for the physic engine that needs a separate scaling
//parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
// Extract the rotation and the scaling from the basis
2008-08-15 22:17:50 +00:00
MT_Matrix3x3 ori ( parinvtrans . getBasis ( ) ) ;
MT_Vector3 x ( ori . getColumn ( 0 ) ) ;
MT_Vector3 y ( ori . getColumn ( 1 ) ) ;
MT_Vector3 z ( ori . getColumn ( 2 ) ) ;
2009-02-25 03:26:02 +00:00
MT_Vector3 parscale ( x . length ( ) , y . length ( ) , z . length ( ) ) ;
if ( ! MT_fuzzyZero ( parscale [ 0 ] ) )
x / = parscale [ 0 ] ;
if ( ! MT_fuzzyZero ( parscale [ 1 ] ) )
y / = parscale [ 1 ] ;
if ( ! MT_fuzzyZero ( parscale [ 2 ] ) )
z / = parscale [ 2 ] ;
2008-08-15 22:17:50 +00:00
ori . setColumn ( 0 , x ) ;
ori . setColumn ( 1 , y ) ;
ori . setColumn ( 2 , z ) ;
parentinversenode - > SetLocalOrientation ( ori ) ;
2009-02-25 03:26:02 +00:00
parentinversenode - > SetLocalScale ( parscale ) ;
2005-04-23 11:36:44 +00:00
2002-10-12 11:37:38 +00:00
parentinversenode - > AddChild ( gameobj - > GetSGNode ( ) ) ;
}
// needed for python scripting
logicmgr - > RegisterGameObjectName ( gameobj - > GetName ( ) , gameobj ) ;
Patch: [ #2439 ] Makes objects react properly to deformations after a mesh replacement call.
from brian hayward (bthayward)
Detailed description:
Currently, when an armature deformed object's mesh is replaced by the ReplaceMesh actuator, the new mesh fails to deform to the armature's movement.
My patch fixes this by properly replacing the deform controller along with the mesh (when appropriete).
For instance, if one had an animated character using any of the standard deformation techniques (armature, ipo, RVK, or AVK), that character's mesh would currently be prevented from changing mid-game. It could be replaced, but the new mesh would lack the controller which tells it how to deform. If one wanted to dynamiclly add a hat on top of the character's head, it would require storing a secondary prebuilt character (mesh, armature, logic, ect...) on another layer FOR EACH HAT the character could possibly wear, then swapping out the whole character when the hat change was desired. So if you had 4 possible hat/character combos, you would have 4 character meshes, 4 armatures, 4 sets of logic, and so on. I find this lack of flexibility to be unresonable.
With my patch, one could accomplish the same thing mearly by making one version of the character in the main layer, and adding an invisible object atop the character's head (which is parented to the head bone). Then whenever it becomes desirable, one can replace the invisible object's mesh with the desirable hat's mesh, then make it visible. With my patch, the hat object would then continue to deform to the character's head regardless of which hat was currently being worn.
*note 1*
for armature/mesh deformations, the new mesh must have properly assigned vertex groups which match one or more of the bones of the target armature before the replaceMesh call is made. Otherwise the vertices won't react to the armature because they won't know how. (not sure if vertices can be scripted to change groups after the game has started)
*note 2*
The added processing time involved with replacing the object's deform controller is negligible.
2005-04-18 11:44:21 +00:00
2008-07-26 11:00:21 +00:00
// needed for group duplication
logicmgr - > RegisterGameObj ( blenderobject , gameobj ) ;
Patch: [ #2439 ] Makes objects react properly to deformations after a mesh replacement call.
from brian hayward (bthayward)
Detailed description:
Currently, when an armature deformed object's mesh is replaced by the ReplaceMesh actuator, the new mesh fails to deform to the armature's movement.
My patch fixes this by properly replacing the deform controller along with the mesh (when appropriete).
For instance, if one had an animated character using any of the standard deformation techniques (armature, ipo, RVK, or AVK), that character's mesh would currently be prevented from changing mid-game. It could be replaced, but the new mesh would lack the controller which tells it how to deform. If one wanted to dynamiclly add a hat on top of the character's head, it would require storing a secondary prebuilt character (mesh, armature, logic, ect...) on another layer FOR EACH HAT the character could possibly wear, then swapping out the whole character when the hat change was desired. So if you had 4 possible hat/character combos, you would have 4 character meshes, 4 armatures, 4 sets of logic, and so on. I find this lack of flexibility to be unresonable.
With my patch, one could accomplish the same thing mearly by making one version of the character in the main layer, and adding an invisible object atop the character's head (which is parented to the head bone). Then whenever it becomes desirable, one can replace the invisible object's mesh with the desirable hat's mesh, then make it visible. With my patch, the hat object would then continue to deform to the character's head regardless of which hat was currently being worn.
*note 1*
for armature/mesh deformations, the new mesh must have properly assigned vertex groups which match one or more of the bones of the target armature before the replaceMesh call is made. Otherwise the vertices won't react to the armature because they won't know how. (not sure if vertices can be scripted to change groups after the game has started)
*note 2*
The added processing time involved with replacing the object's deform controller is negligible.
2005-04-18 11:44:21 +00:00
for ( int i = 0 ; i < gameobj - > GetMeshCount ( ) ; i + + )
logicmgr - > RegisterGameMeshName ( gameobj - > GetMesh ( i ) - > GetName ( ) , blenderobject ) ;
2002-10-12 11:37:38 +00:00
converter - > RegisterGameObject ( gameobj , blenderobject ) ;
// this was put in rapidly, needs to be looked at more closely
// only draw/use objects in active 'blender' layers
logicbrick_conversionlist - > Add ( gameobj - > AddRef ( ) ) ;
2006-12-16 05:50:38 +00:00
if ( converter - > addInitFromFrame ) {
posPrev = gameobj - > NodeGetWorldPosition ( ) ;
angor = gameobj - > NodeGetWorldOrientation ( ) ;
}
2002-10-12 11:37:38 +00:00
if ( isInActiveLayer )
{
objectlist - > Add ( gameobj - > AddRef ( ) ) ;
2008-03-01 19:46:50 +00:00
//tf.Add(gameobj->GetSGNode());
2002-10-12 11:37:38 +00:00
2009-04-07 22:14:06 +00:00
gameobj - > NodeUpdateGS ( 0 ) ;
2009-05-11 22:07:30 +00:00
gameobj - > AddMeshUser ( ) ;
2008-07-15 20:05:23 +00:00
2004-05-16 12:52:08 +00:00
}
2008-03-01 19:46:50 +00:00
else
{
//we must store this object otherwise it will be deleted
//at the end of this function if it is not a root object
inactivelist - > Add ( gameobj - > AddRef ( ) ) ;
}
2008-07-26 11:00:21 +00:00
if ( gameobj - > IsDupliGroup ( ) )
grouplist . insert ( blenderobject - > dup_group ) ;
2006-12-16 05:50:38 +00:00
if ( converter - > addInitFromFrame ) {
gameobj - > NodeSetLocalPosition ( posPrev ) ;
gameobj - > NodeSetLocalOrientation ( angor ) ;
}
2002-10-12 11:37:38 +00:00
}
2008-03-01 19:46:50 +00:00
/* Note about memory leak issues:
When a CValue derived class is created , m_refcount is initialized to 1
so the class must be released after being used to make sure that it won ' t
hang in memory . If the object needs to be stored for a long time ,
use AddRef ( ) so that this Release ( ) does not free the object .
Make sure that for any AddRef ( ) there is a Release ( ) ! ! ! !
Do the same for any object derived from CValue , CExpression and NG_NetworkMessage
*/
if ( gameobj )
gameobj - > Release ( ) ;
2002-10-12 11:37:38 +00:00
}
2008-07-15 20:05:23 +00:00
if ( ! grouplist . empty ( ) )
{
// now convert the group referenced by dupli group object
// keep track of all groups already converted
set < Group * > allgrouplist = grouplist ;
set < Group * > tempglist ;
// recurse
while ( ! grouplist . empty ( ) )
{
set < Group * > : : iterator git ;
tempglist . clear ( ) ;
tempglist . swap ( grouplist ) ;
for ( git = tempglist . begin ( ) ; git ! = tempglist . end ( ) ; git + + )
{
Group * group = * git ;
GroupObject * go ;
for ( go = ( GroupObject * ) group - > gobject . first ; go ; go = ( GroupObject * ) go - > next )
{
Object * blenderobject = go - > ob ;
if ( converter - > FindGameObject ( blenderobject ) = = NULL )
{
allblobj . insert ( blenderobject ) ;
groupobj . insert ( blenderobject ) ;
KX_GameObject * gameobj = gameobject_from_blenderobject (
blenderobject ,
kxscene ,
rendertools ,
converter ,
blenderscene ) ;
// this code is copied from above except that
2008-07-26 11:00:21 +00:00
// object from groups are never in active layer
2008-07-15 20:05:23 +00:00
bool isInActiveLayer = false ;
bool addobj = true ;
if ( converter - > addInitFromFrame )
if ( ! isInActiveLayer )
addobj = false ;
if ( gameobj & & addobj )
{
MT_Point3 posPrev ;
MT_Matrix3x3 angor ;
if ( converter - > addInitFromFrame )
blenderscene - > r . cfra = blenderscene - > r . sfra ;
2009-02-25 06:43:03 +00:00
MT_Point3 pos (
2008-07-15 20:05:23 +00:00
blenderobject - > loc [ 0 ] + blenderobject - > dloc [ 0 ] ,
blenderobject - > loc [ 1 ] + blenderobject - > dloc [ 1 ] ,
blenderobject - > loc [ 2 ] + blenderobject - > dloc [ 2 ]
) ;
2009-02-25 06:43:03 +00:00
MT_Vector3 eulxyz ( blenderobject - > rot ) ;
MT_Vector3 scale ( blenderobject - > size ) ;
2008-07-15 20:05:23 +00:00
if ( converter - > addInitFromFrame ) { //rcruiz
float eulxyzPrev [ 3 ] ;
blenderscene - > r . cfra = blenderscene - > r . sfra - 1 ;
update_for_newframe ( ) ;
MT_Vector3 tmp = pos - MT_Point3 ( blenderobject - > loc [ 0 ] + blenderobject - > dloc [ 0 ] ,
blenderobject - > loc [ 1 ] + blenderobject - > dloc [ 1 ] ,
blenderobject - > loc [ 2 ] + blenderobject - > dloc [ 2 ]
) ;
eulxyzPrev [ 0 ] = blenderobject - > rot [ 0 ] ;
eulxyzPrev [ 1 ] = blenderobject - > rot [ 1 ] ;
eulxyzPrev [ 2 ] = blenderobject - > rot [ 2 ] ;
double fps = ( double ) blenderscene - > r . frs_sec /
( double ) blenderscene - > r . frs_sec_base ;
tmp . scale ( fps , fps , fps ) ;
inivel . push_back ( tmp ) ;
tmp = eulxyz - eulxyzPrev ;
tmp . scale ( fps , fps , fps ) ;
iniang . push_back ( tmp ) ;
blenderscene - > r . cfra = blenderscene - > r . sfra ;
update_for_newframe ( ) ;
}
gameobj - > NodeSetLocalPosition ( pos ) ;
gameobj - > NodeSetLocalOrientation ( MT_Matrix3x3 ( eulxyz ) ) ;
gameobj - > NodeSetLocalScale ( scale ) ;
2009-04-07 22:14:06 +00:00
gameobj - > NodeUpdateGS ( 0 ) ;
2008-07-15 20:05:23 +00:00
BL_ConvertIpos ( blenderobject , gameobj , converter ) ;
2008-07-25 13:45:57 +00:00
BL_ConvertMaterialIpos ( blenderobject , gameobj , converter ) ;
2008-07-15 20:05:23 +00:00
sumolist - > Add ( gameobj - > AddRef ( ) ) ;
BL_ConvertProperties ( blenderobject , gameobj , timemgr , kxscene , isInActiveLayer ) ;
gameobj - > SetName ( blenderobject - > id . name ) ;
// update children/parent hierarchy
if ( ( blenderobject - > parent ! = 0 ) & & ( ! converter - > addInitFromFrame ) )
{
// blender has an additional 'parentinverse' offset in each object
2009-05-04 08:17:18 +00:00
SG_Callbacks callback ( NULL , NULL , NULL , KX_Scene : : KX_ScenegraphUpdateFunc , KX_Scene : : KX_ScenegraphRescheduleFunc ) ;
SG_Node * parentinversenode = new SG_Node ( NULL , kxscene , callback ) ;
2008-07-15 20:05:23 +00:00
// define a normal parent relationship for this node.
KX_NormalParentRelation * parent_relation = KX_NormalParentRelation : : New ( ) ;
parentinversenode - > SetParentRelation ( parent_relation ) ;
parentChildLink pclink ;
pclink . m_blenderchild = blenderobject ;
pclink . m_gamechildnode = parentinversenode ;
vec_parent_child . push_back ( pclink ) ;
float * fl = ( float * ) blenderobject - > parentinv ;
MT_Transform parinvtrans ( fl ) ;
parentinversenode - > SetLocalPosition ( parinvtrans . getOrigin ( ) ) ;
2008-08-15 22:17:50 +00:00
// Extract the rotation and the scaling from the basis
MT_Matrix3x3 ori ( parinvtrans . getBasis ( ) ) ;
MT_Vector3 x ( ori . getColumn ( 0 ) ) ;
MT_Vector3 y ( ori . getColumn ( 1 ) ) ;
MT_Vector3 z ( ori . getColumn ( 2 ) ) ;
2009-02-25 03:26:02 +00:00
MT_Vector3 localscale ( x . length ( ) , y . length ( ) , z . length ( ) ) ;
if ( ! MT_fuzzyZero ( localscale [ 0 ] ) )
x / = localscale [ 0 ] ;
if ( ! MT_fuzzyZero ( localscale [ 1 ] ) )
y / = localscale [ 1 ] ;
if ( ! MT_fuzzyZero ( localscale [ 2 ] ) )
z / = localscale [ 2 ] ;
2008-08-15 22:17:50 +00:00
ori . setColumn ( 0 , x ) ;
ori . setColumn ( 1 , y ) ;
ori . setColumn ( 2 , z ) ;
parentinversenode - > SetLocalOrientation ( ori ) ;
2009-02-25 03:26:02 +00:00
parentinversenode - > SetLocalScale ( localscale ) ;
2008-07-15 20:05:23 +00:00
parentinversenode - > AddChild ( gameobj - > GetSGNode ( ) ) ;
}
// needed for python scripting
logicmgr - > RegisterGameObjectName ( gameobj - > GetName ( ) , gameobj ) ;
2008-07-26 11:00:21 +00:00
// needed for group duplication
logicmgr - > RegisterGameObj ( blenderobject , gameobj ) ;
2008-07-15 20:05:23 +00:00
for ( int i = 0 ; i < gameobj - > GetMeshCount ( ) ; i + + )
logicmgr - > RegisterGameMeshName ( gameobj - > GetMesh ( i ) - > GetName ( ) , blenderobject ) ;
converter - > RegisterGameObject ( gameobj , blenderobject ) ;
// this was put in rapidly, needs to be looked at more closely
// only draw/use objects in active 'blender' layers
logicbrick_conversionlist - > Add ( gameobj - > AddRef ( ) ) ;
if ( converter - > addInitFromFrame ) {
posPrev = gameobj - > NodeGetWorldPosition ( ) ;
angor = gameobj - > NodeGetWorldOrientation ( ) ;
}
if ( isInActiveLayer )
{
objectlist - > Add ( gameobj - > AddRef ( ) ) ;
//tf.Add(gameobj->GetSGNode());
2009-04-07 22:14:06 +00:00
gameobj - > NodeUpdateGS ( 0 ) ;
2009-05-11 22:07:30 +00:00
gameobj - > AddMeshUser ( ) ;
2008-07-15 20:05:23 +00:00
}
else
{
//we must store this object otherwise it will be deleted
//at the end of this function if it is not a root object
inactivelist - > Add ( gameobj - > AddRef ( ) ) ;
}
if ( gameobj - > IsDupliGroup ( ) )
{
// check that the group is not already converted
if ( allgrouplist . insert ( blenderobject - > dup_group ) . second )
grouplist . insert ( blenderobject - > dup_group ) ;
}
if ( converter - > addInitFromFrame ) {
gameobj - > NodeSetLocalPosition ( posPrev ) ;
gameobj - > NodeSetLocalOrientation ( angor ) ;
}
}
if ( gameobj )
gameobj - > Release ( ) ;
}
}
}
}
}
2008-07-28 14:28:19 +00:00
// non-camera objects not supported as camera currently
if ( blenderscene - > camera & & blenderscene - > camera - > type = = OB_CAMERA ) {
2002-10-12 11:37:38 +00:00
KX_Camera * gamecamera = ( KX_Camera * ) converter - > FindGameObject ( blenderscene - > camera ) ;
2008-07-10 12:47:20 +00:00
if ( gamecamera )
kxscene - > SetActiveCamera ( gamecamera ) ;
2002-10-12 11:37:38 +00:00
}
// Set up armatures
2008-07-15 20:05:23 +00:00
set < Object * > : : iterator oit ;
for ( oit = allblobj . begin ( ) ; oit ! = allblobj . end ( ) ; oit + + )
{
Object * blenderobj = * oit ;
2008-09-14 17:59:22 +00:00
if ( blenderobj - > type = = OB_MESH ) {
2008-07-15 20:05:23 +00:00
Mesh * me = ( Mesh * ) blenderobj - > data ;
2002-10-12 11:37:38 +00:00
if ( me - > dvert ) {
2008-09-14 17:59:22 +00:00
BL_DeformableGameObject * obj = ( BL_DeformableGameObject * ) converter - > FindGameObject ( blenderobj ) ;
2002-10-12 11:37:38 +00:00
2008-07-15 20:05:23 +00:00
if ( obj & & blenderobj - > parent & & blenderobj - > parent - > type = = OB_ARMATURE & & blenderobj - > partype = = PARSKEL ) {
KX_GameObject * par = converter - > FindGameObject ( blenderobj - > parent ) ;
2008-09-24 03:12:10 +00:00
if ( par & & obj - > GetDeformer ( ) )
( ( BL_SkinDeformer * ) obj - > GetDeformer ( ) ) - > SetArmature ( ( BL_ArmatureObject * ) par ) ;
2002-10-12 11:37:38 +00:00
}
}
}
}
// create hierarchy information
int i ;
vector < parentChildLink > : : iterator pcit ;
for ( pcit = vec_parent_child . begin ( ) ; ! ( pcit = = vec_parent_child . end ( ) ) ; + + pcit )
{
struct Object * blenderchild = pcit - > m_blenderchild ;
2008-09-06 22:06:01 +00:00
struct Object * blenderparent = blenderchild - > parent ;
KX_GameObject * parentobj = converter - > FindGameObject ( blenderparent ) ;
KX_GameObject * childobj = converter - > FindGameObject ( blenderchild ) ;
assert ( childobj ) ;
if ( ! parentobj | | objectlist - > SearchValue ( childobj ) ! = objectlist - > SearchValue ( parentobj ) )
{
// special case: the parent and child object are not in the same layer.
// This weird situation is used in Apricot for test purposes.
2008-09-07 10:47:33 +00:00
// Resolve it by not converting the child
2008-09-06 22:06:01 +00:00
childobj - > GetSGNode ( ) - > DisconnectFromParent ( ) ;
delete pcit - > m_gamechildnode ;
2008-09-07 10:47:33 +00:00
// Now destroy the child object but also all its descendent that may already be linked
// Remove the child reference in the local list!
// Note: there may be descendents already if the children of the child were processed
// by this loop before the child. In that case, we must remove the children also
2009-04-19 12:46:39 +00:00
CListValue * childrenlist = childobj - > GetChildrenRecursive ( ) ;
2008-09-07 10:47:33 +00:00
childrenlist - > Add ( childobj - > AddRef ( ) ) ;
for ( i = 0 ; i < childrenlist - > GetCount ( ) ; i + + )
{
KX_GameObject * obj = static_cast < KX_GameObject * > ( childrenlist - > GetValue ( i ) ) ;
if ( sumolist - > RemoveValue ( obj ) )
obj - > Release ( ) ;
if ( logicbrick_conversionlist - > RemoveValue ( obj ) )
obj - > Release ( ) ;
}
childrenlist - > Release ( ) ;
// now destroy recursively
kxscene - > RemoveObject ( childobj ) ;
2008-09-06 22:06:01 +00:00
continue ;
}
2005-04-23 11:36:44 +00:00
switch ( blenderchild - > partype )
2002-10-12 11:37:38 +00:00
{
2005-04-23 11:36:44 +00:00
case PARVERT1 :
{
// creat a new vertex parent relationship for this node.
KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation : : New ( ) ;
pcit - > m_gamechildnode - > SetParentRelation ( vertex_parent_relation ) ;
break ;
}
case PARSLOW :
{
// creat a new slow parent relationship for this node.
KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation : : New ( blenderchild - > sf ) ;
pcit - > m_gamechildnode - > SetParentRelation ( slow_parent_relation ) ;
break ;
}
case PARBONE :
{
// parent this to a bone
Bone * parent_bone = get_named_bone ( get_armature ( blenderchild - > parent ) , blenderchild - > parsubstr ) ;
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
if ( parent_bone ) {
KX_BoneParentRelation * bone_parent_relation = KX_BoneParentRelation : : New ( parent_bone ) ;
pcit - > m_gamechildnode - > SetParentRelation ( bone_parent_relation ) ;
}
2005-04-23 11:36:44 +00:00
break ;
}
case PARSKEL : // skinned - ignore
break ;
case PAROBJECT :
case PARCURVE :
case PARKEY :
case PARVERT3 :
default :
// unhandled
break ;
}
2002-10-12 11:37:38 +00:00
2008-09-06 22:06:01 +00:00
parentobj - > GetSGNode ( ) - > AddChild ( pcit - > m_gamechildnode ) ;
2002-10-12 11:37:38 +00:00
}
vec_parent_child . clear ( ) ;
// find 'root' parents (object that has not parents in SceneGraph)
2009-05-14 13:47:08 +00:00
for ( i = 0 ; i < sumolist - > GetCount ( ) ; + + i )
2002-10-12 11:37:38 +00:00
{
2009-05-14 13:47:08 +00:00
KX_GameObject * gameobj = ( KX_GameObject * ) sumolist - > GetValue ( i ) ;
2002-10-12 11:37:38 +00:00
if ( gameobj - > GetSGNode ( ) - > GetSGParent ( ) = = 0 )
{
parentlist - > Add ( gameobj - > AddRef ( ) ) ;
2009-04-07 22:14:06 +00:00
gameobj - > NodeUpdateGS ( 0 ) ;
2002-10-12 11:37:38 +00:00
}
}
2009-05-14 13:47:08 +00:00
// create graphic controller for culling
if ( kxscene - > GetDbvtCulling ( ) )
{
bool occlusion = false ;
for ( i = 0 ; i < sumolist - > GetCount ( ) ; i + + )
{
KX_GameObject * gameobj = ( KX_GameObject * ) sumolist - > GetValue ( i ) ;
if ( gameobj - > GetMeshCount ( ) > 0 )
{
MT_Point3 box [ 2 ] ;
gameobj - > GetSGNode ( ) - > BBox ( ) . getmm ( box , MT_Transform : : Identity ( ) ) ;
// box[0] is the min, box[1] is the max
bool isactive = objectlist - > SearchValue ( gameobj ) ;
BL_CreateGraphicObjectNew ( gameobj , box [ 0 ] , box [ 1 ] , kxscene , isactive , physics_engine ) ;
if ( gameobj - > GetOccluder ( ) )
occlusion = true ;
}
}
if ( occlusion )
kxscene - > SetDbvtOcclusionRes ( blenderscene - > world - > occlusionRes ) ;
}
2009-05-21 18:10:19 +00:00
if ( blenderscene - > world )
kxscene - > GetPhysicsEnvironment ( ) - > setNumTimeSubSteps ( blenderscene - > world - > physubstep ) ;
2009-05-14 13:47:08 +00:00
// now that the scenegraph is complete, let's instantiate the deformers.
// We need that to create reusable derived mesh and physic shapes
for ( i = 0 ; i < sumolist - > GetCount ( ) ; + + i )
{
KX_GameObject * gameobj = ( KX_GameObject * ) sumolist - > GetValue ( i ) ;
if ( gameobj - > GetDeformer ( ) )
gameobj - > GetDeformer ( ) - > UpdateBuckets ( ) ;
}
2006-12-01 01:04:27 +00:00
bool processCompoundChildren = false ;
2002-10-12 11:37:38 +00:00
// create physics information
for ( i = 0 ; i < sumolist - > GetCount ( ) ; i + + )
{
KX_GameObject * gameobj = ( KX_GameObject * ) sumolist - > GetValue ( i ) ;
struct Object * blenderobject = converter - > FindBlenderObject ( gameobj ) ;
int nummeshes = gameobj - > GetMeshCount ( ) ;
RAS_MeshObject * meshobj = 0 ;
if ( nummeshes > 0 )
{
meshobj = gameobj - > GetMesh ( 0 ) ;
}
2008-07-15 20:05:23 +00:00
int layerMask = ( groupobj . find ( blenderobject ) = = groupobj . end ( ) ) ? activeLayerBitInfo : 0 ;
BL_CreatePhysicsObjectNew ( gameobj , blenderobject , meshobj , kxscene , layerMask , physics_engine , converter , processCompoundChildren ) ;
2006-12-01 01:04:27 +00:00
}
2002-10-12 11:37:38 +00:00
2006-12-01 01:04:27 +00:00
processCompoundChildren = true ;
// create physics information
for ( i = 0 ; i < sumolist - > GetCount ( ) ; i + + )
{
KX_GameObject * gameobj = ( KX_GameObject * ) sumolist - > GetValue ( i ) ;
struct Object * blenderobject = converter - > FindBlenderObject ( gameobj ) ;
int nummeshes = gameobj - > GetMeshCount ( ) ;
RAS_MeshObject * meshobj = 0 ;
if ( nummeshes > 0 )
{
meshobj = gameobj - > GetMesh ( 0 ) ;
}
2008-07-15 20:05:23 +00:00
int layerMask = ( groupobj . find ( blenderobject ) = = groupobj . end ( ) ) ? activeLayerBitInfo : 0 ;
BL_CreatePhysicsObjectNew ( gameobj , blenderobject , meshobj , kxscene , layerMask , physics_engine , converter , processCompoundChildren ) ;
2002-10-12 11:37:38 +00:00
}
2006-12-16 05:50:38 +00:00
//set ini linearVel and int angularVel //rcruiz
if ( converter - > addInitFromFrame )
for ( i = 0 ; i < sumolist - > GetCount ( ) ; i + + )
{
KX_GameObject * gameobj = ( KX_GameObject * ) sumolist - > GetValue ( i ) ;
if ( gameobj - > IsDynamic ( ) ) {
gameobj - > setLinearVelocity ( inivel [ i ] , false ) ;
gameobj - > setAngularVelocity ( iniang [ i ] , false ) ;
}
}
2006-12-01 01:04:27 +00:00
2006-11-30 00:19:27 +00:00
// create physics joints
for ( i = 0 ; i < sumolist - > GetCount ( ) ; i + + )
{
KX_GameObject * gameobj = ( KX_GameObject * ) sumolist - > GetValue ( i ) ;
struct Object * blenderobject = converter - > FindBlenderObject ( gameobj ) ;
2008-05-05 17:29:11 +00:00
ListBase * conlist ;
bConstraint * curcon ;
conlist = get_active_constraints2 ( blenderobject ) ;
2006-12-02 22:25:47 +00:00
2008-05-05 17:29:11 +00:00
if ( conlist ) {
for ( curcon = ( bConstraint * ) conlist - > first ; curcon ; curcon = ( bConstraint * ) curcon - > next ) {
if ( curcon - > type = = CONSTRAINT_TYPE_RIGIDBODYJOINT ) {
bRigidBodyJointConstraint * dat = ( bRigidBodyJointConstraint * ) curcon - > data ;
if ( ! dat - > child ) {
PHY_IPhysicsController * physctr2 = 0 ;
if ( dat - > tar )
{
KX_GameObject * gotar = getGameOb ( dat - > tar - > id . name , sumolist ) ;
if ( gotar & & gotar - > GetPhysicsController ( ) )
physctr2 = ( PHY_IPhysicsController * ) gotar - > GetPhysicsController ( ) - > GetUserData ( ) ;
}
2006-12-18 07:51:12 +00:00
2008-05-05 17:29:11 +00:00
if ( gameobj - > GetPhysicsController ( ) )
{
float radsPerDeg = 6.283185307179586232f / 360.f ;
PHY_IPhysicsController * physctrl = ( PHY_IPhysicsController * ) gameobj - > GetPhysicsController ( ) - > GetUserData ( ) ;
//we need to pass a full constraint frame, not just axis
2006-12-02 22:25:47 +00:00
2008-05-05 17:29:11 +00:00
//localConstraintFrameBasis
MT_Matrix3x3 localCFrame ( MT_Vector3 ( radsPerDeg * dat - > axX , radsPerDeg * dat - > axY , radsPerDeg * dat - > axZ ) ) ;
MT_Vector3 axis0 = localCFrame . getColumn ( 0 ) ;
MT_Vector3 axis1 = localCFrame . getColumn ( 1 ) ;
MT_Vector3 axis2 = localCFrame . getColumn ( 2 ) ;
2006-12-16 05:50:38 +00:00
2008-05-05 17:29:11 +00:00
int constraintId = kxscene - > GetPhysicsEnvironment ( ) - > createConstraint ( physctrl , physctr2 , ( PHY_ConstraintType ) dat - > type , ( float ) dat - > pivX ,
( float ) dat - > pivY , ( float ) dat - > pivZ ,
2006-12-16 05:50:38 +00:00
( float ) axis0 . x ( ) , ( float ) axis0 . y ( ) , ( float ) axis0 . z ( ) ,
( float ) axis1 . x ( ) , ( float ) axis1 . y ( ) , ( float ) axis1 . z ( ) ,
2008-10-10 05:12:57 +00:00
( float ) axis2 . x ( ) , ( float ) axis2 . y ( ) , ( float ) axis2 . z ( ) , dat - > flag ) ;
2008-05-05 17:29:11 +00:00
if ( constraintId )
{
//if it is a generic 6DOF constraint, set all the limits accordingly
if ( dat - > type = = PHY_GENERIC_6DOF_CONSTRAINT )
2006-12-02 03:48:36 +00:00
{
2008-05-05 17:29:11 +00:00
int dof ;
int dofbit = 1 ;
for ( dof = 0 ; dof < 6 ; dof + + )
2006-12-02 03:48:36 +00:00
{
2008-05-05 17:29:11 +00:00
if ( dat - > flag & dofbit )
2006-12-02 22:25:47 +00:00
{
2008-05-05 17:29:11 +00:00
kxscene - > GetPhysicsEnvironment ( ) - > setConstraintParam ( constraintId , dof , dat - > minLimit [ dof ] , dat - > maxLimit [ dof ] ) ;
} else
{
//minLimit > maxLimit means free(disabled limit) for this degree of freedom
kxscene - > GetPhysicsEnvironment ( ) - > setConstraintParam ( constraintId , dof , 1 , - 1 ) ;
2006-12-02 22:25:47 +00:00
}
2008-05-05 17:29:11 +00:00
dofbit < < = 1 ;
2006-12-02 03:48:36 +00:00
}
}
}
2008-05-05 17:29:11 +00:00
}
}
}
}
}
2006-11-30 00:19:27 +00:00
}
2002-10-12 11:37:38 +00:00
sumolist - > Release ( ) ;
// convert global sound stuff
/* XXX, glob is the very very wrong place for this
* to be , re - enable once the listener has been moved into
* the scene . */
2004-12-29 01:31:17 +00:00
# if 1
2002-10-12 11:37:38 +00:00
SND_Scene * soundscene = kxscene - > GetSoundScene ( ) ;
SND_SoundListener * listener = soundscene - > GetListener ( ) ;
2004-12-29 01:31:17 +00:00
if ( listener & & G . listener )
2002-10-12 11:37:38 +00:00
{
2004-12-29 01:31:17 +00:00
listener - > SetDopplerFactor ( G . listener - > dopplerfactor ) ;
listener - > SetDopplerVelocity ( G . listener - > dopplervelocity ) ;
listener - > SetGain ( G . listener - > gain ) ;
2002-10-12 11:37:38 +00:00
}
# endif
// convert world
KX_WorldInfo * worldinfo = new BlenderWorldInfo ( blenderscene - > world ) ;
converter - > RegisterWorldInfo ( worldinfo ) ;
kxscene - > SetWorldInfo ( worldinfo ) ;
2005-07-16 21:47:54 +00:00
# define CONVERT_LOGIC
# ifdef CONVERT_LOGIC
2002-10-12 11:37:38 +00:00
// convert logic bricks, sensors, controllers and actuators
for ( i = 0 ; i < logicbrick_conversionlist - > GetCount ( ) ; i + + )
{
KX_GameObject * gameobj = static_cast < KX_GameObject * > ( logicbrick_conversionlist - > GetValue ( i ) ) ;
struct Object * blenderobj = converter - > FindBlenderObject ( gameobj ) ;
2008-07-15 20:05:23 +00:00
int layerMask = ( groupobj . find ( blenderobj ) = = groupobj . end ( ) ) ? activeLayerBitInfo : 0 ;
bool isInActiveLayer = ( blenderobj - > lay & layerMask ) ! = 0 ;
2009-05-10 20:53:58 +00:00
BL_ConvertActuators ( maggie - > name , blenderobj , gameobj , logicmgr , kxscene , ketsjiEngine , layerMask , isInActiveLayer , rendertools , converter ) ;
2002-10-12 11:37:38 +00:00
}
for ( i = 0 ; i < logicbrick_conversionlist - > GetCount ( ) ; i + + )
{
KX_GameObject * gameobj = static_cast < KX_GameObject * > ( logicbrick_conversionlist - > GetValue ( i ) ) ;
struct Object * blenderobj = converter - > FindBlenderObject ( gameobj ) ;
2008-07-15 20:05:23 +00:00
int layerMask = ( groupobj . find ( blenderobj ) = = groupobj . end ( ) ) ? activeLayerBitInfo : 0 ;
bool isInActiveLayer = ( blenderobj - > lay & layerMask ) ! = 0 ;
2009-05-10 20:53:58 +00:00
BL_ConvertControllers ( blenderobj , gameobj , logicmgr , pythondictionary , layerMask , isInActiveLayer , converter ) ;
2002-10-12 11:37:38 +00:00
}
for ( i = 0 ; i < logicbrick_conversionlist - > GetCount ( ) ; i + + )
{
KX_GameObject * gameobj = static_cast < KX_GameObject * > ( logicbrick_conversionlist - > GetValue ( i ) ) ;
struct Object * blenderobj = converter - > FindBlenderObject ( gameobj ) ;
2008-07-15 20:05:23 +00:00
int layerMask = ( groupobj . find ( blenderobj ) = = groupobj . end ( ) ) ? activeLayerBitInfo : 0 ;
bool isInActiveLayer = ( blenderobj - > lay & layerMask ) ! = 0 ;
2009-05-10 20:53:58 +00:00
BL_ConvertSensors ( blenderobj , gameobj , logicmgr , kxscene , ketsjiEngine , keydev , layerMask , isInActiveLayer , canvas , converter ) ;
2008-07-30 17:41:47 +00:00
// set the init state to all objects
gameobj - > SetInitState ( ( blenderobj - > init_state ) ? blenderobj - > init_state : blenderobj - > state ) ;
2002-10-12 11:37:38 +00:00
}
2008-07-30 17:41:47 +00:00
// apply the initial state to controllers, only on the active objects as this registers the sensors
for ( i = 0 ; i < objectlist - > GetCount ( ) ; i + + )
BGE patch: add state engine support in the logic bricks.
This patch introduces a simple state engine system with the logic bricks. This system features full
backward compatibility, multiple active states, multiple state transitions, automatic disabling of
sensor and actuators, full GUI support and selective display of sensors and actuators.
Note: Python API is available but not documented yet. It will be added asap.
State internals
===============
The state system is object based. The current state mask is stored in the object as a 32 bit value;
each bit set in the mask is an active state. The controllers have a state mask too but only one bit
can be set: a controller belongs to a single state. The game engine will only execute controllers
that belong to active states. Sensors and actuators don't have a state mask but are effectively
attached to states via their links to the controllers. Sensors and actuators can be connected to more
than one state. When a controller becomes inactive because of a state change, its links to sensors
and actuators are temporarily broken (until the state becomes active again). If an actuator gets isolated,
i.e all the links to controllers are broken, it is automatically disabled. If a sensor gets isolated,
the game engine will stop calling it to save CPU. It will also reset the sensor internal state so that
it can react as if the game just started when it gets reconnected to an active controller. For example,
an Always sensor in no pulse mode that is connected to a single state (i.e connected to one or more
controllers of a single state) will generate a pulse each time the state becomes active. This feature is
not available on all sensors, see the notes below.
GUI
===
This system system is fully configurable through the GUI: the object state mask is visible under the
object bar in the controller's colum as an array of buttons just like the 3D view layer mask.
Click on a state bit to only display the controllers of that state. You can select more than one state
with SHIFT-click. The All button sets all the bits so that you can see all the controllers of the object.
The Ini button sets the state mask back to the object default state. You can change the default state
of object by first selecting the desired state mask and storing using the menu under the State button.
If you define a default state mask, it will be loaded into the object state make when you load the blend
file or when you run the game under the blenderplayer. However, when you run the game under Blender,
the current selected state mask will be used as the startup state for the object. This allows you to test
specific state during the game design.
The controller display the state they belong to with a new button in the controller header. When you add
a new controller, it is added by default in the lowest enabled state. You can change the controller state
by clicking on the button and selecting another state. If more than one state is enabled in the object
state mask, controllers are grouped by state for more readibility.
The new Sta button in the sensor and actuator column header allows you to display only the sensors and
actuators that are linked to visible controllers.
A new state actuator is available to modify the state during the game. It defines a bit mask and
the operation to apply on the current object state mask:
Cpy: the bit mask is copied to the object state mask.
Add: the bits that set in the bit mask will be turned on in the object state mask.
Sub: the bits that set in the bit mask will be turned off in the object state mask.
Inv: the bits that set in the bit mask will be inverted in the objecyy state mask.
Notes
=====
- Although states have no name, a simply convention consists in using the name of the first controller
of the state as the state name. The GUI will support that convention by displaying as a hint the name
of the first controller of the state when you move the mouse over a state bit of the object state mask
or of the state actuator bit mask.
- Each object has a state mask and each object can have a state engine but if several objects are
part of a logical group, it is recommended to put the state engine only in the main object and to
link the controllers of that object to the sensors and actuators of the different objects.
- When loading an old blend file, the state mask of all objects and controllers are initialized to 1
so that all the controllers belong to this single state. This ensures backward compatibility with
existing game.
- When the state actuator is activated at the same time as other actuators, these actuators are
guaranteed to execute before being eventually disabled due to the state change. This is useful for
example to send a message or update a property at the time of changing the state.
- Sensors that depend on underlying resource won't reset fully when they are isolated. By the time they
are acticated again, they will behave as follow:
* keyboard sensor: keys already pressed won't be detected. The keyboard sensor is only sensitive
to new key press.
* collision sensor: objects already colliding won't be detected. Only new collisions are
detected.
* near and radar sensor: same as collision sensor.
2008-06-22 14:23:57 +00:00
{
2008-07-30 17:41:47 +00:00
KX_GameObject * gameobj = static_cast < KX_GameObject * > ( objectlist - > GetValue ( i ) ) ;
BGE logic patch: new "Add" mode for Ipo actuator, several corrections in state system.
New Add mode for Ipo actuator
=============================
A new Add button, mutually exclusive with Force button, is available in
the Ipo actuator. When selected, it activates the Add mode that consists
in adding the Ipo curve to the current object situation in world
coordinates, or parent coordinates if the object has a parent. Scale Ipo
curves are multiplied instead of added to the object current scale.
If the local flag is selected, the Ipo curve is added (multiplied) in
the object's local coordinates.
Delta Ipo curves are handled identically to normal Ipo curve and there
is no need to work with Delta Ipo curves provided that you make sure
that the Ipo curve starts from origin. Origin means location 0 for
Location Ipo curve, rotation 0 for Rotation Ipo curve and scale 1 for
Scale Ipo curve.
The "current object situation" means the object's location, rotation
and scale at the start of the Ipo curve. For Loop Stop and Loop End Ipo
actuators, this means at the start of each loop. This initial state is
used as a base during the execution of the Ipo Curve but when the Ipo
curve is restarted (later or immediately in case of Loop mode), the
object current situation at that time is used as the new base.
For reference, here is the exact operation of the Add mode for each
type of Ipo curve (oLoc, oRot, oScale, oMat: object's loc/rot/scale
and orientation matrix at the start of the curve; iLoc, iRot, iScale,
iMat: Ipo curve loc/rot/scale and orientation matrix resulting from
the rotation).
Location
Local=false: newLoc = oLoc+iLoc
Local=true : newLoc = oLoc+oScale*(oMat*iLoc)
Rotation
Local=false: newMat = iMat*oMat
Local=true : newMat = oMat*iMat
Scale
Local=false: newScale = oScale*iScale
Local=true : newScale = oScale*iScale
Add+Local mode is very useful to have dynamic object executing complex
movement relative to their current location/orientation. Of cource,
dynamics should be disabled during the execution of the curve.
Several corrections in state system
===================================
- Object initial state is taken into account when adding object
dynamically
- Fix bug with link count when adding object dynamically
- Fix false on-off detection for Actuator sensor when actuator is
trigged on negative event.
- Fix Parent actuator false activation on negative event
- Loop Ipo curve not restarting at correct frame when start frame is
different from one.
2008-07-08 12:18:43 +00:00
gameobj - > ResetState ( ) ;
BGE patch: add state engine support in the logic bricks.
This patch introduces a simple state engine system with the logic bricks. This system features full
backward compatibility, multiple active states, multiple state transitions, automatic disabling of
sensor and actuators, full GUI support and selective display of sensors and actuators.
Note: Python API is available but not documented yet. It will be added asap.
State internals
===============
The state system is object based. The current state mask is stored in the object as a 32 bit value;
each bit set in the mask is an active state. The controllers have a state mask too but only one bit
can be set: a controller belongs to a single state. The game engine will only execute controllers
that belong to active states. Sensors and actuators don't have a state mask but are effectively
attached to states via their links to the controllers. Sensors and actuators can be connected to more
than one state. When a controller becomes inactive because of a state change, its links to sensors
and actuators are temporarily broken (until the state becomes active again). If an actuator gets isolated,
i.e all the links to controllers are broken, it is automatically disabled. If a sensor gets isolated,
the game engine will stop calling it to save CPU. It will also reset the sensor internal state so that
it can react as if the game just started when it gets reconnected to an active controller. For example,
an Always sensor in no pulse mode that is connected to a single state (i.e connected to one or more
controllers of a single state) will generate a pulse each time the state becomes active. This feature is
not available on all sensors, see the notes below.
GUI
===
This system system is fully configurable through the GUI: the object state mask is visible under the
object bar in the controller's colum as an array of buttons just like the 3D view layer mask.
Click on a state bit to only display the controllers of that state. You can select more than one state
with SHIFT-click. The All button sets all the bits so that you can see all the controllers of the object.
The Ini button sets the state mask back to the object default state. You can change the default state
of object by first selecting the desired state mask and storing using the menu under the State button.
If you define a default state mask, it will be loaded into the object state make when you load the blend
file or when you run the game under the blenderplayer. However, when you run the game under Blender,
the current selected state mask will be used as the startup state for the object. This allows you to test
specific state during the game design.
The controller display the state they belong to with a new button in the controller header. When you add
a new controller, it is added by default in the lowest enabled state. You can change the controller state
by clicking on the button and selecting another state. If more than one state is enabled in the object
state mask, controllers are grouped by state for more readibility.
The new Sta button in the sensor and actuator column header allows you to display only the sensors and
actuators that are linked to visible controllers.
A new state actuator is available to modify the state during the game. It defines a bit mask and
the operation to apply on the current object state mask:
Cpy: the bit mask is copied to the object state mask.
Add: the bits that set in the bit mask will be turned on in the object state mask.
Sub: the bits that set in the bit mask will be turned off in the object state mask.
Inv: the bits that set in the bit mask will be inverted in the objecyy state mask.
Notes
=====
- Although states have no name, a simply convention consists in using the name of the first controller
of the state as the state name. The GUI will support that convention by displaying as a hint the name
of the first controller of the state when you move the mouse over a state bit of the object state mask
or of the state actuator bit mask.
- Each object has a state mask and each object can have a state engine but if several objects are
part of a logical group, it is recommended to put the state engine only in the main object and to
link the controllers of that object to the sensors and actuators of the different objects.
- When loading an old blend file, the state mask of all objects and controllers are initialized to 1
so that all the controllers belong to this single state. This ensures backward compatibility with
existing game.
- When the state actuator is activated at the same time as other actuators, these actuators are
guaranteed to execute before being eventually disabled due to the state change. This is useful for
example to send a message or update a property at the time of changing the state.
- Sensors that depend on underlying resource won't reset fully when they are isolated. By the time they
are acticated again, they will behave as follow:
* keyboard sensor: keys already pressed won't be detected. The keyboard sensor is only sensitive
to new key press.
* collision sensor: objects already colliding won't be detected. Only new collisions are
detected.
* near and radar sensor: same as collision sensor.
2008-06-22 14:23:57 +00:00
}
2005-07-16 21:47:54 +00:00
# endif //CONVERT_LOGIC
2002-10-12 11:37:38 +00:00
logicbrick_conversionlist - > Release ( ) ;
2004-05-16 12:52:08 +00:00
// Calculate the scene btree -
// too slow - commented out.
//kxscene->SetNodeTree(tf.MakeTree());
2008-07-15 20:05:23 +00:00
// instantiate dupli group, we will loop trough the object
// that are in active layers. Note that duplicating group
// has the effect of adding objects at the end of objectlist.
// Only loop through the first part of the list.
int objcount = objectlist - > GetCount ( ) ;
for ( i = 0 ; i < objcount ; i + + )
{
KX_GameObject * gameobj = ( KX_GameObject * ) objectlist - > GetValue ( i ) ;
if ( gameobj - > IsDupliGroup ( ) )
{
kxscene - > DupliGroupRecurse ( gameobj , 0 ) ;
}
}
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
KX_Camera * activecam = kxscene - > GetActiveCamera ( ) ;
MT_Scalar distance = ( activecam ) ? activecam - > GetCameraFar ( ) - activecam - > GetCameraNear ( ) : 100.0f ;
RAS_BucketManager * bucketmanager = kxscene - > GetBucketManager ( ) ;
bucketmanager - > OptimizeBuckets ( distance ) ;
2002-10-12 11:37:38 +00:00
}
2004-05-16 12:52:08 +00:00