diff options
53 files changed, 1022 insertions, 1594 deletions
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index 397cc301627..3865729fe56 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -34,7 +34,7 @@ PROJECT_NAME = Blender # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = "V2.6x" +PROJECT_NUMBER = "V2.7x" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/doc/doxygen/doxygen.main b/doc/doxygen/doxygen.main index 188382d6a9c..7f63764d7c6 100644 --- a/doc/doxygen/doxygen.main +++ b/doc/doxygen/doxygen.main @@ -7,7 +7,7 @@ * These pages document the source code of blender. * * \subsection implinks Important Links - * - <a href="http://projects.blender.org">projects.blender.org</a> with <a href="http://projects.blender.org/tracker/index.php?group_id=9&atid=498">bug tracker</a> + * - <a href="http://developer.blender.org">developer.blender.org</a> with bug tracker * - <a href="http://wiki.blender.org/index.php/Dev:Contents">Development documents</a> on our wiki. * * \subsection blother Other diff --git a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst index a6d03dee1a1..1ee0ad9252a 100644 --- a/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst +++ b/doc/python_api/rst/bge_types/bge.types.KX_GameObject.rst @@ -124,13 +124,13 @@ base class --- :class:`SCA_IObject` .. attribute:: groupMembers - Returns the list of group members if the object is a group object, otherwise None is returned. + Returns the list of group members if the object is a group object (dupli group instance), otherwise None is returned. :type: :class:`CListValue` of :class:`KX_GameObject` or None .. attribute:: groupObject - Returns the group object that the object belongs to or None if the object is not part of a group. + Returns the group object (dupli group instance) that the object belongs to or None if the object is not part of a group. :type: :class:`KX_GameObject` or None @@ -876,4 +876,4 @@ base class --- :class:`SCA_IObject` :arg name: name of the property that added to the debug list. :type name: string :arg debug: the debug state. - :type debug: boolean
\ No newline at end of file + :type debug: boolean diff --git a/doc/python_api/rst/bgl.rst b/doc/python_api/rst/bgl.rst index dfdb4a17998..67d0c59aa32 100644 --- a/doc/python_api/rst/bgl.rst +++ b/doc/python_api/rst/bgl.rst @@ -8,19 +8,17 @@ This module wraps OpenGL constants and functions, making them available from within Blender Python. The complete list can be retrieved from the module itself, by listing its -contents: dir(bgl). A simple search on the net can point to more +contents: dir(bgl). A simple search on the web can point to more than enough material to teach OpenGL programming, from books to many collections of tutorials. -The "red book": "I{OpenGL Programming Guide: The Official Guide to Learning -OpenGL}" and the online NeHe tutorials are two of the best resources. +Here is a comprehensive `list of books <http://www.opengl.org/documentation/books/>`_ (non free). The `arcsynthesis tutorials <http://www.arcsynthesis.org/gltut/>`_ is one of the best resources to learn modern OpenGL and `g-truc <http://www.g-truc.net/post-tech-content-sample.html>`_ offers a set of extensive examples, including advanced features. + .. note:: You can use the :class:`Image` type to load and set textures. See :class:`Image.gl_load` and :class:`Image.gl_load`, for example. - `OpenGL.org <http://www.opengl.org>`_ - `NeHe GameDev <http://nehe.gamedev.net>`_ .. function:: glAccum(op, value): diff --git a/extern/bullet2/Bullet_User_Manual.pdf b/extern/bullet2/Bullet_User_Manual.pdf Binary files differnew file mode 100644 index 00000000000..e68a9169834 --- /dev/null +++ b/extern/bullet2/Bullet_User_Manual.pdf diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index 503b3cd234c..cefddae0586 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -56,7 +56,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel): layout.prop(game, "jump_speed") layout.prop(game, "fall_speed") - elif physics_type in {'DYNAMIC', 'RIGID_BODY'}: + elif physics_type in {'DYNAMIC', 'RIGID_BODY', 'VEHICLE'}: split = layout.split() col = split.column() @@ -209,7 +209,7 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel): def poll(cls, context): game = context.object.game rd = context.scene.render - return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC', 'CHARACTER'}) and (rd.engine in cls.COMPAT_ENGINES) + return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC', 'CHARACTER', 'VEHICLE'}) and (rd.engine in cls.COMPAT_ENGINES) def draw_header(self, context): game = context.active_object.game @@ -226,8 +226,9 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel): row = layout.row() row.prop(game, "collision_margin", text="Margin", slider=True) - row.prop(game, "use_collision_compound", text="Compound") - + sub = row.row() + sub.active = game.physics_type not in {'SOFT_BODY', 'CHARACTER', 'VEHICLE'} + sub.prop(game, "use_collision_compound", text="Compound") class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel): bl_label = "Create Obstacle" diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py index 2494e49d812..1eddfbdf556 100644 --- a/release/scripts/startup/bl_ui/properties_render_layer.py +++ b/release/scripts/startup/bl_ui/properties_render_layer.py @@ -56,6 +56,10 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel): scene = context.scene rd = scene.render + if rd.engine == 'BLENDER_GAME': + layout.label("Not available in the Game Engine") + return + row = layout.row() col = row.column() col.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2) diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 049161fdce8..d172596d51f 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -62,7 +62,8 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel): layout.prop(scene, "camera") layout.prop(scene, "background_set", text="Background") - layout.prop(scene, "active_clip", text="Active Clip") + if context.scene.render.engine != 'BLENDER_GAME': + layout.prop(scene, "active_clip", text="Active Clip") class SCENE_PT_unit(SceneButtonsPanel, Panel): diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 8f74df72b04..fb6b65d7a00 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2403,20 +2403,12 @@ static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4 static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4]) { - float *fp1, *fp2; - float fac1, fac2; - int a; + float fac1 = (1.0f / (1.0f + fabsf(ob->sf)) ); - /* include framerate */ - fac1 = (1.0f / (1.0f + fabsf(ob->sf))); - if (fac1 >= 1.0f) return false; - fac2 = 1.0f - fac1; + if (fac1 >= 1.0f) + return false; - fp1 = obmat[0]; - fp2 = slowmat[0]; - for (a = 0; a < 16; a++, fp1++, fp2++) { - fp1[0] = fac1 * fp1[0] + fac2 * fp2[0]; - } + blend_m4_m4m4(obmat, slowmat, obmat, fac1); return true; } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index c3edd63b2d4..cbfb59e2eb2 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -423,7 +423,7 @@ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const floa /* Ignore collisions by default for non-mesh objects */ if (type != OB_MESH) { ob->body_type = OB_BODY_TYPE_NO_COLLISION; - ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH); /* copied from rna_object.c */ + ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_VEHICLE | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH); /* copied from rna_object.c */ } DAG_id_type_tag(bmain, ID_OB); diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 0bcc6bfd70e..2fffd2a7937 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -560,6 +560,8 @@ enum { OB_CHARACTER = 1 << 22, OB_RECORD_ANIMATION = 1 << 23, + + OB_VEHICLE = 1 << 24, }; /* ob->gameflag2 */ @@ -586,6 +588,7 @@ enum { OB_BODY_TYPE_SENSOR = 6, OB_BODY_TYPE_NAVMESH = 7, OB_BODY_TYPE_CHARACTER = 8, + OB_BODY_TYPE_VEHICLE = 9, }; /* ob->depsflag */ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index f9a76005df8..d83bf2ac0c9 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -508,7 +508,9 @@ static EnumPropertyItem *rna_Object_collision_bounds_itemf(bContext *UNUSED(C), EnumPropertyItem *item = NULL; int totitem = 0; - RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_TRIANGLE_MESH); + if (ob->body_type != OB_BODY_TYPE_CHARACTER && ob->body_type != OB_BODY_TYPE_VEHICLE) { + RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_TRIANGLE_MESH); + } RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_CONVEX_HULL); if (ob->body_type != OB_BODY_TYPE_SOFT) { @@ -982,6 +984,9 @@ static int rna_GameObjectSettings_physics_type_get(PointerRNA *ptr) else if (ob->gameflag & OB_CHARACTER) { ob->body_type = OB_BODY_TYPE_CHARACTER; } + else if (ob->gameflag & OB_VEHICLE) { + ob->body_type = OB_BODY_TYPE_VEHICLE; + } else if (ob->gameflag & OB_SENSOR) { ob->body_type = OB_BODY_TYPE_SENSOR; } @@ -1013,16 +1018,16 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value) switch (ob->body_type) { case OB_BODY_TYPE_SENSOR: ob->gameflag |= OB_SENSOR | OB_COLLISION; - ob->gameflag &= ~(OB_OCCLUDER | OB_CHARACTER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR | + ob->gameflag &= ~(OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR | OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH); break; case OB_BODY_TYPE_OCCLUDER: ob->gameflag |= OB_OCCLUDER; - ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_DYNAMIC | OB_NAVMESH); + ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_VEHICLE | OB_DYNAMIC | OB_NAVMESH); break; case OB_BODY_TYPE_NAVMESH: ob->gameflag |= OB_NAVMESH; - ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_DYNAMIC | OB_OCCLUDER); + ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_VEHICLE | OB_DYNAMIC | OB_OCCLUDER); if (ob->type == OB_MESH) { /* could be moved into mesh UI but for now ensure mesh data layer */ @@ -1031,29 +1036,34 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value) break; case OB_BODY_TYPE_NO_COLLISION: - ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH); + ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_VEHICLE | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH); break; case OB_BODY_TYPE_CHARACTER: ob->gameflag |= OB_COLLISION | OB_CHARACTER; - ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR | + ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_VEHICLE | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR | + OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH); + break; + case OB_BODY_TYPE_VEHICLE: + ob->gameflag |= OB_COLLISION | OB_VEHICLE; + ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_CHARACTER | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR | OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH); break; case OB_BODY_TYPE_STATIC: ob->gameflag |= OB_COLLISION; - ob->gameflag &= ~(OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH); + ob->gameflag &= ~(OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_SENSOR | OB_NAVMESH); break; case OB_BODY_TYPE_DYNAMIC: ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_ACTOR; - ob->gameflag &= ~(OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH); + ob->gameflag &= ~(OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_SENSOR | OB_NAVMESH); break; case OB_BODY_TYPE_RIGID: ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_RIGID_BODY | OB_ACTOR; - ob->gameflag &= ~(OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH); + ob->gameflag &= ~(OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_SENSOR | OB_NAVMESH); break; default: case OB_BODY_TYPE_SOFT: ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_SOFT_BODY | OB_ACTOR; - ob->gameflag &= ~(OB_RIGID_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH); + ob->gameflag &= ~(OB_RIGID_BODY | OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_SENSOR | OB_NAVMESH); /* assume triangle mesh, if no bounds chosen for soft body */ if ((ob->gameflag & OB_BOUNDS) && (ob->boundtype < OB_BOUND_TRIANGLE_MESH)) { @@ -1638,6 +1648,8 @@ static void rna_def_object_game_settings(BlenderRNA *brna) {OB_BODY_TYPE_NAVMESH, "NAVMESH", 0, "Navigation Mesh", "Navigation mesh"}, {OB_BODY_TYPE_CHARACTER, "CHARACTER", 0, "Character", "Simple kinematic physics appropriate for game characters"}, + {OB_BODY_TYPE_VEHICLE, "VEHICLE", 0, "Vehicle", + "Simple kinematic physics appropriate for vehicles"}, {0, NULL, 0, NULL, NULL} }; @@ -1735,7 +1747,9 @@ static void rna_def_object_game_settings(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "max_vel"); RNA_def_property_range(prop, 0.0, 1000.0); RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed"); - + + /* Vehicle physics */ + /* Character physics */ prop = RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "step_height"); @@ -1752,6 +1766,8 @@ static void rna_def_object_game_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0, 1000.0); RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall"); + + /* Collision Masks */ prop = RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER); RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1); diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 60b8832b44e..0d2e97bf96e 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -471,7 +471,6 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c // create a scene converter, create and convert the startingscene KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); ketsjiengine->SetSceneConverter(sceneconverter); - sceneconverter->addInitFromFrame=false; if (always_use_expand_framing) sceneconverter->SetAlwaysUseExpandFraming(true); diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index 31f3b1b2047..2cb79c04b95 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -67,6 +67,7 @@ m_frame_rect(rect) // area boundaries needed for mouse coordinates in Letterbox framing mode m_area_left = ar->winrct.xmin; m_area_top = ar->winrct.ymax; + m_frame = 1; glGetIntegerv(GL_VIEWPORT, (GLint *)m_viewport); } @@ -350,6 +351,8 @@ void KX_BlenderCanvas::MakeScreenShot(const char *filename) char path[FILE_MAX]; BLI_strncpy(path, filename, sizeof(path)); BLI_path_abs(path, G.main->name); + BLI_path_frame(path, m_frame, 0); + m_frame++; BKE_add_image_extension_from_type(path, im_format.imtype); /* create and save imbuf */ diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h index 917e0136cb1..c150af21230 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h @@ -210,6 +210,7 @@ private: RAS_Rect m_area_rect; int m_area_left; int m_area_top; + int m_frame; #ifdef WITH_CXX_GUARDEDALLOC diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index c6140743950..e4f20359079 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -52,23 +52,13 @@ #include <algorithm> #include "BL_BlenderDataConversion.h" -#include "KX_BlenderScalarInterpolator.h" -#include "RAS_IPolygonMaterial.h" - -// Expressions -#include "ListValue.h" -#include "IntValue.h" -// Collision & Fuzzics LTD +#include "MT_Matrix3x3.h" +#include "MT_MinMax.h" #include "PHY_Pro.h" #include "PHY_IPhysicsEnvironment.h" -#include "PHY_DynamicTypes.h" - -#include "KX_Scene.h" -#include "KX_GameObject.h" -#include "RAS_FramingManager.h" #include "RAS_MeshObject.h" #include "RAS_IRasterizer.h" #include "RAS_ILightObject.h" @@ -76,31 +66,27 @@ #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_ClientObjectInfo.h" +#include "KX_Scene.h" +#include "KX_GameObject.h" #include "KX_Light.h" #include "KX_Camera.h" -#include "KX_ClientObjectInfo.h" #include "KX_EmptyObject.h" #include "KX_FontObject.h" -#include "MT_Point3.h" -#include "MT_Transform.h" -#include "MT_MinMax.h" -#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_IPolygonMaterial.h" #include "BL_Material.h" #include "KX_BlenderMaterial.h" #include "BL_Texture.h" -#include "DNA_action_types.h" #include "BKE_main.h" #include "BKE_global.h" #include "BKE_object.h" @@ -109,9 +95,10 @@ #include "BL_SkinDeformer.h" #include "BL_MeshDeformer.h" #include "KX_SoftBodyDeformer.h" -//#include "BL_ArmatureController.h" + #include "BLI_utildefines.h" #include "BLI_listbase.h" + #include "BlenderWorldInfo.h" #include "KX_KetsjiEngine.h" @@ -143,13 +130,14 @@ #include "DNA_sound_types.h" #include "DNA_key_types.h" #include "DNA_armature_types.h" +#include "DNA_action_types.h" #include "DNA_object_force.h" +#include "DNA_constraint_types.h" #include "MEM_guardedalloc.h" #include "BKE_key.h" #include "BKE_mesh.h" -#include "MT_Point3.h" #include "BLI_math.h" @@ -170,29 +158,18 @@ extern Material defmaterial; /* material.c */ #include "KX_BlenderInputDevice.h" #include "KX_ConvertProperties.h" -#include "KX_HashedPtr.h" - - -#include "KX_ScalarInterpolator.h" - -#include "KX_IpoConvert.h" -#include "BL_System.h" #include "SG_Node.h" #include "SG_BBox.h" -#include "SG_Tree.h" +#include "KX_SG_NodeRelationships.h" +#include "KX_SG_BoneParentNodeRelationship.h" #ifdef WITH_BULLET #include "CcdPhysicsEnvironment.h" #include "CcdGraphicController.h" #endif -#include "KX_MotionState.h" - -// This file defines relationships between parents and children -// in the game engine. -#include "KX_SG_NodeRelationships.h" -#include "KX_SG_BoneParentNodeRelationship.h" +#include "KX_MotionState.h" #include "BL_ArmatureObject.h" #include "BL_DeformableGameObject.h" @@ -200,18 +177,9 @@ extern Material defmaterial; /* material.c */ #include "KX_NavMeshObject.h" #include "KX_ObstacleSimulation.h" -#ifdef __cplusplus -extern "C" { -#endif -//XXX void update_for_newframe(); -//void BKE_scene_update_for_newframe(struct Scene *sce, unsigned int lay); -//void do_all_data_ipos(void); -#ifdef __cplusplus -} -#endif - #include "BLI_threads.h" + static bool default_light_mode = 0; static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table() @@ -389,6 +357,11 @@ static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table() static std::map<int, SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable = create_translate_table(); +SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code) +{ + return gReverseKeyTranslateTable[key_code]; +} + static unsigned int KX_rgbaint2uint_new(unsigned int icol) { union @@ -889,10 +862,10 @@ static bool ConvertMaterial( // swap the material color, so MCol on bitmap font works if (validmat && (use_vcol == false) && (mat->game.flag & GEMAT_TEXT)) { - 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]); + material->rgb[0] = KX_rgbaint2uint_new(rgb[0]); + material->rgb[1] = KX_rgbaint2uint_new(rgb[1]); + material->rgb[2] = KX_rgbaint2uint_new(rgb[2]); + material->rgb[3] = KX_rgbaint2uint_new(rgb[3]); } if (validmat) @@ -1389,16 +1362,14 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, } bool isCompoundChild = false; - bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD); + bool hasCompoundChildren = !parent && (blenderobject->gameflag & OB_CHILD) && !(blenderobject->gameflag & OB_SOFT_BODY); /* When the parent is not OB_DYNAMIC and has no OB_COLLISION then it gets no bullet controller - * and cant be apart of the parents compound shape */ + * and cant be apart of the parents compound shape, same goes for OB_SOFT_BODY */ if (parent && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) { - - if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD)) - { + if( (parent->gameflag & OB_CHILD)!=0 && (blenderobject->gameflag & OB_CHILD) && !(parent->gameflag & OB_SOFT_BODY)) { isCompoundChild = true; - } + } } if (processCompoundChildren != isCompoundChild) return; @@ -1711,9 +1682,6 @@ struct parentChildLink { SG_Node* m_gamechildnode; }; -#include "DNA_constraint_types.h" -//XXX #include "BIF_editconstraint.h" - static bPoseChannel *get_active_posechannel2(Object *ob) { bArmature *arm= (bArmature*)ob->data; @@ -1747,20 +1715,15 @@ static ListBase *get_active_constraints2(Object *ob) return NULL; } -static void UNUSED_FUNCTION(RBJconstraints)(Object *ob)//not used +static void UNUSED_FUNCTION(print_active_constraints2)(Object *ob) //not used, use to debug { - ListBase *conlist; - bConstraint *curcon; - - conlist = get_active_constraints2(ob); + bConstraint* curcon; + ListBase* conlist = get_active_constraints2(ob); if (conlist) { for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) { - printf("%i\n",curcon->type); } - - } } @@ -1782,20 +1745,22 @@ static KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist) * note: all var names match args are passed from the caller */ static void bl_ConvertBlenderObject_Single( KX_BlenderSceneConverter *converter, - Scene *blenderscene, Object *blenderobject, - vector<MT_Vector3> &inivel, vector<MT_Vector3> &iniang, + Object *blenderobject, vector<parentChildLink> &vec_parent_child, CListValue* logicbrick_conversionlist, - CListValue* objectlist, CListValue* inactivelist, CListValue* sumolist, + CListValue* objectlist, CListValue* inactivelist, CListValue* sumolist, KX_Scene* kxscene, KX_GameObject* gameobj, SCA_LogicManager* logicmgr, SCA_TimeEventManager* timemgr, bool isInActiveLayer ) { - MT_Point3 posPrev; - MT_Matrix3x3 angor; - if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra; + sumolist->Add(gameobj->AddRef()); + + BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); + gameobj->SetName(blenderobject->id.name + 2); + + /* Setting local coordinates according to current local+delta */ MT_Point3 pos( blenderobject->loc[0]+blenderobject->dloc[0], blenderobject->loc[1]+blenderobject->dloc[1], @@ -1804,97 +1769,61 @@ static void bl_ConvertBlenderObject_Single( MT_Matrix3x3 rotation; float rotmat[3][3]; - BKE_object_rot_to_mat3(blenderobject, rotmat, false); + BKE_object_rot_to_mat3(blenderobject, rotmat, true); rotation.setValue3x3((float*)rotmat); - MT_Vector3 scale(blenderobject->size); - - if (converter->addInitFromFrame) {//rcruiz - blenderscene->r.cfra=blenderscene->r.sfra-1; - //XXX 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] - ); - - float rotmatPrev[3][3]; - BKE_object_rot_to_mat3(blenderobject, rotmatPrev, false); - - float eulxyz[3], eulxyzPrev[3]; - mat3_to_eul(eulxyz, rotmat); - mat3_to_eul(eulxyzPrev, rotmatPrev); - - double fps = (double) blenderscene->r.frs_sec/ - (double) blenderscene->r.frs_sec_base; - - tmp.scale(fps, fps, fps); - inivel.push_back(tmp); - tmp[0]=eulxyz[0]-eulxyzPrev[0]; - tmp[1]=eulxyz[1]-eulxyzPrev[1]; - tmp[2]=eulxyz[2]-eulxyzPrev[2]; - tmp.scale(fps, fps, fps); - iniang.push_back(tmp); - blenderscene->r.cfra=blenderscene->r.sfra; - //XXX update_for_newframe(); - } + MT_Vector3 scale( + blenderobject->size[0]*blenderobject->dscale[0], + blenderobject->size[1]*blenderobject->dscale[1], + blenderobject->size[2]*blenderobject->dscale[2] + ); gameobj->NodeSetLocalPosition(pos); gameobj->NodeSetLocalOrientation(rotation); gameobj->NodeSetLocalScale(scale); - gameobj->NodeUpdateGS(0); - sumolist->Add(gameobj->AddRef()); - - BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer); - - gameobj->SetName(blenderobject->id.name + 2); - - // update children/parent hierarchy - if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame)) + /* if the node has a parent, add a parent/child link */ + if (blenderobject->parent != 0) { - // blender has an additional 'parentinverse' offset in each object - SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); - SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); - - // define a normal parent relationship for this node. - KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); - parentinversenode->SetParentRelation(parent_relation); + SG_Callbacks callbacks( + NULL, /* replicationfunc, */ + NULL, /* destructionfunc,*/ + NULL, /* updatefunc, */ + KX_Scene::KX_ScenegraphUpdateFunc, /* schedulefunc, */ + KX_Scene::KX_ScenegraphRescheduleFunc); /* reschedulefunc */ + + /* + * when an object gets parented, an inverse parenting matrix is kept, + * or the child would pop to the parents position, alignment, etc. + * the GE scene graph makes an intermediate node between the parent + * and child to store this transform. + */ + SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callbacks); + parentinversenode->SetParentRelation(KX_NormalParentRelation::New()); + parentinversenode->AddChild(gameobj->GetSGNode()); + /* add the link to vec_parent_child that will be processed later, connecting the parent nodes */ 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()); - // 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 - MT_Matrix3x3 ori(parinvtrans.getBasis()); - MT_Vector3 x(ori.getColumn(0)); - MT_Vector3 y(ori.getColumn(1)); - MT_Vector3 z(ori.getColumn(2)); - 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]; - ori.setColumn(0, x); - ori.setColumn(1, y); - ori.setColumn(2, z); - parentinversenode->SetLocalOrientation(ori); - parentinversenode->SetLocalScale(parscale); + /* extract location, orientation and scale out of the inverse parent matrix */ + float invp_loc[3], invp_rot[3][3], invp_size[3]; + mat4_to_loc_rot_size(invp_loc, invp_rot, invp_size, blenderobject->parentinv); + + MT_Matrix3x3 invp_rot_mt; + invp_rot_mt.setValue3x3((float *) invp_rot); + parentinversenode->SetLocalPosition(MT_Point3(invp_loc)); + parentinversenode->SetLocalOrientation(invp_rot_mt); + parentinversenode->SetLocalScale(MT_Vector3(invp_size)); - parentinversenode->AddChild(gameobj->GetSGNode()); } + /* Note: world coordinates are calculated for all nodes when the scene graph + * is complete, after processing vec_parent_child */ + + // needed for python scripting logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); @@ -1909,18 +1838,11 @@ static void bl_ConvertBlenderObject_Single( logicbrick_conversionlist->Add(gameobj->AddRef()); - if (converter->addInitFromFrame) { - posPrev=gameobj->NodeGetWorldPosition(); - angor=gameobj->NodeGetWorldOrientation(); - } + if (isInActiveLayer) { objectlist->Add(gameobj->AddRef()); - //tf.Add(gameobj->GetSGNode()); - - gameobj->NodeUpdateGS(0); gameobj->AddMeshUser(); - } else { @@ -1928,11 +1850,6 @@ static void bl_ConvertBlenderObject_Single( //at the end of this function if it is not a root object inactivelist->Add(gameobj->AddRef()); } - - if (converter->addInitFromFrame) { - gameobj->NodeSetLocalPosition(posPrev); - gameobj->NodeSetLocalOrientation(angor); - } } @@ -1951,8 +1868,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, #define BL_CONVERTBLENDEROBJECT_SINGLE \ bl_ConvertBlenderObject_Single(converter, \ - blenderscene, blenderobject, \ - inivel, iniang, \ + blenderobject, \ vec_parent_child, \ logicbrick_conversionlist, \ objectlist, inactivelist, sumolist, \ @@ -1974,7 +1890,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, RAS_FrameSettings::RAS_FrameType frame_type; int aspect_width; int aspect_height; - vector<MT_Vector3> inivel,iniang; 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) @@ -2020,24 +1935,25 @@ void BL_ConvertBlenderObjects(struct Main* maggie, // no occlusion culling by default kxscene->SetDbvtOcclusionRes(0); + + /* Objects' Conversion */ + int activeLayerBitInfo = blenderscene->lay; - + // list of all object converted, active and inactive CListValue* sumolist = new CListValue(); - + vector<parentChildLink> vec_parent_child; - + CListValue* objectlist = kxscene->GetObjectList(); CListValue* inactivelist = kxscene->GetInactiveList(); CListValue* parentlist = kxscene->GetRootParentList(); - + SCA_LogicManager* logicmgr = kxscene->GetLogicManager(); SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager(); - + CListValue* logicbrick_conversionlist = new CListValue(); - - //SG_TreeFactory tf; - + // Convert actions to actionmap bAction *curAct; for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next) @@ -2046,6 +1962,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } SetDefaultLightMode(blenderscene); + // 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 @@ -2061,23 +1978,15 @@ void BL_ConvertBlenderObjects(struct Main* maggie, rendertools, converter, libloading); - - bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0; - bool addobj=true; - - if (converter->addInitFromFrame) - if (!isInActiveLayer) - addobj=false; + bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0; if (gameobj) { - if (addobj) - { /* macro calls object conversion funcs */ - BL_CONVERTBLENDEROBJECT_SINGLE; + /* macro calls object conversion funcs */ + BL_CONVERTBLENDEROBJECT_SINGLE; - if (gameobj->IsDupliGroup()) { - grouplist.insert(blenderobject->dup_group); - } + if (gameobj->IsDupliGroup()) { + grouplist.insert(blenderobject->dup_group); } /* Note about memory leak issues: @@ -2121,22 +2030,12 @@ void BL_ConvertBlenderObjects(struct Main* maggie, rendertools, converter, libloading); - - // this code is copied from above except that - // object from groups are never in active layer - bool isInActiveLayer = false; - bool addobj=true; - - if (converter->addInitFromFrame) - if (!isInActiveLayer) - addobj=false; + bool isInActiveLayer = false; if (gameobj) { - if (addobj) - { /* macro calls object conversion funcs */ - BL_CONVERTBLENDEROBJECT_SINGLE; - } + /* macro calls object conversion funcs */ + BL_CONVERTBLENDEROBJECT_SINGLE; if (gameobj->IsDupliGroup()) { @@ -2146,7 +2045,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } } - /* see comment above re: mem leaks */ gameobj->Release(); } @@ -2183,14 +2081,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } } } - - // create hierarchy information + int i; + + + /* Build the scene graph relations */ vector<parentChildLink>::iterator pcit; - for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit) { - struct Object* blenderchild = pcit->m_blenderchild; struct Object* blenderparent = blenderchild->parent; KX_GameObject* parentobj = converter->FindGameObject(blenderparent); @@ -2228,33 +2126,28 @@ void BL_ConvertBlenderObjects(struct Main* maggie, continue; } + /* override the parent relation type if not normal. + * If the type is not supported, the NormalParentRelation is kept. */ switch (blenderchild->partype) { 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); + pcit->m_gamechildnode->SetParentRelation(KX_VertexParentRelation::New()); 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); + pcit->m_gamechildnode->SetParentRelation(KX_SlowParentRelation::New(blenderchild->sf)); break; } case PARBONE: { - // parent this to a bone Bone *parent_bone = BKE_armature_find_bone_name(BKE_armature_from_object(blenderchild->parent), blenderchild->parsubstr); if (parent_bone) { - KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone); - pcit->m_gamechildnode->SetParentRelation(bone_parent_relation); + pcit->m_gamechildnode->SetParentRelation(KX_BoneParentRelation::New(parent_bone)); } - break; } case PARSKEL: // skinned - ignore @@ -2267,19 +2160,19 @@ void BL_ConvertBlenderObjects(struct Main* maggie, // unhandled break; } - + parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode); } vec_parent_child.clear(); - // find 'root' parents (object that has not parents in SceneGraph) + /* Find all 'root' parents (objects that have no parents in SceneGraph) and init the world transforms */ for (i=0;i<sumolist->GetCount();++i) { KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); if (gameobj->GetSGNode()->GetSGParent() == 0) { parentlist->Add(gameobj->AddRef()); - gameobj->NodeUpdateGS(0); + gameobj->GetSGNode()->UpdateWorldData(0, true); } } @@ -2290,7 +2183,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, for (i=0; i<sumolist->GetCount();i++) { KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); - if (gameobj->GetMeshCount() > 0) + if (gameobj->GetMeshCount() > 0) { MT_Point3 box[2]; gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity()); @@ -2304,6 +2197,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie, if (occlusion) kxscene->SetDbvtOcclusionRes(blenderscene->gm.occlusionRes); } + + if (blenderscene->world) kxscene->GetPhysicsEnvironment()->SetNumTimeSubSteps(blenderscene->gm.physubstep); @@ -2338,7 +2233,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } bool processCompoundChildren = false; - // create physics information for (i=0;i<sumolist->GetCount();i++) { @@ -2369,32 +2263,19 @@ void BL_ConvertBlenderObjects(struct Main* maggie, int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0; BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,converter,processCompoundChildren); } - - //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); - } - - - } - // create physics joints + // create physics joints for (i=0;i<sumolist->GetCount();i++) { KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); struct Object* blenderobject = gameobj->GetBlenderObject(); ListBase *conlist; bConstraint *curcon; - conlist = get_active_constraints2(blenderobject); if ((gameobj->GetLayer()&activeLayerBitInfo)==0) continue; + conlist = get_active_constraints2(blenderobject); if (conlist) { for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) { if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT) { @@ -2405,15 +2286,13 @@ void BL_ConvertBlenderObjects(struct Main* maggie, PHY_IPhysicsController* physctr2 = 0; - if (dat->tar) - { + if (dat->tar) { KX_GameObject *gotar=getGameOb(dat->tar->id.name+2,sumolist); if (gotar && ((gotar->GetLayer()&activeLayerBitInfo)!=0) && gotar->GetPhysicsController()) physctr2 = gotar->GetPhysicsController(); } - if (gameobj->GetPhysicsController()) - { + if (gameobj->GetPhysicsController()) { PHY_IPhysicsController* physctrl = gameobj->GetPhysicsController(); //we need to pass a full constraint frame, not just axis @@ -2422,62 +2301,47 @@ void BL_ConvertBlenderObjects(struct Main* maggie, MT_Vector3 axis0 = localCFrame.getColumn(0); MT_Vector3 axis1 = localCFrame.getColumn(1); MT_Vector3 axis2 = localCFrame.getColumn(2); - + int constraintId = kxscene->GetPhysicsEnvironment()->CreateConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX, (float)dat->pivY,(float)dat->pivZ, (float)axis0.x(),(float)axis0.y(),(float)axis0.z(), (float)axis1.x(),(float)axis1.y(),(float)axis1.z(), (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),dat->flag); - if (constraintId) - { + if (constraintId) { //if it is a generic 6DOF constraint, set all the limits accordingly - if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT) - { + if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT) { int dof; int dofbit=1; - for (dof=0;dof<6;dof++) - { - if (dat->flag & dofbit) - { + for (dof=0;dof<6;dof++) { + if (dat->flag & dofbit) { kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]); - } else - { + } else { //minLimit > maxLimit means free(disabled limit) for this degree of freedom kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1); } dofbit<<=1; } - } - else if (dat->type == PHY_CONE_TWIST_CONSTRAINT) - { + } else if (dat->type == PHY_CONE_TWIST_CONSTRAINT) { int dof; int dofbit = 1<<3; // bitflag use_angular_limit_x - - for (dof=3;dof<6;dof++) - { - if (dat->flag & dofbit) - { + + for (dof=3;dof<6;dof++) { + if (dat->flag & dofbit) { kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]); - } - else - { + } else { //maxLimit < 0 means free(disabled limit) for this degree of freedom kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1); } dofbit<<=1; } - } - else if (dat->type == PHY_LINEHINGE_CONSTRAINT) - { + } else if (dat->type == PHY_LINEHINGE_CONSTRAINT) { int dof = 3; // dof for angular x int dofbit = 1<<3; // bitflag use_angular_limit_x - - if (dat->flag & dofbit) - { + + if (dat->flag & dofbit) { kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof, dat->minLimit[dof],dat->maxLimit[dof]); - } else - { + } else { //minLimit > maxLimit means free(disabled limit) for this degree of freedom kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1); } @@ -2537,8 +2401,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, } } -#define CONVERT_LOGIC -#ifdef CONVERT_LOGIC // convert logic bricks, sensors, controllers and actuators for (i=0;i<logicbrick_conversionlist->GetCount();i++) { @@ -2573,8 +2435,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie, gameobj->ResetState(); } -#endif //CONVERT_LOGIC - logicbrick_conversionlist->Release(); // Calculate the scene btree - @@ -2601,7 +2461,3 @@ void BL_ConvertBlenderObjects(struct Main* maggie, bucketmanager->OptimizeBuckets(distance); } -SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code) -{ - return gReverseKeyTranslateTable[key_code]; -} diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index eb4b9a8124a..09cc74d717f 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -529,76 +529,59 @@ void KX_BlenderSceneConverter::CacheBlenderMaterial(KX_Scene *scene, struct Mate m_mat_cache[scene][mat] = blmat; } + BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(KX_Scene *scene, struct Material *mat) { return (m_use_mat_cache) ? m_mat_cache[scene][mat] : NULL; } -void KX_BlenderSceneConverter::RegisterInterpolatorList( - BL_InterpolatorList *actList, - struct bAction *for_act) + +void KX_BlenderSceneConverter::RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act) { m_map_blender_to_gameAdtList.insert(CHashedPtr(for_act), actList); } - - -BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList( - struct bAction *for_act) +BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(struct bAction *for_act) { BL_InterpolatorList **listp = m_map_blender_to_gameAdtList[CHashedPtr(for_act)]; - return listp?*listp:NULL; } - -void KX_BlenderSceneConverter::RegisterGameActuator( - SCA_IActuator *act, - struct bActuator *for_actuator) +void KX_BlenderSceneConverter::RegisterGameActuator(SCA_IActuator *act, struct bActuator *for_actuator) { m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act); } - - -SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator( - struct bActuator *for_actuator) +SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(struct bActuator *for_actuator) { SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)]; - return actp?*actp:NULL; } - -void KX_BlenderSceneConverter::RegisterGameController( - SCA_IController *cont, - struct bController *for_controller) +void KX_BlenderSceneConverter::RegisterGameController(SCA_IController *cont, struct bController *for_controller) { m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont); } - - -SCA_IController *KX_BlenderSceneConverter::FindGameController( - struct bController *for_controller) +SCA_IController *KX_BlenderSceneConverter::FindGameController(struct bController *for_controller) { SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)]; - return contp?*contp:NULL; } -void KX_BlenderSceneConverter::RegisterWorldInfo( - KX_WorldInfo *worldinfo) +void KX_BlenderSceneConverter::RegisterWorldInfo(KX_WorldInfo *worldinfo) { m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo)); } void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) { + //TODO this entire function is deprecated, written for 2.4x + //the functionality should be rewritten, currently it does nothing KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); int numScenes = scenes->size(); @@ -614,7 +597,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) { KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g); if (gameObj->IsRecordAnimation()) { - + Object* blenderObject = gameObj->GetBlenderObject(); if (blenderObject) { @@ -625,21 +608,21 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) { //clear the curve data if (clearIpo) {//rcruiz IpoCurve *icu1; - + int numCurves = 0; for ( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) { - + IpoCurve* tmpicu = icu1; - + /*int i; BezTriple *bezt; for ( bezt = tmpicu->bezt, i = 0; i < tmpicu->totvert; i++, bezt++) { printf("(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",bezt->vec[0][0],bezt->vec[0][1],bezt->vec[0][2],bezt->vec[1][0],bezt->vec[1][1],bezt->vec[1][2],bezt->vec[2][0],bezt->vec[2][1],bezt->vec[2][2]); }*/ - + icu1 = icu1->next; numCurves++; - + BLI_remlink( &( blenderObject->ipo->curve ), tmpicu ); if ( tmpicu->bezt ) MEM_freeN( tmpicu->bezt ); @@ -657,8 +640,8 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) } } - - + + } @@ -667,45 +650,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo() { - if (addInitFromFrame) { - KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); - int numScenes = scenes->size(); - if (numScenes>=0) { - KX_Scene* scene = scenes->at(0); - CListValue* parentList = scene->GetRootParentList(); - for (int ix=0;ix<parentList->GetCount();ix++) { - KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix); - if (!gameobj->IsRecordAnimation()) { - Object* blenderobject = gameobj->GetBlenderObject(); - if (!blenderobject) - continue; - if (blenderobject->type==OB_ARMATURE) - continue; - float eu[3]; - mat4_to_eul(eu,blenderobject->obmat); - MT_Point3 pos = MT_Point3( - blenderobject->obmat[3][0], - blenderobject->obmat[3][1], - blenderobject->obmat[3][2] - ); - MT_Vector3 eulxyz = MT_Vector3( - eu[0], - eu[1], - eu[2] - ); - MT_Vector3 scale = MT_Vector3( - blenderobject->size[0], - blenderobject->size[1], - blenderobject->size[2] - ); - gameobj->NodeSetLocalPosition(pos); - gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz)); - gameobj->NodeSetLocalScale(scale); - gameobj->NodeUpdateGS(0); - } - } - } - } + //TODO the functionality should be rewritten } diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp index be7cf6629f0..a3c6221c621 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp @@ -69,6 +69,7 @@ GPC_Canvas::GPC_Canvas( m_displayarea.m_y1 = 0; m_displayarea.m_x2 = width; m_displayarea.m_y2 = height; + m_frame = 1; glGetIntegerv(GL_VIEWPORT, (GLint*)m_viewport); } @@ -180,6 +181,8 @@ MakeScreenShot( char path[FILE_MAX]; BLI_strncpy(path, filename, sizeof(path)); BLI_path_abs(path, G.main->name); + BLI_path_frame(path, m_frame, 0); + m_frame++; BKE_add_image_extension_from_type(path, im_format.imtype); // create and save imbuf diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h index 338f9647b3e..acbea477e38 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.h +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h @@ -56,6 +56,8 @@ protected: /** Rect that defines the area used for rendering, * relative to the context */ RAS_Rect m_displayarea; + /** Frame counter for screenshots */ + int m_frame; int m_viewport[4]; diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index 006c1f7202c..849b5e0f3c3 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -47,10 +47,10 @@ BL_Material::BL_Material() void BL_Material::Initialize() { - rgb[0] = 0; - rgb[1] = 0; - rgb[2] = 0; - rgb[3] = 0; + rgb[0] = 0xFFFFFFFFL; + rgb[1] = 0xFFFFFFFFL; + rgb[2] = 0xFFFFFFFFL; + rgb[3] = 0xFFFFFFFFL; IdMode = 0; ras_mode = 0; glslmat = 0; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 4ac889b1927..7a443968311 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -124,14 +124,10 @@ KX_GameObject::KX_GameObject( { m_ignore_activity_culling = false; m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR); - m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks); - // define the relationship between this node and it's parent. - - KX_NormalParentRelation * parent_relation = - KX_NormalParentRelation::New(); - m_pSGNode->SetParentRelation(parent_relation); -}; + m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks); + m_pSGNode->SetParentRelation(KX_NormalParentRelation::New()); +} @@ -157,8 +153,7 @@ KX_GameObject::~KX_GameObject() //if (m_sumoObj) // delete m_sumoObj; delete m_pClient_info; - //if (m_pSGNode) - // delete m_pSGNode; + if (m_pSGNode) { // must go through controllers and make sure they will not use us anymore @@ -601,7 +596,7 @@ void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local) { m_pPhysicsController->RelativeTranslate(dloc,local); } - GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local); + GetSGNode()->RelativeTranslate(dloc,local); } } diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h index a07d4b2195c..b6647cdf3dc 100644 --- a/source/gameengine/Ketsji/KX_ISceneConverter.h +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -45,8 +45,8 @@ class KX_ISceneConverter { public: - KX_ISceneConverter() :addInitFromFrame(false) {}//this addInitFromFrame is a back hack, todo remove - virtual ~KX_ISceneConverter () {}; + KX_ISceneConverter() {} + virtual ~KX_ISceneConverter () {} /* * scenename: name of the scene to be converted, @@ -59,7 +59,7 @@ public: class RAS_IRasterizer* rendertools, class RAS_ICanvas* canvas, bool libloading=false)=0; - + virtual void RemoveScene(class KX_Scene *scene)=0; // handle any pending merges from asynchronous loads @@ -69,11 +69,9 @@ public: virtual void SetNewFileName(const STR_String& filename) = 0; virtual bool TryAndLoadNewFile() = 0; - bool addInitFromFrame;//rcruiz virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo) = 0; - ///this generates ipo curves for position, rotation, allowing to use game physics in animation virtual void WritePhysicsObjectToAnimationIpo(int frameNumber) = 0; virtual void TestHandlesPhysicsObjectToAnimationIpo() = 0; diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index f1d0e4262e9..ba12efb816a 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -80,9 +80,6 @@ #include "KX_NavMeshObject.h" -// If define: little test for Nzc: guarded drawing. If the canvas is -// not valid, skip rendering this frame. -//#define NZC_GUARDED_OUTPUT #define DEFAULT_LOGIC_TIC_RATE 60.0 //#define DEFAULT_PHYSICS_TIC_RATE 60.0 @@ -741,85 +738,6 @@ bool KX_KetsjiEngine::NextFrame() frames--; } - bool bUseAsyncLogicBricks= false;//true; - - if (bUseAsyncLogicBricks) - { - // Logic update sub frame: this will let some logic bricks run at the - // full frame rate. - for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit) - // for each scene, call the proceed functions - { - KX_Scene* scene = *sceneit; - - if (!scene->IsSuspended()) - { - // if the scene was suspended recalcutlate the delta tu "curtime" - m_suspendedtime = scene->getSuspendedTime(); - if (scene->getSuspendedTime()!=0.0) - scene->setSuspendedDelta(scene->getSuspendedDelta()+m_clockTime-scene->getSuspendedTime()); - m_suspendeddelta = scene->getSuspendedDelta(); - - // set Python hooks for each scene -#ifdef WITH_PYTHON - PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment()); -#endif - KX_SetActiveScene(scene); - - m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); - SG_SetActiveStage(SG_STAGE_PHYSICS1); - scene->UpdateParents(m_clockTime); - - // Perform physics calculations on the scene. This can involve - // many iterations of the physics solver. - m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true); - scene->GetPhysicsEnvironment()->ProceedDeltaTime(m_clockTime,timestep,timestep); - // Update scenegraph after physics step. This maps physics calculations - // into node positions. - m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); - SG_SetActiveStage(SG_STAGE_PHYSICS2); - scene->UpdateParents(m_clockTime); - - // Do some cleanup work for this logic frame - m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true); - scene->LogicUpdateFrame(m_clockTime, false); - - // Actuators can affect the scenegraph - m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); - SG_SetActiveStage(SG_STAGE_ACTUATOR); - scene->UpdateParents(m_clockTime); - - scene->setSuspendedTime(0.0); - } // suspended - else - if (scene->getSuspendedTime()==0.0) - scene->setSuspendedTime(m_clockTime); - - m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true); - } - } - - - // Handle the animations independently of the logic time step - if (GetRestrictAnimationFPS()) - { - double clocktime = m_kxsystem->GetTimeInSeconds(); - m_logger->StartLog(tc_animations, clocktime, true); - SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE); - - double anim_timestep = 1.0/KX_GetActiveScene()->GetAnimationFPS(); - if (clocktime - m_previousAnimTime > anim_timestep) - { - // Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep) - // printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime)); - m_previousAnimTime = clocktime; - for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit) - { - (*sceneit)->UpdateAnimations(clocktime); - } - } - } - // Start logging time spend outside main loop m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true); diff --git a/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h index ca99c2e7526..e5d1c09f5d1 100644 --- a/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h +++ b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h @@ -36,6 +36,7 @@ enum e_PhysicsEngine { NoSelection = -1, UseNone = 0, + /* UseEnji=1, UseSumo, useDynamo and useODE were removed */ UseBullet = 5, }; diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index ebf1b9ec577..ce3e4722ae0 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -56,38 +56,75 @@ // if there is a better way (without global), please do so! static PHY_IPhysicsEnvironment* g_CurrentActivePhysicsEnvironment = NULL; -static char PhysicsConstraints_module_documentation[] = -"This is the Python API for the Physics Constraints"; - - -static char gPySetGravity__doc__[] = "setGravity(float x,float y,float z)"; -static char gPySetDebugMode__doc__[] = "setDebugMode(int mode)"; - -static char gPySetNumIterations__doc__[] = "setNumIterations(int numiter) This sets the number of iterations for an iterative constraint solver"; -static char gPySetNumTimeSubSteps__doc__[] = "setNumTimeSubSteps(int numsubstep) This sets the number of substeps for each physics proceed. Tradeoff quality for performance."; - - -static char gPySetDeactivationTime__doc__[] = "setDeactivationTime(float time) This sets the time after which a resting rigidbody gets deactived"; -static char gPySetDeactivationLinearTreshold__doc__[] = "setDeactivationLinearTreshold(float linearTreshold)"; -static char gPySetDeactivationAngularTreshold__doc__[] = "setDeactivationAngularTreshold(float angularTreshold)"; -static char gPySetContactBreakingTreshold__doc__[] = "setContactBreakingTreshold(float breakingTreshold) Reasonable default is 0.02 (if units are meters)"; - -static char gPySetCcdMode__doc__[] = "setCcdMode(int ccdMode) Very experimental, not recommended"; -static char gPySetSorConstant__doc__[] = "setSorConstant(float sor) Very experimental, not recommended"; -static char gPySetSolverTau__doc__[] = "setTau(float tau) Very experimental, not recommended"; -static char gPySetSolverDamping__doc__[] = "setDamping(float damping) Very experimental, not recommended"; -static char gPySetLinearAirDamping__doc__[] = "setLinearAirDamping(float damping) Very experimental, not recommended"; -static char gPySetUseEpa__doc__[] = "setUseEpa(int epa) Very experimental, not recommended"; -static char gPySetSolverType__doc__[] = "setSolverType(int solverType) Very experimental, not recommended"; - - -static char gPyCreateConstraint__doc__[] = "createConstraint(ob1,ob2,float restLength,float restitution,float damping)"; -static char gPyGetVehicleConstraint__doc__[] = "getVehicleConstraint(int constraintId)"; -static char gPyGetCharacter__doc__[] = "getCharacter(KX_GameObject obj)"; -static char gPyRemoveConstraint__doc__[] = "removeConstraint(int constraintId)"; -static char gPyGetAppliedImpulse__doc__[] = "getAppliedImpulse(int constraintId)"; - +PyDoc_STRVAR(PhysicsConstraints_module_documentation, + "This is the Python API for the Physics Constraints" +); + +PyDoc_STRVAR(gPySetGravity__doc__, + "setGravity(float x,float y,float z)\n" + ""); +PyDoc_STRVAR(gPySetDebugMode__doc__, + "setDebugMode(int mode)\n" + ""); + +PyDoc_STRVAR(gPySetNumIterations__doc__, + "setNumIterations(int numiter)\n" + "This sets the number of iterations for an iterative constraint solver"); +PyDoc_STRVAR(gPySetNumTimeSubSteps__doc__, + "setNumTimeSubSteps(int numsubstep)\n" + "This sets the number of substeps for each physics proceed. Tradeoff quality for performance."); + +PyDoc_STRVAR(gPySetDeactivationTime__doc__, + "setDeactivationTime(float time)\n" + "This sets the time after which a resting rigidbody gets deactived"); +PyDoc_STRVAR(gPySetDeactivationLinearTreshold__doc__, + "setDeactivationLinearTreshold(float linearTreshold)\n" + ""); +PyDoc_STRVAR(gPySetDeactivationAngularTreshold__doc__, + "setDeactivationAngularTreshold(float angularTreshold)\n" + ""); +PyDoc_STRVAR(gPySetContactBreakingTreshold__doc__, + "setContactBreakingTreshold(float breakingTreshold)\n" + "Reasonable default is 0.02 (if units are meters)"); + +PyDoc_STRVAR(gPySetCcdMode__doc__, + "setCcdMode(int ccdMode)\n" + "Very experimental, not recommended"); +PyDoc_STRVAR(gPySetSorConstant__doc__, + "setSorConstant(float sor)\n" + "Very experimental, not recommended"); +PyDoc_STRVAR(gPySetSolverTau__doc__, + "setTau(float tau)\n" + "Very experimental, not recommended"); +PyDoc_STRVAR(gPySetSolverDamping__doc__, + "setDamping(float damping)\n" + "Very experimental, not recommended"); +PyDoc_STRVAR(gPySetLinearAirDamping__doc__, + "setLinearAirDamping(float damping)\n" + "Very experimental, not recommended"); +PyDoc_STRVAR(gPySetUseEpa__doc__, + "setUseEpa(int epa)\n" + "Very experimental, not recommended"); +PyDoc_STRVAR(gPySetSolverType__doc__, + "setSolverType(int solverType)\n" + "Very experimental, not recommended"); + +PyDoc_STRVAR(gPyCreateConstraint__doc__, + "createConstraint(ob1,ob2,float restLength,float restitution,float damping)\n" + ""); +PyDoc_STRVAR(gPyGetVehicleConstraint__doc__, + "getVehicleConstraint(int constraintId)\n" + ""); +PyDoc_STRVAR(gPyGetCharacter__doc__, + "getCharacter(KX_GameObject obj)\n" + ""); +PyDoc_STRVAR(gPyRemoveConstraint__doc__, + "removeConstraint(int constraintId)\n" + ""); +PyDoc_STRVAR(gPyGetAppliedImpulse__doc__, + "getAppliedImpulse(int constraintId)\n" + ""); @@ -677,7 +714,7 @@ static struct PyMethodDef physicsconstraints_methods[] = { }; static struct PyModuleDef PhysicsConstraints_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "PhysicsConstraints", /* m_name */ PhysicsConstraints_module_documentation, /* m_doc */ 0, /* m_size */ @@ -688,7 +725,7 @@ static struct PyModuleDef PhysicsConstraints_module_def = { 0, /* m_free */ }; -PyObject *initPythonConstraintBinding() +PyMODINIT_FUNC initConstraintPythonBinding() { PyObject *ErrorObject; @@ -747,7 +784,7 @@ PyObject *initPythonConstraintBinding() Py_FatalError("can't initialize module PhysicsConstraints"); } - return d; + return m; } #if 0 diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.h b/source/gameengine/Ketsji/KX_PyConstraintBinding.h index b4a520ce71b..2bf9f7e197d 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.h +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.h @@ -36,7 +36,8 @@ #include <Python.h> -PyObject* initPythonConstraintBinding(); +PyMODINIT_FUNC initConstraintPythonBinding(); + void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env); PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment(); #endif /* WITH_PYTHON */ diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 3ddd53b971f..0b3e794f75e 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -223,8 +223,11 @@ static void KX_MACRO_addTypesToDict_fn(PyObject *dict, const char *name, long va // List of methods defined in the module static PyObject *ErrorObject; -static const char *gPyGetRandomFloat_doc="getRandomFloat returns a random floating point value in the range [0..1]"; +PyDoc_STRVAR(gPyGetRandomFloat_doc, + "getRandomFloat()\n" + "returns a random floating point value in the range [0..1]" +); static PyObject *gPyGetRandomFloat(PyObject *) { return PyFloat_FromDouble(MT_random()); @@ -242,15 +245,15 @@ static PyObject *gPySetGravity(PyObject *, PyObject *value) Py_RETURN_NONE; } -static char gPyExpandPath_doc[] = -"(path) - Converts a blender internal path into a proper file system path.\n\ -path - the string path to convert.\n\n\ -Use / as directory separator in path\n\ -You can use '//' at the start of the string to define a relative path;\n\ -Blender replaces that string by the directory of the current .blend or runtime\n\ -file to make a full path name.\n\ -The function also converts the directory separator to the local file system format."; - +PyDoc_STRVAR(gPyExpandPath_doc, + "expandPath(path)\n" + "Converts a blender internal path into a proper file system path.\n" + " path - the string path to convert.\n" + "Use / as directory separator in path\n" + "You can use '//' at the start of the string to define a relative path." + "Blender replaces that string by the directory of the current .blend or runtime file to make a full path name.\n" + "The function also converts the directory separator to the local file system format." +); static PyObject *gPyExpandPath(PyObject *, PyObject *args) { char expanded[FILE_MAX]; @@ -264,10 +267,10 @@ static PyObject *gPyExpandPath(PyObject *, PyObject *args) return PyC_UnicodeFromByte(expanded); } -static char gPyStartGame_doc[] = -"startGame(blend)\n\ -Loads the blend file"; - +PyDoc_STRVAR(gPyStartGame_doc, + "startGame(blend)\n" + "Loads the blend file" +); static PyObject *gPyStartGame(PyObject *, PyObject *args) { char* blendfile; @@ -281,10 +284,10 @@ static PyObject *gPyStartGame(PyObject *, PyObject *args) Py_RETURN_NONE; } -static char gPyEndGame_doc[] = -"endGame()\n\ -Ends the current game"; - +PyDoc_STRVAR(gPyEndGame_doc, + "endGame()\n" + "Ends the current game" +); static PyObject *gPyEndGame(PyObject *) { gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_QUIT_GAME); @@ -294,10 +297,10 @@ static PyObject *gPyEndGame(PyObject *) Py_RETURN_NONE; } -static char gPyRestartGame_doc[] = -"restartGame()\n\ -Restarts the current game by reloading the .blend file"; - +PyDoc_STRVAR(gPyRestartGame_doc, + "restartGame()\n" + "Restarts the current game by reloading the .blend file" +); static PyObject *gPyRestartGame(PyObject *) { gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_RESTART_GAME); @@ -306,10 +309,10 @@ static PyObject *gPyRestartGame(PyObject *) Py_RETURN_NONE; } -static char gPySaveGlobalDict_doc[] = +PyDoc_STRVAR(gPySaveGlobalDict_doc, "saveGlobalDict()\n" - "Saves bge.logic.globalDict to a file"; - + "Saves bge.logic.globalDict to a file" +); static PyObject *gPySaveGlobalDict(PyObject *) { char marshal_path[512]; @@ -343,10 +346,10 @@ static PyObject *gPySaveGlobalDict(PyObject *) Py_RETURN_NONE; } -static char gPyLoadGlobalDict_doc[] = +PyDoc_STRVAR(gPyLoadGlobalDict_doc, "LoadGlobalDict()\n" - "Loads bge.logic.globalDict from a file"; - + "Loads bge.logic.globalDict from a file" +); static PyObject *gPyLoadGlobalDict(PyObject *) { char marshal_path[512]; @@ -384,23 +387,23 @@ static PyObject *gPyLoadGlobalDict(PyObject *) Py_RETURN_NONE; } -static char gPyGetProfileInfo_doc[] = -"getProfileInfo()\n" -"returns a dictionary with profiling information"; - +PyDoc_STRVAR(gPyGetProfileInfo_doc, + "getProfileInfo()\n" + "returns a dictionary with profiling information" +); static PyObject *gPyGetProfileInfo(PyObject *) { return gp_KetsjiEngine->GetPyProfileDict(); } -static char gPySendMessage_doc[] = -"sendMessage(subject, [body, to, from])\n\ -sends a message in same manner as a message actuator\ -subject = Subject of the message\ -body = Message body\ -to = Name of object to send the message to\ -from = Name of object to send the string from"; - +PyDoc_STRVAR(gPySendMessage_doc, + "sendMessage(subject, [body, to, from])\n" + "sends a message in same manner as a message actuator" + " subject = Subject of the message" + " body = Message body" + " to = Name of object to send the message to" + " from = Name of object to send the string from" +); static PyObject *gPySendMessage(PyObject *, PyObject *args) { char* subject; @@ -560,11 +563,12 @@ static PyObject *gPyGetBlendFileList(PyObject *, PyObject *args) return list; } -static char gPyAddScene_doc[] = -"addScene(name, [overlay])\n\ -adds a scene to the game engine\n\ -name = Name of the scene\n\ -overlay = Overlay or underlay"; +PyDoc_STRVAR(gPyAddScene_doc, + "addScene(name, [overlay])\n" + "Adds a scene to the game engine.\n" + " name = Name of the scene\n" + " overlay = Overlay or underlay" +); static PyObject *gPyAddScene(PyObject *, PyObject *args) { char* name; @@ -578,17 +582,19 @@ static PyObject *gPyAddScene(PyObject *, PyObject *args) Py_RETURN_NONE; } -static const char *gPyGetCurrentScene_doc = -"getCurrentScene()\n" -"Gets a reference to the current scene.\n"; +PyDoc_STRVAR(gPyGetCurrentScene_doc, + "getCurrentScene()\n" + "Gets a reference to the current scene." +); static PyObject *gPyGetCurrentScene(PyObject *self) { return gp_KetsjiScene->GetProxy(); } -static const char *gPyGetSceneList_doc = -"getSceneList()\n" -"Return a list of converted scenes.\n"; +PyDoc_STRVAR(gPyGetSceneList_doc, + "getSceneList()\n" + "Return a list of converted scenes." +); static PyObject *gPyGetSceneList(PyObject *self) { KX_KetsjiEngine* m_engine = KX_GetActiveEngine(); @@ -1470,6 +1476,11 @@ static PyObject *gPyClearDebugList(PyObject *) } + +PyDoc_STRVAR(Rasterizer_module_documentation, + "This is the Python API for the game engine of Rasterizer" +); + static struct PyMethodDef rasterizer_methods[] = { {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, METH_VARARGS, "getWindowWidth doc"}, @@ -1525,15 +1536,11 @@ static struct PyMethodDef rasterizer_methods[] = { { NULL, (PyCFunction) NULL, 0, NULL } }; -// Initialization function for the module (*must* be called initGameLogic) -static char GameLogic_module_documentation[] = -"This is the Python API for the game engine of bge.logic" -; -static char Rasterizer_module_documentation[] = -"This is the Python API for the game engine of Rasterizer" -; +PyDoc_STRVAR(GameLogic_module_documentation, + "This is the Python API for the game engine of bge.logic" +); static struct PyModuleDef GameLogic_module_def = { {}, /* m_base */ @@ -1547,17 +1554,14 @@ static struct PyModuleDef GameLogic_module_def = { 0, /* m_free */ }; -PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack to get gravity hook +PyMODINIT_FUNC initGameLogicPythonBinding() { PyObject *m; PyObject *d; PyObject *item; /* temp PyObject *storage */ - - gp_KetsjiEngine = engine; - gp_KetsjiScene = scene; gUseVisibilityTemp=false; - + PyObjectPlus::ClearDeprecationWarning(); /* Not that nice to call here but makes sure warnings are reset between loading scenes */ /* Use existing module where possible @@ -2053,7 +2057,61 @@ void removeImportMain(struct Main *maggie) bpy_import_main_extra_remove(maggie); } -// Copied from bpy_interface.c + +PyDoc_STRVAR(BGE_module_documentation, + "This module contains submodules for the Blender Game Engine.\n" +); + +static struct PyModuleDef BGE_module_def = { + PyModuleDef_HEAD_INIT, + "bge", /* m_name */ + BGE_module_documentation, /* m_doc */ + 0, /* m_size */ + NULL, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + +PyMODINIT_FUNC initBGE(void) +{ + PyObject *mod; + PyObject *submodule; + PyObject *sys_modules = PyThreadState_GET()->interp->modules; + + mod = PyModule_Create(&BGE_module_def); + + PyModule_AddObject(mod, "constraints", (submodule = initConstraintPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + PyModule_AddObject(mod, "events", (submodule = initGameKeysPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + PyModule_AddObject(mod, "logic", (submodule = initGameLogicPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + PyModule_AddObject(mod, "render", (submodule = initRasterizerPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + PyModule_AddObject(mod, "texture", (submodule = initVideoTexturePythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + /* GameTypes is initted *after* in initPyTypes() */ + PyModule_AddObject(mod, "types", (submodule = initGameTypesPythonBinding())); + PyDict_SetItemString(sys_modules, PyModule_GetName(submodule), submodule); + Py_INCREF(submodule); + + return mod; +} + + +/* minimal required blender modules to run blenderplayer */ static struct _inittab bge_internal_modules[] = { {"mathutils", PyInit_mathutils}, {"bgl", BPyInit_bgl}, @@ -2066,7 +2124,7 @@ static struct _inittab bge_internal_modules[] = { * Python is not initialized. * see bpy_interface.c's BPY_python_start() which shares the same functionality in blender. */ -PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv) +PyObject *initGamePlayerPythonScripting(Main *maggie, int argc, char** argv) { /* Yet another gotcha in the py api * Cant run PySys_SetArgv more than once because this adds the @@ -2077,14 +2135,20 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur static bool first_time = true; const char * const py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); -#if 0 // TODO - py3 - STR_String pname = progname; - Py_SetProgramName(pname.Ptr()); -#endif + /* not essential but nice to set our name */ + static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ + BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar)); + Py_SetProgramName(program_path_wchar); + /* Update, Py3.3 resolves attempting to parse non-existing header */ + #if 0 + /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to + * parse from the 'sysconfig' module which is used by 'site', + * so for now disable site. alternatively we could copy the file. */ if (py_path_bundle != NULL) { - Py_NoSiteFlag = 1; + Py_NoSiteFlag = 1; /* inhibits the automatic importing of 'site' */ } + #endif Py_FrozenFlag = 1; @@ -2108,12 +2172,14 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur PySys_SetObject("argv", py_argv); Py_DECREF(py_argv); } - + /* Initialize thread support (also acquires lock) */ PyEval_InitThreads(); bpy_import_init(PyEval_GetBuiltins()); + PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE()); + /* mathutils types are used by the BGE even if we don't import them */ { PyObject *mod = PyImport_ImportModuleLevel("mathutils", NULL, NULL, NULL, 0); @@ -2128,12 +2194,12 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur } #endif - initPyTypes(); - bpy_import_main_set(maggie); - + initPySysObjects(maggie); - + + initPyTypes(); + first_time = false; PyObjectPlus::ClearDeprecationWarning(); @@ -2170,12 +2236,11 @@ void exitGamePlayerPythonScripting() /** * Python is already initialized. */ -PyObject *initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie) +PyObject *initGamePythonScripting(Main *maggie) { -#if 0 // XXX TODO Py3 - STR_String pname = progname; - Py_SetProgramName(pname.Ptr()); -#endif + /* no need to Py_SetProgramName, it was already taken care of in BPY_python_start */ + + PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE()); #ifdef WITH_AUDASPACE /* accessing a SoundActuator's sound results in a crash if aud is not initialized... */ @@ -2222,51 +2287,32 @@ void exitGamePythonScripting() void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main *blenderdata, PyObject *pyGlobalDict, PyObject **gameLogic, PyObject **gameLogic_keys, int argc, char** argv) { - PyObject *dictionaryobject; + PyObject *modules, *dictionaryobject; + + gp_Canvas = ketsjiengine->GetCanvas(); + gp_Rasterizer = ketsjiengine->GetRasterizer(); + gp_KetsjiEngine = ketsjiengine; + gp_KetsjiScene = startscene; if (argv) /* player only */ - dictionaryobject= initGamePlayerPythonScripting("Ketsji", psl_Lowest, blenderdata, argc, argv); + dictionaryobject= initGamePlayerPythonScripting(blenderdata, argc, argv); else - dictionaryobject= initGamePythonScripting("Ketsji", psl_Lowest, blenderdata); + dictionaryobject= initGamePythonScripting(blenderdata); ketsjiengine->SetPyNamespace(dictionaryobject); - initRasterizer(ketsjiengine->GetRasterizer(), ketsjiengine->GetCanvas()); - *gameLogic = initGameLogic(ketsjiengine, startscene); - /* is set in initGameLogic so only set here if we want it to persist between scenes */ + modules = PyImport_GetModuleDict(); + + *gameLogic = PyDict_GetItemString(modules, "GameLogic"); + /* is set in initGameLogicPythonBinding so only set here if we want it to persist between scenes */ if (pyGlobalDict) PyDict_SetItemString(PyModule_GetDict(*gameLogic), "globalDict", pyGlobalDict); // Same as importing the module. *gameLogic_keys = PyDict_Keys(PyModule_GetDict(*gameLogic)); - - initGameKeys(); - initPythonConstraintBinding(); - initVideoTexture(); - - /* could be done a lot more nicely, but for now a quick way to get bge.* working */ - PyRun_SimpleString("sys = __import__('sys');" - "bge = type(sys)('bge');" - "bge.__dict__.update({'logic':__import__('GameLogic'), " - "'render':__import__('Rasterizer'), " - "'events':__import__('GameKeys'), " - "'constraints':__import__('PhysicsConstraints'), " - "'physics':__import__('PhysicsConstraints')," - "'types':__import__('GameTypes'), " - "'texture':__import__('VideoTexture')});" - /* so we can do 'import bge.foo as bar' */ - "sys.modules.update({'bge': bge, " - "'bge.logic':bge.logic, " - "'bge.render':bge.render, " - "'bge.events':bge.events, " - "'bge.constraints':bge.constraints, " - "'bge.physics':bge.physics," - "'bge.types':bge.types, " - "'bge.texture':bge.texture})" - ); } static struct PyModuleDef Rasterizer_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "Rasterizer", /* m_name */ Rasterizer_module_documentation, /* m_doc */ 0, /* m_size */ @@ -2277,12 +2323,8 @@ static struct PyModuleDef Rasterizer_module_def = { 0, /* m_free */ }; -PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) +PyMODINIT_FUNC initRasterizerPythonBinding() { - gp_Canvas = canvas; - gp_Rasterizer = rasty; - - PyObject *m; PyObject *d; @@ -2328,7 +2370,7 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) Py_FatalError("can't initialize module Rasterizer"); } - return d; + return m; } @@ -2337,13 +2379,14 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) /* GameKeys: symbolic constants for key mapping */ /* ------------------------------------------------------------------------- */ -static char GameKeys_module_documentation[] = -"This modules provides defines for key-codes" -; +PyDoc_STRVAR(GameKeys_module_documentation, + "This modules provides defines for key-codes" +); -static char gPyEventToString_doc[] = -"EventToString(event) - Take a valid event from the GameKeys module or Keyboard Sensor and return a name" -; +PyDoc_STRVAR(gPyEventToString_doc, + "EventToString(event)\n" + "Take a valid event from the GameKeys module or Keyboard Sensor and return a name" +); static PyObject *gPyEventToString(PyObject *, PyObject *value) { @@ -2371,9 +2414,11 @@ static PyObject *gPyEventToString(PyObject *, PyObject *value) return ret; } -static char gPyEventToCharacter_doc[] = -"EventToCharacter(event, is_shift) - Take a valid event from the GameKeys module or Keyboard Sensor and return a character" -; + +PyDoc_STRVAR(gPyEventToCharacter_doc, + "EventToCharacter(event, is_shift)\n" + "Take a valid event from the GameKeys module or Keyboard Sensor and return a character" +); static PyObject *gPyEventToCharacter(PyObject *, PyObject *args) { @@ -2399,7 +2444,7 @@ static struct PyMethodDef gamekeys_methods[] = { }; static struct PyModuleDef GameKeys_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "GameKeys", /* m_name */ GameKeys_module_documentation, /* m_doc */ 0, /* m_size */ @@ -2410,11 +2455,11 @@ static struct PyModuleDef GameKeys_module_def = { 0, /* m_free */ }; -PyObject *initGameKeys() +PyMODINIT_FUNC initGameKeysPythonBinding() { PyObject *m; PyObject *d; - + /* Use existing module where possible */ m = PyImport_ImportModule( "GameKeys" ); if (m) { @@ -2423,7 +2468,7 @@ PyObject *initGameKeys() } else { PyErr_Clear(); - + // Create the module and add the functions m = PyModule_Create(&GameKeys_module_def); PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m); @@ -2572,7 +2617,7 @@ PyObject *initGameKeys() Py_FatalError("can't initialize module GameKeys"); } - return d; + return m; } // utility function for loading and saving the globalDict diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h index 719a74ee219..f74a4b3865f 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.h +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -36,6 +36,9 @@ #include "STR_String.h" #include "MT_Vector3.h" +class KX_KetsjiEngine; +class KX_Scene; + typedef enum { psl_Lowest = 0, psl_Highest, @@ -44,13 +47,13 @@ typedef enum { extern bool gUseVisibilityTemp; #ifdef WITH_PYTHON -PyObject *initGameLogic(class KX_KetsjiEngine *engine, class KX_Scene *ketsjiscene); -PyObject *initGameKeys(); -PyObject *initRasterizer(class RAS_IRasterizer *rasty,class RAS_ICanvas *canvas); -PyObject *initGamePlayerPythonScripting(const STR_String &progname, TPythonSecurityLevel level, - struct Main *maggie, int argc, char **argv); -PyObject *initVideoTexture(void); -PyObject *initGamePythonScripting(const STR_String &progname, TPythonSecurityLevel level, struct Main *maggie); +PyMODINIT_FUNC initBGE(void); +PyMODINIT_FUNC initGameLogicPythonBinding(void); +PyMODINIT_FUNC initGameKeysPythonBinding(void); +PyMODINIT_FUNC initRasterizerPythonBinding(void); +PyMODINIT_FUNC initVideoTexturePythonBinding(void); +PyObject *initGamePlayerPythonScripting(struct Main *maggie, int argc, char **argv); +PyObject *initGamePythonScripting(struct Main *maggie); void exitGamePlayerPythonScripting(); void exitGamePythonScripting(); @@ -69,9 +72,9 @@ void removeImportMain(struct Main *maggie); class KX_KetsjiEngine; class KX_Scene; -void KX_SetActiveScene(class KX_Scene *scene); -class KX_Scene *KX_GetActiveScene(); -class KX_KetsjiEngine *KX_GetActiveEngine(); +void KX_SetActiveScene(KX_Scene *scene); +KX_Scene *KX_GetActiveScene(); +KX_KetsjiEngine *KX_GetActiveEngine(); typedef int (*PyNextFrameFunc)(void *); diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index 7d38ce58eee..8ef4b6261b5 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -171,8 +171,10 @@ void initPyTypes(void) * ..... */ + /* Use existing module where possible */ + PyObject *mod = initGameTypesPythonBinding(); + /* For now just do PyType_Ready */ - PyObject *mod = PyModule_New("GameTypes"); PyObject *dict = PyModule_GetDict(mod); PyDict_SetItemString(PySys_GetObject("modules"), "GameTypes", mod); Py_DECREF(mod); @@ -269,4 +271,42 @@ void initPyTypes(void) #endif } + +PyDoc_STRVAR(GameTypes_module_documentation, + "This module provides access to the game engine data types." +); +static struct PyModuleDef GameTypes_module_def = { + PyModuleDef_HEAD_INIT, + "GameTypes", /* m_name */ + GameTypes_module_documentation, /* m_doc */ + 0, /* m_size */ + NULL, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ +}; + + +PyMODINIT_FUNC initGameTypesPythonBinding(void) +{ + PyObject *m; + + /* Use existing module where possible */ + m = PyImport_ImportModule( "GameTypes" ); + if (m) { + Py_DECREF(m); + return m; + } + else { + PyErr_Clear(); + + // Create the module and add the functions + m = PyModule_Create(&GameTypes_module_def); + PyDict_SetItemString(PySys_GetObject("modules"), GameTypes_module_def.m_name, m); + } + + return m; +} + #endif // WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.h b/source/gameengine/Ketsji/KX_PythonInitTypes.h index d8ee4f75fdd..4d7d26f7fb2 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.h +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.h @@ -33,7 +33,9 @@ #define __KX_PYTHON_INIT_TYPES__ #ifdef WITH_PYTHON +#include <Python.h> void initPyTypes(void); +PyMODINIT_FUNC initGameTypesPythonBinding(void); #endif #endif /* __KX_PYTHON_INIT_TYPES__ */ diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp index 19b9d13087d..d7487a4f9b3 100644 --- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp +++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp @@ -38,44 +38,24 @@ #include "BL_ArmatureObject.h" -/** - * Implementation of classes defined in KX_SG_BoneParentNodeRelationship.h - */ - -/** - * first of all KX_SG_BoneParentRelation - */ - - KX_BoneParentRelation * -KX_BoneParentRelation:: -New(Bone* bone -) { +KX_BoneParentRelation* KX_BoneParentRelation::New(Bone* bone) +{ return new KX_BoneParentRelation(bone); } - bool -KX_BoneParentRelation:: -UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated -) { +bool KX_BoneParentRelation::UpdateChildCoordinates(SG_Spatial * child, const SG_Spatial * parent, bool& parentUpdated) +{ MT_assert(child != NULL); - + // This way of accessing child coordinates is a bit cumbersome // be nice to have non constant reference access to these values. + const MT_Vector3 & child_l_scale = child->GetLocalScale(); + const MT_Point3 & child_l_pos = child->GetLocalPosition(); + const MT_Matrix3x3 & child_l_orientation = child->GetLocalOrientation(); - const MT_Vector3 & child_scale = child->GetLocalScale(); - const MT_Point3 & child_pos = child->GetLocalPosition(); - const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); - // we don't know if the armature has been updated or not, assume yes - parentUpdated = true; - - // the childs world locations which we will update. - MT_Vector3 child_w_scale; MT_Point3 child_w_pos; - MT_Matrix3x3 child_w_rotation; + MT_Matrix3x3 child_w_orientation; bool valid_parent_transform = false; @@ -88,68 +68,62 @@ UpdateChildCoordinates( if (armature->GetBoneMatrix(m_bone, parent_matrix)) { // Get the child's transform, and the bone matrix. - MT_Matrix4x4 child_transform ( - MT_Transform(child_pos + MT_Vector3(0.0, armature->GetBoneLength(m_bone), 0.0), - child_rotation.scaled( - child_scale[0], - child_scale[1], - child_scale[2]))); - - // The child's world transform is parent * child - parent_matrix = parent->GetWorldTransform() * parent_matrix; - child_transform = parent_matrix * child_transform; + MT_Matrix4x4 child_transform ( + MT_Transform( + child_l_pos + MT_Vector3(0.0, armature->GetBoneLength(m_bone), 0.0), + child_l_orientation.scaled(child_l_scale[0], child_l_scale[1], child_l_scale[2]))); + + parent_matrix = parent->GetWorldTransform() * parent_matrix; //the bone is relative to the armature + child_transform = parent_matrix * child_transform; // The child's world transform is parent * child // Recompute the child transform components from the transform. child_w_scale.setValue( MT_Vector3(child_transform[0][0], child_transform[0][1], child_transform[0][2]).length(), MT_Vector3(child_transform[1][0], child_transform[1][1], child_transform[1][2]).length(), MT_Vector3(child_transform[2][0], child_transform[2][1], child_transform[2][2]).length()); - child_w_rotation.setValue(child_transform[0][0], child_transform[0][1], child_transform[0][2], + child_w_orientation.setValue( + child_transform[0][0], child_transform[0][1], child_transform[0][2], child_transform[1][0], child_transform[1][1], child_transform[1][2], child_transform[2][0], child_transform[2][1], child_transform[2][2]); - child_w_rotation.scale(1.0/child_w_scale[0], 1.0/child_w_scale[1], 1.0/child_w_scale[2]); - + child_w_orientation.scale(1.0/child_w_scale[0], 1.0/child_w_scale[1], 1.0/child_w_scale[2]); child_w_pos = MT_Point3(child_transform[0][3], child_transform[1][3], child_transform[2][3]); - + valid_parent_transform = true; } } - } - + } + if (valid_parent_transform) { child->SetWorldScale(child_w_scale); child->SetWorldPosition(child_w_pos); - child->SetWorldOrientation(child_w_rotation); + child->SetWorldOrientation(child_w_orientation); } else { + /* the parent is null or not an armature */ child->SetWorldFromLocalTransform(); } + + parentUpdated = true; //this variable is going to be used to update the children of this child child->ClearModified(); // this node must always be updated, so reschedule it for next time child->ActivateRecheduleUpdateCallback(); return valid_parent_transform; } - SG_ParentRelation * -KX_BoneParentRelation:: -NewCopy( -) { - KX_BoneParentRelation* bone_parent = new KX_BoneParentRelation(m_bone); - return bone_parent; +SG_ParentRelation* KX_BoneParentRelation::NewCopy() +{ + return new KX_BoneParentRelation(m_bone); } -KX_BoneParentRelation:: -~KX_BoneParentRelation( -) { +KX_BoneParentRelation::~KX_BoneParentRelation() +{ //nothing to do } -KX_BoneParentRelation:: -KX_BoneParentRelation(Bone* bone -) -: m_bone(bone) +KX_BoneParentRelation::KX_BoneParentRelation(Bone* bone) + : m_bone(bone) { // nothing to do } diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h index 6f4fd482198..9c983e65f5e 100644 --- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h +++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.h @@ -39,53 +39,33 @@ struct Bone; /** - * Bone parent relationship parents a child SG_Spatial frame to a - * bone in an armature object. + * Bone parent relationship parents a child SG_Spatial frame to a bone in an armature object. */ class KX_BoneParentRelation : public SG_ParentRelation { public : /** - * Allocate and construct a new KX_SG_BoneParentRelation - * on the heap. - * - * bone is the bone id to use. Currently it is a pointer - * to a Blender struct Bone - this should be fixed if + * Allocate and construct a new KX_SG_BoneParentRelation on the heap. */ - - static - KX_BoneParentRelation * - New(Bone* bone - ); + static KX_BoneParentRelation* New(Bone* bone); /** - * Updates the childs world coordinates relative to the parent's - * world coordinates. - * + * Updates the child's world coordinates based upon the local ones and relative to the parent's world coordinates. * Parent should be a BL_ArmatureObject. */ - bool - UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated - ); + bool UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated); /** * Create a copy of this relationship */ - SG_ParentRelation * - NewCopy( - ); + SG_ParentRelation* NewCopy(); - ~KX_BoneParentRelation( - ); + ~KX_BoneParentRelation(); private : Bone* m_bone; - KX_BoneParentRelation(Bone* bone - ); + KX_BoneParentRelation(Bone* bone); #ifdef WITH_CXX_GUARDEDALLOC @@ -93,4 +73,4 @@ private : #endif }; -#endif +#endif /* __KX_SG_BONEPARENTNODERELATIONSHIP_H__ */ diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp index e80de76861e..160654c26f1 100644 --- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp @@ -32,267 +32,214 @@ #include "KX_SG_NodeRelationships.h" -/** - * Implementation of classes defined in KX_SG_NodeRelationships.h - */ /** - * first of all KX_NormalParentRelation + * KX_NormalParentRelation - a regular parent/child relation, the child's coordinates are relative to the parent */ - KX_NormalParentRelation * -KX_NormalParentRelation:: -New( -) { +KX_NormalParentRelation* KX_NormalParentRelation::New() +{ return new KX_NormalParentRelation(); } - bool -KX_NormalParentRelation:: -UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated -) { +bool KX_NormalParentRelation::UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated) +{ MT_assert(child != NULL); + /* If nothing changed in the parent or child, there is nothing to do here */ if (!parentUpdated && !child->IsModified()) return false; - parentUpdated = true; - - if (parent==NULL) { /* Simple case */ + /* The child has no parent, it is a root object. + * The world and local coordinates should be the same and applied directly. */ + if (parent==NULL) { child->SetWorldFromLocalTransform(); - child->ClearModified(); - return true; //false; } + /* The child has a parent. The child's coordinates are defined relative to the parent's. + * The parent's coordinates should be applied to the child's local ones to calculate the real world position. */ else { - // the childs world locations which we will update. - const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); - const MT_Point3 & p_world_pos = parent->GetWorldPosition(); - const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); - - child->SetWorldScale(p_world_scale * child->GetLocalScale()); - child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation()); - child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition())); - child->ClearModified(); - return true; + const MT_Vector3 & parent_world_scale = parent->GetWorldScaling(); + const MT_Point3 & parent_world_pos = parent->GetWorldPosition(); + const MT_Matrix3x3 & parent_world_ori = parent->GetWorldOrientation(); + const MT_Vector3 & child_local_scale = child->GetLocalScale(); + const MT_Point3 & child_local_pos = child->GetLocalPosition(); + const MT_Matrix3x3 & child_local_ori = child->GetLocalOrientation(); + + const MT_Vector3 & new_world_scale = parent_world_scale * child_local_scale; + const MT_Matrix3x3 & new_world_ori = parent_world_ori * child_local_ori; + const MT_Point3 & new_world_pos = parent_world_pos + (new_world_scale * (new_world_ori * child_local_pos)); + + child->SetWorldScale(new_world_scale); + child->SetWorldOrientation(new_world_ori); + child->SetWorldPosition(new_world_pos); } + + parentUpdated = true; //this variable is going to be used to update the children of this child + child->ClearModified(); + return true; } - SG_ParentRelation * -KX_NormalParentRelation:: -NewCopy( -) { +SG_ParentRelation* KX_NormalParentRelation::NewCopy() +{ return new KX_NormalParentRelation(); } -KX_NormalParentRelation:: -~KX_NormalParentRelation( -) { +KX_NormalParentRelation::~KX_NormalParentRelation() +{ //nothing to do } - -KX_NormalParentRelation:: -KX_NormalParentRelation( -) { +KX_NormalParentRelation::KX_NormalParentRelation() +{ // nothing to do } -/** - * Next KX_VertexParentRelation - */ - KX_VertexParentRelation * -KX_VertexParentRelation:: -New( -) { - return new KX_VertexParentRelation(); -} - -/** - * Method inherited from KX_ParentRelation + + +/** + * KX_VertexParentRelation - the child only inherits the position, not the orientation or scale */ - bool -KX_VertexParentRelation:: -UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated -) { +KX_VertexParentRelation* KX_VertexParentRelation::New() +{ + return new KX_VertexParentRelation(); +} +bool KX_VertexParentRelation::UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated) +{ MT_assert(child != NULL); + /* If nothing changed in the parent or child, there is nothing to do here */ if (!parentUpdated && !child->IsModified()) return false; - child->SetWorldScale(child->GetLocalScale()); - - if (parent) - child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition()); - else + /* The parent (if existing) is a vertex, so only position should be applied + * to the child's local coordinates to calculate the real world position. */ + + if (parent==NULL) child->SetWorldPosition(child->GetLocalPosition()); - + else + child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition()); + + child->SetWorldScale(child->GetLocalScale()); child->SetWorldOrientation(child->GetLocalOrientation()); + + parentUpdated = true; //this variable is going to be used to update the children of this child child->ClearModified(); - return true; //parent != NULL; + return true; } -/** - * Method inherited from KX_ParentRelation - */ - - SG_ParentRelation * -KX_VertexParentRelation:: -NewCopy( -) { +SG_ParentRelation* KX_VertexParentRelation::NewCopy() +{ return new KX_VertexParentRelation(); -}; +} -KX_VertexParentRelation:: -~KX_VertexParentRelation( -) { +KX_VertexParentRelation::~KX_VertexParentRelation() +{ //nothing to do } - -KX_VertexParentRelation:: -KX_VertexParentRelation( -) { +KX_VertexParentRelation::KX_VertexParentRelation() +{ //nothing to do } + + + /** - * Slow parent relationship + * KX_SlowParentRelation - the child only inherits the position, not the orientation or scale */ - KX_SlowParentRelation * -KX_SlowParentRelation:: -New( - MT_Scalar relaxation -) { - return new KX_SlowParentRelation(relaxation); +KX_SlowParentRelation* KX_SlowParentRelation::New(MT_Scalar relaxation) +{ + return new KX_SlowParentRelation(relaxation); } -/** - * Method inherited from KX_ParentRelation - */ - - bool -KX_SlowParentRelation:: -UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated -) { +bool KX_SlowParentRelation::UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated) +{ MT_assert(child != NULL); - // the child will move even if the parent is not - parentUpdated = true; - - const MT_Vector3 & child_scale = child->GetLocalScale(); - const MT_Point3 & child_pos = child->GetLocalPosition(); - const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); - - // the childs world locations which we will update. - - MT_Vector3 child_w_scale; - MT_Point3 child_w_pos; - MT_Matrix3x3 child_w_rotation; - - if (parent) { - - // This is a slow parent relation - // first compute the normal child world coordinates. - - MT_Vector3 child_n_scale; - MT_Point3 child_n_pos; - MT_Matrix3x3 child_n_rotation; - - const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); - const MT_Point3 & p_world_pos = parent->GetWorldPosition(); - const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); - - child_n_scale = p_world_scale * child_scale; - child_n_rotation = p_world_rotation * child_rotation; - - child_n_pos = p_world_pos + p_world_scale * - (p_world_rotation * child_pos); - + /* The child has no parent, it is a root object. + * The world and local coordinates should be the same and applied directly. */ + if (parent==NULL) { + child->SetWorldFromLocalTransform(); + } + /* The child's coordinates get linearly interpolated with the parent's */ + else { + const MT_Vector3 & parent_world_scale = parent->GetWorldScaling(); + const MT_Point3 & parent_world_pos = parent->GetWorldPosition(); + const MT_Matrix3x3 & parent_world_ori = parent->GetWorldOrientation(); + const MT_Vector3 & child_local_scale = child->GetLocalScale(); + const MT_Point3 & child_local_pos = child->GetLocalPosition(); + const MT_Matrix3x3 & child_local_ori = child->GetLocalOrientation(); + + /* Compute the normal world coordinates, where the child would be if it was a normal parent relation */ + const MT_Vector3 & normal_world_scale = parent_world_scale * child_local_scale; + const MT_Matrix3x3 & normal_world_ori = parent_world_ori * child_local_ori; + const MT_Point3 & normal_world_pos = parent_world_pos + (normal_world_scale * (normal_world_ori * child_local_pos)); + + MT_Vector3 new_world_scale; + MT_Point3 new_world_pos; + MT_Matrix3x3 new_world_ori; if (m_initialized) { - // get the current world positions + /* Get the current world positions */ + const MT_Vector3 & current_world_scale = child->GetWorldScaling(); + const MT_Matrix3x3 & current_world_ori = child->GetWorldOrientation(); + const MT_Point3 & current_world_pos = child->GetWorldPosition(); - child_w_scale = child->GetWorldScaling(); - child_w_pos = child->GetWorldPosition(); - child_w_rotation = child->GetWorldOrientation(); + /* Interpolate between the current world coordinates and the normal ones according to the weight. + * a bigger relax parameter, is a smaller weight, + * meaning that the child follows its normal position in smaller steps*/ + /* XXX - this design has problems as it does not consider elapsed time between last update */ + new_world_ori.setRotation(current_world_ori.getRotation().slerp(normal_world_ori.getRotation(), m_weight)); + new_world_pos = current_world_pos + ( (normal_world_pos - current_world_pos) * m_weight); + new_world_scale = current_world_scale + ( (normal_world_scale - current_world_scale) * m_weight); - // now 'interpolate' the normal coordinates with the last - // world coordinates to get the new world coordinates. - - MT_Scalar weight = MT_Scalar(1)/(m_relax + 1); - child_w_scale = (m_relax * child_w_scale + child_n_scale) * weight; - child_w_pos = (m_relax * child_w_pos + child_n_pos) * weight; - // for rotation we must go through quaternion - MT_Quaternion child_w_quat = child_w_rotation.getRotation().slerp(child_n_rotation.getRotation(), weight); - child_w_rotation.setRotation(child_w_quat); //FIXME: update physics controller. + } else { - child_w_scale = child_n_scale; - child_w_pos = child_n_pos; - child_w_rotation = child_n_rotation; + /** + * We need to compute valid world coordinates the first + * time we update spatial data of the child. This is done + * by just doing a normal parent relation the first time. + */ + new_world_scale = normal_world_scale; + new_world_ori = normal_world_ori; + new_world_pos = normal_world_pos; m_initialized = true; } - - } else { - child_w_scale = child_scale; - child_w_pos = child_pos; - child_w_rotation = child_rotation; + child->SetWorldScale(new_world_scale); + child->SetWorldOrientation(new_world_ori); + child->SetWorldPosition(new_world_pos); } - child->SetWorldScale(child_w_scale); - child->SetWorldPosition(child_w_pos); - child->SetWorldOrientation(child_w_rotation); + parentUpdated = true; //this variable is going to be used to update the children of this child child->ClearModified(); // this node must always be updated, so reschedule it for next time child->ActivateRecheduleUpdateCallback(); - - return true; //parent != NULL; + return true; } -/** - * Method inherited from KX_ParentRelation - */ - - SG_ParentRelation * -KX_SlowParentRelation:: -NewCopy( -) { +SG_ParentRelation* KX_SlowParentRelation::NewCopy() +{ return new KX_SlowParentRelation(m_relax); } -KX_SlowParentRelation:: -KX_SlowParentRelation( - MT_Scalar relaxation -): - m_relax(relaxation), - m_initialized(false) +KX_SlowParentRelation::KX_SlowParentRelation(MT_Scalar relaxation) + :m_initialized(false) { - //nothing to do + m_relax = fabs(relaxation); + m_weight = MT_Scalar(1)/(m_relax + 1); } -KX_SlowParentRelation:: -~KX_SlowParentRelation( -) { +KX_SlowParentRelation::~KX_SlowParentRelation() +{ //nothing to do } - - - - diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h index 5d777f5028f..54b940351ca 100644 --- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h @@ -28,15 +28,14 @@ /** \file KX_SG_NodeRelationships.h * \ingroup ketsji - * \section KX_SG_NodeRelationships - * This file provides common concrete implementations of - * SG_ParentRelation used by the game engine. These are - * KX_SlowParentRelation a slow parent relationship. - * KX_NormalParentRelation a normal parent relationship where - * orientation and position are inherited from the parent by + * \section KX_SG_NodeRelationships + * This file provides common concrete implementations of + * SG_ParentRelation used by the game engine. These are: + * - KX_NormalParentRelation a normal parent relationship where + * orientation, position and scale are inherited from the parent by * the child. - * KX_VertexParentRelation only location information is - * inherited by the child. + * - KX_VertexParentRelation only location information is inherited by the child. + * - KX_SlowParentRelation a slow parent relationship. */ #ifndef __KX_SG_NODERELATIONSHIPS_H__ @@ -50,41 +49,28 @@ class KX_NormalParentRelation : public SG_ParentRelation public : /** - * Allocate and construct a new KX_NormalParentRelation - * on the heap. + * Allocate and construct a new KX_NormalParentRelation on the heap. */ - - static - KX_NormalParentRelation * - New( - ); + static KX_NormalParentRelation* New(); /** * Method inherited from KX_ParentRelation + * Update the child's global coordinates based upon the local ones and the parent's global coordinates. */ - - bool - UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated - ); + bool UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated); /** * Method inherited from KX_ParentRelation + * This should return a pointer to a new duplicate allocated on the heap. + * Responsibility for deleting the duplicate resides with the caller of this method. */ - - SG_ParentRelation * - NewCopy( - ); + SG_ParentRelation* NewCopy(); - ~KX_NormalParentRelation( - ); + ~KX_NormalParentRelation(); private : - KX_NormalParentRelation( - ); + KX_NormalParentRelation(); #ifdef WITH_CXX_GUARDEDALLOC @@ -99,47 +85,33 @@ class KX_VertexParentRelation : public SG_ParentRelation public : /** - * Allocate and construct a new KX_VertexParentRelation - * on the heap. + * Allocate and construct a new KX_VertexParentRelation on the heap. */ - - static - KX_VertexParentRelation * - New( - ); + static KX_VertexParentRelation* New(); /** * Method inherited from KX_ParentRelation + * Update the child's global coordinates based upon the local ones and the parent's global coordinates. */ - - bool - UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated - ); + bool UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated); /** * Method inherited from KX_ParentRelation + * This should return a pointer to a new duplicate allocated on the heap. + * Responsibility for deleting the duplicate resides with the caller of this method. */ - - SG_ParentRelation * - NewCopy( - ); + SG_ParentRelation * NewCopy(); - ~KX_VertexParentRelation( - ); + ~KX_VertexParentRelation(); - bool - IsVertexRelation( - ) { + bool IsVertexRelation() + { return true; } private : - KX_VertexParentRelation( - ); + KX_VertexParentRelation(); #ifdef WITH_CXX_GUARDEDALLOC @@ -154,72 +126,43 @@ class KX_SlowParentRelation : public SG_ParentRelation public : /** - * Allocate and construct a new KX_VertexParentRelation - * on the heap. + * Allocate and construct a new KX_SlowParentRelation on the heap. */ + static KX_SlowParentRelation* New(MT_Scalar relaxation); - static - KX_SlowParentRelation * - New( - MT_Scalar relaxation - ); - - /** + /** * Method inherited from KX_ParentRelation + * Update the child's global coordinates based upon the local ones and the parent's global coordinates. */ + bool UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated); - bool - UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated - ); - - /** + /** * Method inherited from KX_ParentRelation + * This should return a pointer to a new duplicate allocated on the heap. + * Responsibility for deleting the duplicate resides with the caller of this method. */ - - SG_ParentRelation * - NewCopy( - ); - - MT_Scalar - GetTimeOffset( - ) { return m_relax; } - - void - SetTimeOffset( - MT_Scalar relaxation - ) { m_relax = relaxation; } - - ~KX_SlowParentRelation( - ); - - bool - IsSlowRelation( - ) { + SG_ParentRelation* NewCopy(); + + ~KX_SlowParentRelation(); + + bool IsSlowRelation() + { return true; } -private : + MT_Scalar GetTimeOffset() { return m_relax; } + void SetTimeOffset(MT_Scalar relaxation) { m_relax = relaxation; } - KX_SlowParentRelation( - MT_Scalar relaxation - ); +private : - // the relaxation coefficient. + KX_SlowParentRelation(MT_Scalar relaxation); - MT_Scalar m_relax; + MT_Scalar m_relax; /* the relaxation coefficient. the bigger, the slower */ + MT_Scalar m_weight; /*inverse relax coefficient, computed only once for calculations*/ /** * Looks like a hack flag to me. - * We need to compute valid world coordinates the first - * time we update spatial data of the child. This is done - * by just doing a normal parent relation the first time - * UpdateChildCoordinates is called and then doing the - * slow parent relation */ - bool m_initialized; @@ -228,4 +171,4 @@ private : #endif }; -#endif +#endif /* __KX_SG_NODERELATIONSHIPS_H__ */ diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index b6fd69fe1f4..97ebd6d40a9 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -867,8 +867,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject, m_map_gameobject_to_replica.clear(); m_groupGameObjects.clear(); - // todo: place a timebomb in the object, for temporarily objects :) - // lifespan of zero means 'this object lives forever' KX_GameObject* originalobj = (KX_GameObject*) originalobject; KX_GameObject* parentobj = (KX_GameObject*) parentobject; @@ -877,9 +875,10 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject, // lets create a replica KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj); + // add a timebomb to this object + // lifespan of zero means 'this object lives forever' if (lifespan > 0) { - // add a timebomb to this object // for now, convert between so called frames and realtime m_tempObjectList->Add(replica->AddRef()); // this convert the life from frames to sort-of seconds, hard coded 0.02 that assumes we have 50 frames per second @@ -915,7 +914,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject, // get the rootnode's scale MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale(); - // set the replica's relative scale with the rootnode's scale replica->NodeSetRelativeScale(newscale); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h index 4d0d96e07c6..5d3ffaca0f7 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h @@ -272,6 +272,7 @@ struct CcdConstructionInfo m_bSoft(false), m_bSensor(false), m_bCharacter(false), + m_bVehicle(false), m_bGimpact(false), m_collisionFilterGroup(DefaultFilter), m_collisionFilterMask(AllFilter), @@ -299,8 +300,8 @@ struct CcdConstructionInfo btVector3 m_linearFactor; btVector3 m_angularFactor; btScalar m_mass; - btScalar m_clamp_vel_min; - btScalar m_clamp_vel_max; + btScalar m_clamp_vel_min; + btScalar m_clamp_vel_max; btScalar m_restitution; btScalar m_friction; btScalar m_linearDamping; @@ -356,6 +357,7 @@ struct CcdConstructionInfo bool m_bSoft; bool m_bSensor; bool m_bCharacter; + bool m_bVehicle; bool m_bGimpact; // use Gimpact for mesh body ///optional use of collision group/mask: diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 38e7df6c573..739cf552835 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -58,14 +58,13 @@ extern "C" { #define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80 -#ifdef NEW_BULLET_VEHICLE_SUPPORT +/* Vehicle Controller */ #include "BulletDynamics/Vehicle/btRaycastVehicle.h" #include "BulletDynamics/Vehicle/btVehicleRaycaster.h" #include "BulletDynamics/Vehicle/btWheelInfo.h" #include "PHY_IVehicle.h" -static btRaycastVehicle::btVehicleTuning gTuning; +static btRaycastVehicle::btVehicleTuning gTuning; -#endif //NEW_BULLET_VEHICLE_SUPPORT #include "LinearMath/btAabbUtil2.h" #include "MT_Matrix4x4.h" #include "MT_Vector3.h" @@ -97,220 +96,200 @@ void DrawRasterizerLine(const float* from,const float* to,int color); #endif //_MSC_VER #endif //WIN32 -#ifdef NEW_BULLET_VEHICLE_SUPPORT class WrapperVehicle : public PHY_IVehicle { - - btRaycastVehicle* m_vehicle; - PHY_IPhysicsController* m_chassis; + btRaycastVehicle *m_vehicle; + PHY_IPhysicsController *m_chassis; public: WrapperVehicle(btRaycastVehicle* vehicle,PHY_IPhysicsController* chassis) :m_vehicle(vehicle), m_chassis(chassis) - { - } + {} ~WrapperVehicle() { delete m_vehicle; } - btRaycastVehicle* GetVehicle() + btRaycastVehicle* GetVehicle() { return m_vehicle; } - PHY_IPhysicsController* GetChassis() + PHY_IPhysicsController* GetChassis() { return m_chassis; } - virtual void AddWheel( - PHY_IMotionState* motionState, - MT_Vector3 connectionPoint, - MT_Vector3 downDirection, - MT_Vector3 axleDirection, - float suspensionRestLength, + virtual void AddWheel( + PHY_IMotionState *motionState, + MT_Vector3 connectionPoint, + MT_Vector3 downDirection, + MT_Vector3 axleDirection, + float suspensionRestLength, float wheelRadius, bool hasSteering - ) + ) { btVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]); btVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]); btVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]); - - btWheelInfo& info = m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxle, - suspensionRestLength,wheelRadius,gTuning,hasSteering); + btWheelInfo& info = m_vehicle->addWheel( connectionPointCS0, + wheelDirectionCS0, + wheelAxle, + suspensionRestLength, + wheelRadius, + gTuning, + hasSteering + ); info.m_clientInfo = motionState; - } - void SyncWheels() + void SyncWheels() { int numWheels = GetNumWheels(); int i; - for (i=0;i<numWheels;i++) - { - btWheelInfo& info = m_vehicle->getWheelInfo(i); - PHY_IMotionState* motionState = (PHY_IMotionState*)info.m_clientInfo; - // m_vehicle->updateWheelTransformsWS(info,false); + for (i=0;i<numWheels;i++) { m_vehicle->updateWheelTransform(i,false); + btTransform trans = m_vehicle->getWheelInfo(i).m_worldTransform; btQuaternion orn = trans.getRotation(); const btVector3& pos = trans.getOrigin(); + PHY_IMotionState* motionState = (PHY_IMotionState*)m_vehicle->getWheelInfo(i).m_clientInfo; motionState->SetWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); motionState->SetWorldPosition(pos.x(),pos.y(),pos.z()); - } } - virtual int GetNumWheels() const + virtual int GetNumWheels() const { return m_vehicle->getNumWheels(); } - virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const + virtual void GetWheelPosition(int wheelIndex, float &posX, float &posY, float &posZ) const { - btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex); - posX = trans.getOrigin().x(); - posY = trans.getOrigin().y(); - posZ = trans.getOrigin().z(); + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { + btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex); + posX = trans.getOrigin().x(); + posY = trans.getOrigin().y(); + posZ = trans.getOrigin().z(); + } } - virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const - { - btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex); - btQuaternion quat = trans.getRotation(); - btMatrix3x3 orn2(quat); - - quatX = trans.getRotation().x(); - quatY = trans.getRotation().y(); - quatZ = trans.getRotation().z(); - quatW = trans.getRotation()[3]; - - - //printf("test"); + virtual void GetWheelOrientationQuaternion(int wheelIndex, float &quatX, float &quatY, float &quatZ, float &quatW) const + { + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { + btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex); + btQuaternion quat = trans.getRotation(); + quatX = quat.x(); + quatY = quat.y(); + quatZ = quat.z(); + quatW = quat[3]; + } } - virtual float GetWheelRotation(int wheelIndex) const + virtual float GetWheelRotation(int wheelIndex) const { float rotation = 0.f; - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); rotation = info.m_rotation; } return rotation; - } - - - virtual int GetUserConstraintId() const + virtual int GetUserConstraintId() const { return m_vehicle->getUserConstraintId(); } - virtual int GetUserConstraintType() const + virtual int GetUserConstraintType() const { return m_vehicle->getUserConstraintType(); } - virtual void SetSteeringValue(float steering,int wheelIndex) + virtual void SetSteeringValue(float steering, int wheelIndex) { m_vehicle->setSteeringValue(steering,wheelIndex); } - virtual void ApplyEngineForce(float force,int wheelIndex) + virtual void ApplyEngineForce(float force, int wheelIndex) { m_vehicle->applyEngineForce(force,wheelIndex); } - virtual void ApplyBraking(float braking,int wheelIndex) + virtual void ApplyBraking(float braking, int wheelIndex) { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); info.m_brake = braking; } } - virtual void SetWheelFriction(float friction,int wheelIndex) + virtual void SetWheelFriction(float friction, int wheelIndex) { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); info.m_frictionSlip = friction; } - } - virtual void SetSuspensionStiffness(float suspensionStiffness,int wheelIndex) + virtual void SetSuspensionStiffness(float suspensionStiffness, int wheelIndex) { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); info.m_suspensionStiffness = suspensionStiffness; - } } - virtual void SetSuspensionDamping(float suspensionDamping,int wheelIndex) + virtual void SetSuspensionDamping(float suspensionDamping, int wheelIndex) { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); info.m_wheelsDampingRelaxation = suspensionDamping; } } - virtual void SetSuspensionCompression(float suspensionCompression,int wheelIndex) + virtual void SetSuspensionCompression(float suspensionCompression,int wheelIndex) { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); info.m_wheelsDampingCompression = suspensionCompression; } } - - - virtual void SetRollInfluence(float rollInfluence,int wheelIndex) + virtual void SetRollInfluence(float rollInfluence, int wheelIndex) { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { + if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) { btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); info.m_rollInfluence = rollInfluence; } } - virtual void SetCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) + virtual void SetCoordinateSystem(int rightIndex, int upIndex, int forwardIndex) { m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex); } - - }; + class BlenderVehicleRaycaster: public btDefaultVehicleRaycaster { - btDynamicsWorld* m_dynamicsWorld; + btDynamicsWorld *m_dynamicsWorld; + public: - BlenderVehicleRaycaster(btDynamicsWorld* world) + BlenderVehicleRaycaster(btDynamicsWorld *world) :btDefaultVehicleRaycaster(world), m_dynamicsWorld(world) - { - } + {} - virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) + virtual void* castRay(const btVector3 &from,const btVector3 &to, btVehicleRaycasterResult &result) { - // RayResultCallback& resultCallback; - btCollisionWorld::ClosestRayResultCallback rayCallback(from,to); // We override btDefaultVehicleRaycaster so we can set this flag, otherwise our @@ -319,12 +298,9 @@ public: m_dynamicsWorld->rayTest(from, to, rayCallback); - if (rayCallback.hasHit()) - { - + if (rayCallback.hasHit()) { const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); - if (body && body->hasContactResponse()) - { + if (body && body->hasContactResponse()) { result.m_hitPointInWorld = rayCallback.m_hitPointWorld; result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld; result.m_hitNormalInWorld.normalize(); @@ -335,7 +311,7 @@ public: return 0; } }; -#endif //NEW_BULLET_VEHICLE_SUPPORT + class CcdOverlapFilterCallBack : public btOverlapFilterCallback { @@ -1967,10 +1943,7 @@ void CcdPhysicsEnvironment::MergeEnvironment(PHY_IPhysicsEnvironment *other_env) CcdPhysicsEnvironment::~CcdPhysicsEnvironment() { - -#ifdef NEW_BULLET_VEHICLE_SUPPORT m_wrapperVehicles.clear(); -#endif //NEW_BULLET_VEHICLE_SUPPORT //m_broadphase->DestroyScene(); //delete broadphase ? release reference on broadphase ? @@ -2373,16 +2346,14 @@ bool CcdOverlapFilterCallBack::needBroadphaseCollision(btBroadphaseProxy* proxy0 } -#ifdef NEW_BULLET_VEHICLE_SUPPORT //complex constraint for vehicles -PHY_IVehicle* CcdPhysicsEnvironment::GetVehicleConstraint(int constraintId) +PHY_IVehicle* CcdPhysicsEnvironment::GetVehicleConstraint(int constraintId) { int i; - int numVehicles = m_wrapperVehicles.size(); - for (i=0;i<numVehicles;i++) - { + + for (i=0; i<numVehicles; i++) { WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; if (wrapperVehicle->GetVehicle()->getUserConstraintId() == constraintId) return wrapperVehicle; @@ -2391,8 +2362,6 @@ PHY_IVehicle* CcdPhysicsEnvironment::GetVehicleConstraint(int constraintId) return 0; } -#endif //NEW_BULLET_VEHICLE_SUPPORT - PHY_ICharacter* CcdPhysicsEnvironment::GetCharacterController(KX_GameObject *ob) { @@ -2865,7 +2834,6 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl return hinge->getUserConstraintId(); break; } -#ifdef NEW_BULLET_VEHICLE_SUPPORT case PHY_VEHICLE_CONSTRAINT: { @@ -2882,7 +2850,6 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl break; }; -#endif //NEW_BULLET_VEHICLE_SUPPORT default: { @@ -3039,6 +3006,7 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject bool isbulletdyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;; bool isbulletsensor = (blenderobject->gameflag & OB_SENSOR) != 0; bool isbulletchar = (blenderobject->gameflag & OB_CHARACTER) != 0; + bool isbulletvehicle = (blenderobject->gameflag & OB_VEHICLE) != 0; bool isbulletsoftbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0; bool isbulletrigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0; bool useGimpact = false; @@ -3065,7 +3033,7 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject { ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; } - if ((blenderobject->gameflag & (OB_GHOST | OB_SENSOR | OB_CHARACTER)) != 0) + if ((blenderobject->gameflag & (OB_GHOST | OB_SENSOR | OB_CHARACTER | OB_VEHICLE)) != 0) { ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE; } @@ -3189,6 +3157,8 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject bounds = OB_BOUND_TRIANGLE_MESH; else if (blenderobject->gameflag & OB_CHARACTER) bounds = OB_BOUND_SPHERE; + else if (blenderobject->gameflag & OB_VEHICLE) + bounds = OB_BOUND_BOX; } else { @@ -3455,19 +3425,20 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject ci.m_collisionFilterGroup = (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) : - (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : - (isbulletchar) ? short(CcdConstructionInfo::CharacterFilter) : - short(CcdConstructionInfo::StaticFilter); + (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : + (isbulletchar || isbulletvehicle) ? short(CcdConstructionInfo::CharacterFilter) : + short(CcdConstructionInfo::StaticFilter); ci.m_collisionFilterMask = (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) : - (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : - (isbulletchar) ? short(CcdConstructionInfo::AllFilter) : - short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); + (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : + (isbulletchar || isbulletvehicle) ? short(CcdConstructionInfo::AllFilter) : + short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); ci.m_bRigid = isbulletdyna && isbulletrigidbody; ci.m_bSoft = isbulletsoftbody; ci.m_bDyna = isbulletdyna; ci.m_bSensor = isbulletsensor; ci.m_bCharacter = isbulletchar; + ci.m_bVehicle = isbulletvehicle; ci.m_bGimpact = useGimpact; MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index ff8a3f4f9f9..48349e7bc74 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -39,9 +39,6 @@ class btCollisionDispatcher; class btDispatcher; //#include "btBroadphaseInterface.h" -//switch on/off new vehicle support -#define NEW_BULLET_VEHICLE_SUPPORT 1 - #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" class WrapperVehicle; @@ -176,16 +173,8 @@ protected: virtual void CallbackTriggers(); + virtual PHY_IVehicle* GetVehicleConstraint(int constraintId); -#ifdef NEW_BULLET_VEHICLE_SUPPORT - //complex constraint for vehicles - virtual PHY_IVehicle* GetVehicleConstraint(int constraintId); -#else - virtual class PHY_IVehicle* GetVehicleConstraint(int constraintId) - { - return 0; - } -#endif /* NEW_BULLET_VEHICLE_SUPPORT */ // Character physics wrapper virtual PHY_ICharacter* GetCharacterController(class KX_GameObject* ob); diff --git a/source/gameengine/Physics/common/PHY_ICharacter.h b/source/gameengine/Physics/common/PHY_ICharacter.h index a3d3000a143..c039df42b3f 100644 --- a/source/gameengine/Physics/common/PHY_ICharacter.h +++ b/source/gameengine/Physics/common/PHY_ICharacter.h @@ -14,8 +14,8 @@ class PHY_ICharacter { -public: - virtual ~PHY_ICharacter(){}; +public: + virtual ~PHY_ICharacter(){} virtual void Jump()= 0; virtual bool OnGround()= 0; diff --git a/source/gameengine/Physics/common/PHY_IVehicle.h b/source/gameengine/Physics/common/PHY_IVehicle.h index 1dcec69a335..65996ed25c8 100644 --- a/source/gameengine/Physics/common/PHY_IVehicle.h +++ b/source/gameengine/Physics/common/PHY_IVehicle.h @@ -18,7 +18,7 @@ class PHY_IMotionState; class PHY_IVehicle { public: - virtual ~PHY_IVehicle(){}; + virtual ~PHY_IVehicle(){} virtual void AddWheel( PHY_IMotionState* motionState, diff --git a/source/gameengine/SceneGraph/SG_Controller.cpp b/source/gameengine/SceneGraph/SG_Controller.cpp index 264942415c9..801f8e8dbb4 100644 --- a/source/gameengine/SceneGraph/SG_Controller.cpp +++ b/source/gameengine/SceneGraph/SG_Controller.cpp @@ -31,16 +31,12 @@ #include "SG_Controller.h" - void -SG_Controller:: -SetObject(SG_IObject* obj) +void SG_Controller::SetObject(SG_IObject* obj) { m_pObject = obj; // no checks yet ? } - void -SG_Controller:: -ClearObject( -) { +void SG_Controller::ClearObject() +{ m_pObject = NULL; } diff --git a/source/gameengine/SceneGraph/SG_Controller.h b/source/gameengine/SceneGraph/SG_Controller.h index a173633e13c..cd7d4b1cc39 100644 --- a/source/gameengine/SceneGraph/SG_Controller.h +++ b/source/gameengine/SceneGraph/SG_Controller.h @@ -40,45 +40,24 @@ /** * A scenegraph controller */ -class SG_Controller +class SG_Controller { public: - SG_Controller( - ) : - m_pObject(NULL) { - } + SG_Controller(): + m_pObject(NULL) + {} - virtual - ~SG_Controller( - ) {}; + virtual ~SG_Controller() {} - virtual - bool - Update( - double time - )=0; + virtual bool Update(double time)=0; - virtual - void - SetObject ( - SG_IObject* object - ); + virtual void SetObject (SG_IObject* object); - void - ClearObject( - ); + void ClearObject(); - virtual - void - SetSimulatedTime( - double time - )=0; + virtual void SetSimulatedTime(double time)=0; - virtual - SG_Controller* - GetReplica( - class SG_Node* destnode - )=0; + virtual SG_Controller* GetReplica(class SG_Node* destnode)=0; /** * Hacky way of passing options to specific controllers @@ -89,12 +68,7 @@ public: * \attention necessary because the identity of the controller * \attention is lost on the way here. */ - virtual - void - SetOption( - int option, - int value - )=0; + virtual void SetOption(int option, int value)=0; /** * Option-identifiers: SG_CONTR_<controller-type>_<option>. @@ -114,7 +88,7 @@ public: }; protected: - SG_IObject* m_pObject; + SG_IObject* m_pObject; #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_Controller") diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp index 9ae32a89ff8..6a60ac1d9ce 100644 --- a/source/gameengine/SceneGraph/SG_IObject.cpp +++ b/source/gameengine/SceneGraph/SG_IObject.cpp @@ -37,12 +37,7 @@ SG_Stage gSG_Stage = SG_STAGE_UNKNOWN; -SG_IObject:: -SG_IObject( - void* clientobj, - void* clientinfo, - SG_Callbacks& callbacks -): +SG_IObject::SG_IObject(void* clientobj, void* clientinfo, SG_Callbacks& callbacks): SG_QList(), m_SGclientObject(clientobj), m_SGclientInfo(clientinfo) @@ -50,10 +45,7 @@ SG_IObject( m_callbacks = callbacks; } -SG_IObject:: -SG_IObject( - const SG_IObject &other -) : +SG_IObject::SG_IObject(const SG_IObject &other): SG_QList(), m_SGclientObject(other.m_SGclientObject), m_SGclientInfo(other.m_SGclientInfo), @@ -62,28 +54,17 @@ SG_IObject( //nothing to do } - void -SG_IObject:: -AddSGController( - SG_Controller* cont -) { +void SG_IObject::AddSGController(SG_Controller* cont) { m_SGcontrollers.push_back(cont); } - void -SG_IObject:: -RemoveSGController( - SG_Controller* cont -) { - SGControllerList::iterator contit; - +void SG_IObject::RemoveSGController(SG_Controller* cont) +{ m_SGcontrollers.erase(std::remove(m_SGcontrollers.begin(), m_SGcontrollers.end(), cont)); } - void -SG_IObject:: -RemoveAllControllers( -) { +void SG_IObject::RemoveAllControllers() +{ m_SGcontrollers.clear(); } @@ -98,9 +79,7 @@ void SG_IObject::SetControllerTime(double time) /// Needed for replication - -SG_IObject:: -~SG_IObject() +SG_IObject::~SG_IObject() { SGControllerList::iterator contit; diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h index 2dcf3c6492e..85b3bd624f0 100644 --- a/source/gameengine/SceneGraph/SG_IObject.h +++ b/source/gameengine/SceneGraph/SG_IObject.h @@ -63,7 +63,6 @@ inline void SG_SetActiveStage(SG_Stage stage) { gSG_Stage = stage; } - class SG_Controller; @@ -103,20 +102,22 @@ typedef bool (*SG_RescheduleUpdateCallback)( /** - * SG_Callbacks hold 2 call backs to the outside world. - * The first is meant to be called when objects are replicated. + * SG_ReplicationNewCallback is meant to be called when objects are replicated. * And allows the outside world to synchronize external objects * with replicated nodes and their children. - * The second is called when a node is destroyed and again - * is their for synchronization purposes - * These callbacks may both be NULL. - * The efficacy of this approach has not been proved some - * alternatives might be to perform all replication and destruction - * externally. - * To define a class interface rather than a simple function - * call back so that replication information can be transmitted from + * + * SG_DestructionNewCallback is called when a node is destroyed and again + * is for synchronization purposes + * + * These callbacks may be NULL. + * The efficacy of this approach has not been proved. + * Some alternatives might be + * 1 - to perform all replication and destruction externally. + * 2 - to define a class interface rather than a simple function + * callback so that replication information can be transmitted from * parent->child. */ + struct SG_Callbacks { SG_Callbacks( @@ -173,21 +174,14 @@ public: * responsibility of this class. It will be deleted when * this object is deleted. */ - - void - AddSGController( - SG_Controller* cont - ); + void AddSGController(SG_Controller* cont); /** * Remove a pointer to a controller from this node. * This does not delete the controller itself! Be careful to * avoid memory leaks. */ - void - RemoveSGController( - SG_Controller* cont - ); + void RemoveSGController(SG_Controller* cont); /** * Clear the array of pointers to controllers associated with @@ -195,10 +189,7 @@ public: * This should be used very carefully to avoid memory * leaks. */ - - void - RemoveAllControllers( - ); + void RemoveAllControllers(); /// Needed for replication @@ -279,17 +270,10 @@ public: void SetControllerTime(double time); - virtual - void - Destruct( - ) = 0; + virtual void Destruct() = 0; protected : - - bool - ActivateReplicationCallback( - SG_IObject *replica - ) + bool ActivateReplicationCallback(SG_IObject *replica) { if (m_callbacks.m_replicafunc) { @@ -301,9 +285,7 @@ protected : } - void - ActivateDestructionCallback( - ) + void ActivateDestructionCallback() { if (m_callbacks.m_destructionfunc) { @@ -317,9 +299,7 @@ protected : } } - void - ActivateUpdateTransformCallback( - ) + void ActivateUpdateTransformCallback() { if (m_callbacks.m_updatefunc) { @@ -328,9 +308,7 @@ protected : } } - bool - ActivateScheduleUpdateCallback( - ) + bool ActivateScheduleUpdateCallback() { // HACK, this check assumes that the scheduled nodes are put on a DList (see SG_Node.h) // The early check on Empty() allows up to avoid calling the callback function @@ -343,9 +321,7 @@ protected : return false; } - void - ActivateRecheduleUpdateCallback( - ) + void ActivateRecheduleUpdateCallback() { if (m_callbacks.m_reschedulefunc) { diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp index 04d9a306fc4..1a2597eb687 100644 --- a/source/gameengine/SceneGraph/SG_Node.cpp +++ b/source/gameengine/SceneGraph/SG_Node.cpp @@ -37,21 +37,14 @@ using namespace std; -SG_Node::SG_Node( - void* clientobj, - void* clientinfo, - SG_Callbacks& callbacks - -) - : SG_Spatial(clientobj,clientinfo,callbacks), +SG_Node::SG_Node(void* clientobj, void* clientinfo, SG_Callbacks& callbacks): + SG_Spatial(clientobj,clientinfo,callbacks), m_SGparent(NULL) { m_modified = true; } -SG_Node::SG_Node( - const SG_Node & other -) : +SG_Node::SG_Node(const SG_Node & other): SG_Spatial(other), m_children(other.m_children), m_SGparent(other.m_SGparent) @@ -74,11 +67,8 @@ SG_Node* SG_Node::GetSGReplica() return replica; } - void -SG_Node:: -ProcessSGReplica( - SG_Node** replica -) { +void SG_Node::ProcessSGReplica(SG_Node** replica) +{ // Apply the replication call back function. if (!ActivateReplicationCallback(*replica)) { @@ -115,10 +105,7 @@ ProcessSGReplica( } } - - void -SG_Node:: -Destruct() +void SG_Node::Destruct() { // Not entirely sure what Destruct() expects to happen. // I think it probably means just to call the DestructionCallback @@ -142,11 +129,8 @@ Destruct() ActivateDestructionCallback(); } -const - SG_Node * -SG_Node:: -GetRootSGParent( -) const { +const SG_Node* SG_Node::GetRootSGParent() const +{ return (m_SGparent ? (const SG_Node*) m_SGparent->GetRootSGParent() : (const SG_Node*) this); } @@ -156,10 +140,8 @@ bool SG_Node::IsAncessor(const SG_Node* child) const (child->m_SGparent == this) ? true : IsAncessor(child->m_SGparent); } - void -SG_Node:: -DisconnectFromParent( -) { +void SG_Node::DisconnectFromParent() +{ if (m_SGparent) { m_SGparent->RemoveChild(this); @@ -188,9 +170,6 @@ void SG_Node::RemoveChild(SG_Node* child) void SG_Node::UpdateWorldData(double time, bool parentUpdated) { - //if (!GetSGParent()) - // return; - if (UpdateSpatialData(GetSGParent(),time,parentUpdated)) // to update the ActivateUpdateTransformCallback(); @@ -209,7 +188,6 @@ void SG_Node::UpdateWorldData(double time, bool parentUpdated) void SG_Node::SetSimulatedTime(double time,bool recurse) { - // update the controllers of this node. SetControllerTime(time); @@ -223,5 +201,3 @@ void SG_Node::SetSimulatedTime(double time,bool recurse) } } - - diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h index bde64f21305..cb2376e38c0 100644 --- a/source/gameengine/SceneGraph/SG_Node.h +++ b/source/gameengine/SceneGraph/SG_Node.h @@ -43,19 +43,11 @@ typedef std::vector<SG_Node*> NodeList; class SG_Node : public SG_Spatial { public: - SG_Node( - void* clientobj, - void* clientinfo, - SG_Callbacks& callbacks - ); - - SG_Node( - const SG_Node & other - ); + SG_Node(void* clientobj, void* clientinfo, SG_Callbacks& callbacks); + SG_Node(const SG_Node & other); virtual ~SG_Node(); - /** * Add a child to this object. This also informs the child of * it's parent. @@ -63,10 +55,7 @@ public: * make a deep copy. */ - void - AddChild( - SG_Node* child - ); + void AddChild(SG_Node* child); /** * Remove a child node from this object. This just removes the child @@ -74,26 +63,19 @@ public: * This does not inform the child that this node is no longer it's parent. * If the node was not a child of this object no action is performed. */ - - void - RemoveChild( - SG_Node* child - ); + void RemoveChild(SG_Node* child); /** * Return true if the node is the ancestor of child */ - bool - IsAncessor( - const SG_Node* child - ) const; + bool IsAncessor(const SG_Node* child) const; + /** * Get the current list of children. Do not use this interface for * adding or removing children please use the methods of this class for * that. * \return a reference to the list of children of this node. */ - NodeList& GetSGChildren() { return this->m_children; @@ -103,7 +85,6 @@ public: * Get the current list of children. * \return a const reference to the current list of children of this node. */ - const NodeList& GetSGChildren() const { return this->m_children; @@ -112,7 +93,6 @@ public: /** * Clear the list of children associated with this node */ - void ClearSGChildren() { m_children.clear(); @@ -130,7 +110,6 @@ public: /** * Set the parent of this node. */ - void SetSGParent(SG_Node* parent) { m_SGparent = parent; @@ -139,19 +118,12 @@ public: /** * Return the top node in this node's Scene graph hierarchy */ - - const - SG_Node* - GetRootSGParent( - ) const; + const SG_Node* GetRootSGParent() const; /** * Disconnect this node from it's parent */ - - void - DisconnectFromParent( - ); + void DisconnectFromParent(); /** * Return vertex parent status. @@ -165,11 +137,9 @@ public: return false; } - /** * Return slow parent status. */ - bool IsSlowParent() { if (m_parent_relation) @@ -180,29 +150,17 @@ public: } - - /** * Update the spatial data of this node. Iterate through * the children of this node and update their world data. */ - - void - UpdateWorldData( - double time, - bool parentUpdated=false - ); + void UpdateWorldData(double time, bool parentUpdated=false); /** * Update the simulation time of this node. Iterate through * the children nodes and update their simulated time. */ - - void - SetSimulatedTime( - double time, - bool recurse - ); + void SetSimulatedTime(double time, bool recurse); /** * Schedule this node for update by placing it in head queue @@ -243,21 +201,12 @@ public: /** * Node replication functions. */ + SG_Node* GetSGReplica(); - SG_Node* - GetSGReplica( - ); + void Destruct(); - void - Destruct( - ); - private: - - void - ProcessSGReplica( - SG_Node** replica - ); + void ProcessSGReplica(SG_Node** replica); /** * The list of children of this node. diff --git a/source/gameengine/SceneGraph/SG_ParentRelation.h b/source/gameengine/SceneGraph/SG_ParentRelation.h index ce45b42c148..493fcd0fc83 100644 --- a/source/gameengine/SceneGraph/SG_ParentRelation.h +++ b/source/gameengine/SceneGraph/SG_ParentRelation.h @@ -32,17 +32,18 @@ * * \section SG_ParentRelationSection SG_ParentRelation * - * This is an abstract interface class to the Scene Graph library. + * This is an abstract interface class to the Scene Graph library. * It allows you to specify how child nodes react to parent nodes. + * * Normally a child will use it's parent's transforms to compute - * it's own global transforms. How this is performed depends on - * the type of relation. For example if the parent is a vertex - * parent to this child then the child should not inherit any - * rotation information from the parent. Or if the parent is a - * 'slow parent' to this child then the child should react + * its own global transforms. How this is performed depends on + * the type of relation. For example if the parent is a vertex + * parent to this child then the child should only inherit + * location information from the parent. Or if the parent is a + * 'slow parent' to this child then the child should react * slowly to changes in the parent's position. The exact relation - * is left for you to implement by filling out this interface - * with concrete examples. + * is left for you to implement by filling out this interface + * with concrete examples. * * There is exactly one SG_ParentRelation per SG_Node. Subclasses * should not be value types and should be allocated on the heap. @@ -57,26 +58,16 @@ class SG_Spatial; class SG_ParentRelation { public : + /** - * Update the childs local and global coordinates - * based upon the parents global coordinates. - * You must also handle the case when this node has no - * parent (parent == NULL). Usually you should just - * copy the local coordinates of the child to the - * world coordinates. - */ - - virtual - bool - UpdateChildCoordinates( - SG_Spatial * child, - const SG_Spatial * parent, - bool& parentUpdated - ) = 0; - - virtual - ~SG_ParentRelation( - ) {}; + * Update the child's local and global coordinates based upon the parents global coordinates. + * You must also handle the case when this node has no parent (parent == NULL). + * Usually you should just copy the local coordinates of the child to the world coordinates. + */ + virtual bool UpdateChildCoordinates(SG_Spatial * child, const SG_Spatial * parent, bool& parentUpdated) = 0; + + /* Destructor */ + virtual ~SG_ParentRelation() {} /** * You must provide a way of duplicating an @@ -85,55 +76,41 @@ public : * on the heap. Responsibility for deleting the * duplicate resides with the caller of this method. */ - - virtual - SG_ParentRelation * - NewCopy( - ) = 0; + virtual SG_ParentRelation* NewCopy() = 0; /** * Vertex Parent Relation are special: they don't propagate rotation */ - virtual - bool - IsVertexRelation( - ) { + virtual bool IsVertexRelation() + { return false; } - + /** * Need this to see if we are able to adjust time-offset from the python api */ - virtual - bool - IsSlowRelation( - ) { + virtual bool IsSlowRelation() + { return false; } + protected : /** - * Protected constructors - * this class is not meant to be instantiated. + * Protected constructors this class is not meant to be instantiated. */ - - SG_ParentRelation( - ) { - }; + SG_ParentRelation() {} /** * Copy construction should not be implemented */ + SG_ParentRelation(const SG_ParentRelation &); + - SG_ParentRelation( - const SG_ParentRelation & - ); - - #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_ParentRelation") #endif }; -#endif +#endif /* __SG_PARENTRELATION_H__ */ diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp index f30c80da434..c8edc139fe6 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.cpp +++ b/source/gameengine/SceneGraph/SG_Spatial.cpp @@ -35,46 +35,36 @@ #include "SG_Controller.h" #include "SG_ParentRelation.h" -SG_Spatial:: -SG_Spatial( - void* clientobj, - void* clientinfo, - SG_Callbacks& callbacks -): - +SG_Spatial::SG_Spatial(void* clientobj, void* clientinfo, SG_Callbacks& callbacks): SG_IObject(clientobj,clientinfo,callbacks), m_localPosition(0.0,0.0,0.0), m_localRotation(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0), m_localScaling(1.f,1.f,1.f), - + m_worldPosition(0.0,0.0,0.0), m_worldRotation(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0), m_worldScaling(1.f,1.f,1.f), m_parent_relation (NULL), - + m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)), m_radius(1.0), m_modified(false), m_ogldirty(false) -{ -} +{} -SG_Spatial:: -SG_Spatial( - const SG_Spatial& other -) : +SG_Spatial::SG_Spatial(const SG_Spatial& other): SG_IObject(other), m_localPosition(other.m_localPosition), m_localRotation(other.m_localRotation), m_localScaling(other.m_localScaling), - + m_worldPosition(other.m_worldPosition), m_worldRotation(other.m_worldRotation), m_worldScaling(other.m_worldScaling), m_parent_relation(NULL), - + m_bbox(other.m_bbox), m_radius(other.m_radius), m_modified(false), @@ -83,18 +73,13 @@ SG_Spatial( // duplicate the parent relation for this object m_parent_relation = other.m_parent_relation->NewCopy(); } - -SG_Spatial:: -~SG_Spatial() + +SG_Spatial::~SG_Spatial() { delete (m_parent_relation); } - void -SG_Spatial:: -SetParentRelation( - SG_ParentRelation *relation -) { +void SG_Spatial::SetParentRelation(SG_ParentRelation *relation) { delete (m_parent_relation); m_parent_relation = relation; SetModified(); @@ -107,20 +92,13 @@ SetParentRelation( */ - bool -SG_Spatial:: -UpdateSpatialData( - const SG_Spatial *parent, - double time, - bool& parentUpdated) +bool SG_Spatial::UpdateSpatialData(const SG_Spatial *parent, double time, bool& parentUpdated) { bool bComputesWorldTransform = false; // update spatial controllers - SGControllerList::iterator cit = GetSGControllerList().begin(); SGControllerList::const_iterator c_end = GetSGControllerList().end(); - for (;cit!=c_end;++cit) { if ((*cit)->Update(time)) @@ -130,71 +108,39 @@ UpdateSpatialData( // If none of the objects updated our values then we ask the // parent_relation object owned by this class to update // our world coordinates. - if (!bComputesWorldTransform) bComputesWorldTransform = ComputeWorldTransforms(parent, parentUpdated); return bComputesWorldTransform; } -/** - * Position and translation methods - */ - void -SG_Spatial:: -RelativeTranslate( - const MT_Vector3& trans, - const SG_Spatial *parent, - bool local -) { +void SG_Spatial::RelativeTranslate(const MT_Vector3& trans, bool local) +{ if (local) { - m_localPosition += m_localRotation * trans; - } - else { - if (parent) { - m_localPosition += trans * parent->GetWorldOrientation(); - } - else { - m_localPosition += trans; - } + m_localPosition += m_localScaling * (m_localRotation * trans); + } else { + m_localPosition += trans; } SetModified(); } - -/** - * Scaling methods. - */ - - -/** - * Orientation and rotation methods. - */ - - - void -SG_Spatial:: -RelativeRotate( - const MT_Matrix3x3& rot, - bool local -) { +void SG_Spatial::RelativeRotate(const MT_Matrix3x3& rot, bool local) { m_localRotation = m_localRotation * ( - local ? - rot - : - (GetWorldOrientation().inverse() * rot * GetWorldOrientation())); + local ? + rot: + (GetWorldOrientation().inverse() * rot * GetWorldOrientation())); SetModified(); } + MT_Transform SG_Spatial::GetWorldTransform() const { return MT_Transform(m_worldPosition, - m_worldRotation.scaled( - m_worldScaling[0], m_worldScaling[1], m_worldScaling[2])); + m_worldRotation.scaled(m_worldScaling[0], m_worldScaling[1], m_worldScaling[2])); } bool SG_Spatial::inside(const MT_Point3 &point) const diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h index aa917fa70db..bacae60b5d4 100644 --- a/source/gameengine/SceneGraph/SG_Spatial.h +++ b/source/gameengine/SceneGraph/SG_Spatial.h @@ -53,11 +53,11 @@ class SG_Spatial : public SG_IObject protected: MT_Point3 m_localPosition; - MT_Matrix3x3 m_localRotation; + MT_Matrix3x3 m_localRotation; MT_Vector3 m_localScaling; MT_Point3 m_worldPosition; - MT_Matrix3x3 m_worldRotation; + MT_Matrix3x3 m_worldRotation; MT_Vector3 m_worldScaling; SG_ParentRelation * m_parent_relation; @@ -82,7 +82,8 @@ public: { m_ogldirty = false; } - /** + + /** * Define the relationship this node has with it's parent * node. You should pass an unshared instance of an SG_ParentRelation * allocated on the heap to this method. Ownership of this @@ -95,12 +96,7 @@ public: * The relation is activated only if no controllers of this object * updated the coordinates of the child. */ - - void - SetParentRelation( - SG_ParentRelation *relation - ); - + void SetParentRelation(SG_ParentRelation *relation); SG_ParentRelation * GetParentRelation() { return m_parent_relation; @@ -111,19 +107,10 @@ public: /** * Apply a translation relative to the current position. - * if local then the translation is assumed to be in the - * local coordinates of this object. If not then the translation - * is assumed to be in global coordinates. In this case - * you must provide a pointer to the parent of this object if it - * exists otherwise if there is no parent set it to NULL + * If local then the translation is assumed to be in the local coordinates of this object. + * If not then the translation is assumed to be in global coordinates. */ - - void - RelativeTranslate( - const MT_Vector3& trans, - const SG_Spatial *parent, - bool local - ); + void RelativeTranslate(const MT_Vector3& trans, bool local); void SetLocalPosition(const MT_Point3& trans) { @@ -136,12 +123,7 @@ public: m_worldPosition = trans; } - - void - RelativeRotate( - const MT_Matrix3x3& rot, - bool local - ); + void RelativeRotate(const MT_Matrix3x3& rot, bool local); void SetLocalOrientation(const MT_Matrix3x3& rot) { @@ -242,7 +224,7 @@ public: bool inside(const MT_Point3 &point) const; void getBBox(MT_Point3 *box) const; void getAABBox(MT_Point3 *box) const; - + MT_Scalar Radius() const { return m_radius; } void SetRadius(MT_Scalar radius) { m_radius = radius; } bool IsModified() { return m_modified; } @@ -260,16 +242,8 @@ protected: * designed for direct instantiation */ - SG_Spatial( - void* clientobj, - void* clientinfo, - SG_Callbacks& callbacks - ); - - SG_Spatial( - const SG_Spatial& other - ); - + SG_Spatial(void* clientobj, void* clientinfo, SG_Callbacks& callbacks); + SG_Spatial(const SG_Spatial& other); virtual ~SG_Spatial(); @@ -278,12 +252,7 @@ protected: * any controllers to update this object. */ - bool - UpdateSpatialData( - const SG_Spatial *parent, - double time, - bool& parentUpdated - ); + bool UpdateSpatialData(const SG_Spatial *parent, double time, bool& parentUpdated); #ifdef WITH_CXX_GUARDEDALLOC diff --git a/source/gameengine/SceneGraph/SG_Tree.h b/source/gameengine/SceneGraph/SG_Tree.h index 339862c652f..7485888df3c 100644 --- a/source/gameengine/SceneGraph/SG_Tree.h +++ b/source/gameengine/SceneGraph/SG_Tree.h @@ -28,14 +28,14 @@ /** \file SG_Tree.h * \ingroup bgesg */ - + #ifndef __SG_TREE_H__ #define __SG_TREE_H__ - + #include "MT_Point3.h" #include "SG_BBox.h" -#include <set> +#include <set> class SG_Node; @@ -56,27 +56,27 @@ class SG_Tree public: SG_Tree(); SG_Tree(SG_Tree* left, SG_Tree* right); - + SG_Tree(SG_Node* client); ~SG_Tree(); - + /** * Computes the volume of the bounding box. */ MT_Scalar volume() const; - + /** * Prints the tree (for debugging.) */ void dump() const; - + /** * Returns the left node. */ SG_Tree *Left() const; SG_Tree *Right() const; SG_Node *Client() const; - + SG_Tree* Find(SG_Node *node); /** * Gets the eight corners of this treenode's bounding box, @@ -101,9 +101,7 @@ public: MT_Point3 Center() const { return m_center; } MT_Scalar Radius() { return m_radius; } - - //friend class SG_TreeFactory; - + struct greater { bool operator()(const SG_Tree *a, const SG_Tree *b) @@ -111,9 +109,8 @@ public: return a->volume() > b->volume(); } }; - - - + + #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_Tree") #endif @@ -127,14 +124,14 @@ public: * cf building an optimized Huffman tree. * \warning O(n^3)!!! */ -class SG_TreeFactory +class SG_TreeFactory { typedef std::multiset<SG_Tree*, SG_Tree::greater> TreeSet; TreeSet m_objects; public: SG_TreeFactory(); ~SG_TreeFactory(); - + /** * Add a node to be added to the tree. */ @@ -146,18 +143,18 @@ public: * the Add method. */ SG_Tree* MakeTreeUp(); - + /** * Build the tree from the set of nodes top down. */ SG_Tree* MakeTreeDown(SG_BBox &bbox); - + SG_Tree* MakeTree(); - - + + #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_TreeFactory") #endif }; -#endif /* __SG_BBOX_H__ */ +#endif /* __SG_TREE_H__ */ diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index 74f36207774..5eb609c0823 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -41,6 +41,7 @@ #include "DNA_meshdata_types.h" #include "DNA_image_types.h" #include "IMB_imbuf_types.h" +#include "BKE_image.h" #include "MEM_guardedalloc.h" @@ -158,6 +159,7 @@ static PyObject *Texture_new(PyTypeObject *type, PyObject *args, PyObject *kwds) // initialize object structure self->m_actTex = 0; self->m_orgSaved = false; + self->m_imgBuf = NULL; self->m_imgTexture = NULL; self->m_matTexture = NULL; self->m_mipmap = false; @@ -282,7 +284,11 @@ PyObject *Texture_close(Texture * self) if (self->m_useMatTexture) self->m_matTexture->swapTexture(self->m_orgTex); else + { self->m_imgTexture->bindcode = self->m_orgTex; + BKE_image_release_ibuf(self->m_imgTexture, self->m_imgBuf, NULL); + self->m_imgBuf = NULL; + } // drop actual texture if (self->m_actTex != 0) { @@ -331,6 +337,12 @@ static PyObject *Texture_refresh(Texture *self, PyObject *args) self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex); else { + // Swapping will work only if the GPU has already loaded the image. + // If not, it will delete and overwrite our texture on next render. + // To avoid that, we acquire the image buffer now. + // WARNING: GPU has a ImageUser to pass, we don't. Using NULL + // works on image file, not necessarily on other type of image. + self->m_imgBuf = BKE_image_acquire_ibuf(self->m_imgTexture, NULL, NULL); self->m_orgTex = self->m_imgTexture->bindcode; self->m_imgTexture->bindcode = self->m_actTex; } diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h index c85b1228864..1befb620447 100644 --- a/source/gameengine/VideoTexture/Texture.h +++ b/source/gameengine/VideoTexture/Texture.h @@ -43,6 +43,8 @@ #include "Exception.h" +struct ImBuf; + // type Texture declaration struct Texture { @@ -58,6 +60,8 @@ struct Texture // original texture saved bool m_orgSaved; + // kernel image buffer, to make sure the image is loaded before we swap the bindcode + struct ImBuf *m_imgBuf; // texture image for game materials Image * m_imgTexture; // texture for blender materials diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index ab6dca0958f..b7539243671 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -157,10 +157,15 @@ static void registerAllTypes(void) pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24"); } +PyDoc_STRVAR(VideoTexture_module_documentation, + "\n" + "Module that allows to play video files on textures in GameBlender." +); + static struct PyModuleDef VideoTexture_module_def = { - {}, /* m_base */ + PyModuleDef_HEAD_INIT, "VideoTexture", /* m_name */ - "Module that allows to play video files on textures in GameBlender.", /* m_doc */ + VideoTexture_module_documentation, /* m_doc */ 0, /* m_size */ moduleMethods, /* m_methods */ 0, /* m_reload */ @@ -169,7 +174,7 @@ static struct PyModuleDef VideoTexture_module_def = { 0, /* m_free */ }; -PyObject *initVideoTexture(void) +PyMODINIT_FUNC initVideoTexturePythonBinding(void) { PyObject *m; |