Compare commits

...

83 Commits

Author SHA1 Message Date
cb61c5aeee Merge branch 'master' into soc-2014-bge 2015-01-13 12:04:25 +01:00
d7cabe7d6f BGE: python API cleanup - initialization for bge with submodules, closes D615 2015-01-13 12:01:50 +01:00
1c57e68d5c BGE: python API cleanup - adding proper initialization to GameTypes 2015-01-13 12:01:33 +01:00
7d3042f95f BGE: python API cleanup - replace BLI_program_path with BKE_appdir_program_path 2015-01-13 12:00:48 +01:00
7fbc7b83c9 Merge branch 'master' into soc-2014-bge
Conflicts:
	source/blender/blenkernel/intern/object.c
	source/gameengine/Ketsji/KX_KetsjiEngine.cpp
	source/gameengine/Ketsji/KX_PythonInit.cpp
2015-01-12 10:48:14 +01:00
335f6653b7 gameengine vehicle controller: removing partially removed constant 2015-01-12 10:34:47 +01:00
8f3c65c9df fixing previously bad merge 2014-11-03 16:08:11 +01:00
12fa08d83f Merge branch 'master' into soc-2014-bge
Conflicts:
	source/blender/blenkernel/intern/object.c
2014-11-03 13:18:39 +01:00
7361d5731e Adding the official bullet documentation by erwin coumans for v2.82 (current one) 2014-08-23 23:42:37 +02:00
0a7af14163 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-08-23 23:41:21 +02:00
65ffe0f541 Merge remote-tracking branch 'origin/master' into soc-2014-bge
Conflicts:
	source/gameengine/Ketsji/KX_PythonInit.cpp
2014-08-18 23:43:30 +02:00
47e5a16853 gameengine vehicle controller: cleanup formatting 2014-08-17 21:36:32 +02:00
7195e8a4bc gameengine physics: adding vehicle controller to the UI 2014-08-17 20:29:33 +02:00
423ee21640 gameengine physics: removing triangle mesh collision option for character controllers 2014-08-17 19:55:57 +02:00
c31d921b0d gameengine physics: removing compound option for character controllers 2014-08-17 19:55:21 +02:00
4054df5b21 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-08-06 18:41:23 +02:00
06a86b9076 attempting to fix slowparent rotation in the viewport 2014-08-06 18:41:07 +02:00
bbf6b0535e slow parent in game engine: fix for negative values 2014-08-06 17:02:14 +02:00
1a1fcba188 fixing slow parent motion in the game engine 2014-08-06 13:23:12 +02:00
5a511eb7cc gamengine: removing useless comment 2014-08-06 10:40:09 +02:00
1fd8030207 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-08-06 10:38:08 +02:00
16741f0763 scene conversion: style cleanup 2014-08-03 19:13:14 +02:00
b4e374cfad Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-08-02 14:56:02 +01:00
c8bfd092a4 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-30 12:17:23 +01:00
838e1d3e27 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-28 08:59:20 +01:00
6203831b89 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-27 09:23:36 +01:00
3f79ceb0ea Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-25 10:20:06 +01:00
52d2099700 gameengine: more tweaks to the scenegraph 2014-07-25 01:48:57 +01:00
b24560e4a8 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-24 19:23:09 +01:00
514c53ef81 game engine: scenegraph cleanup 2014-07-24 19:22:34 +01:00
8468a28467 gameengine: scenegraph corrections 2014-07-23 15:50:40 +01:00
86d8f10200 gameengine: removing addInitFromFrame hack 2014-07-23 13:07:01 +01:00
88f2b48a4d gameengine: dataconversion import and whitespace cleanup 2014-07-23 11:22:33 +01:00
c32a33f40c doxygen: updating blender version and link to tracker 2014-07-23 11:12:09 +01:00
0be0aa99e4 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-23 07:49:27 +01:00
8d53f17138 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-22 09:01:29 +01:00
8b5ec204e9 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-21 19:45:21 +01:00
de540d85a2 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-19 02:41:39 +01:00
51810ed3a3 gameengine scenegraph: whitespace and comment cleanup - KX_BoneParentRelation 2014-07-19 02:40:48 +01:00
1730ed876a Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-18 22:20:12 +01:00
5ba18bc764 gameengine scenegraph: whitespace and comment cleanup - KX_SlowParentRelation 2014-07-18 21:16:06 +01:00
bf51d62e0e gameengine scenegraph: small refactor to KX_NormalParentRelation , KX_VertexRelation was not marking changes for it's children 2014-07-18 20:27:33 +01:00
a26e8f6562 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-18 07:46:48 +01:00
18841038d9 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-15 10:02:33 +01:00
1ba0afc58e gameengine scenegraph: whitespace and comment cleanup - KX_VertexParentRelation 2014-07-14 13:41:07 +01:00
1890168b0d gameengine scenegraph: whitespace and comment cleanup 2014-07-14 13:35:25 +01:00
fa557d685f Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-14 11:58:48 +01:00
e3c6585502 Merge remote-tracking branch 'origin/master' into soc-2014-bge and resolving conflicts 2014-07-12 19:06:53 +01:00
2e5bd8d418 gameengine scenegraph: correction of relative postition computation, fixes T28908 2014-07-07 11:52:39 +01:00
db6abb619c gameengine scenegraph: whitespace and comment cleanup 2014-07-07 10:54:53 +01:00
041beb65ca Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-04 20:42:49 +01:00
0eb272df75 python bge.types module - Updating documentation to close T40778 2014-07-04 20:41:32 +01:00
d5b88e62ca Fixing own mistake 2014-07-04 11:48:38 +01:00
43ae0f0dda Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-03 23:30:36 +01:00
610e2fdabd Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-03 10:07:01 +01:00
2a997e7933 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-02 10:11:20 +01:00
4dd575305c Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-07-01 10:00:51 +01:00
ed9bd6b95d gameengine: KX_Scene comment cleanup 2014-07-01 10:00:20 +01:00
1ff3ca3c63 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-06-27 23:41:38 +01:00
58373b8c2e Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-06-27 12:42:27 +01:00
ebae705c2e Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-06-26 17:51:35 +01:00
cdcd252146 Correcting own mistake 2014-06-24 16:09:34 +01:00
5640131c20 Merging patch D610 - Fixes T30630 2014-06-24 15:54:33 +01:00
aeae4c2d9d No changes, commiting because there was a problem with the way I uploaded the revision
Summary:

Reviewers:

CC:
2014-06-24 15:45:02 +01:00
2420704ef2 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-06-24 15:35:09 +01:00
3d35124a08 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-06-24 09:17:21 +01:00
00d0d9677d Game Engine Scene Graph - documentation cleanup 2014-06-20 23:45:43 +01:00
f80b139a7d Game Engine UI cleanup: Adding missing 'not available' labels in empty panels 2014-06-20 22:15:27 +01:00
a7a58d9675 Game Engine UI cleanup: removing Scene/Active Clip 2014-06-20 11:54:10 +01:00
d1ca785cf5 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-06-20 08:45:11 +01:00
4929cb8126 Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-06-19 18:42:59 +01:00
82313b4fc4 Fix T33762 - texture fonts were not using the material color (gameengine) 2014-06-18 16:55:11 +01:00
331f9fdfac Merge remote-tracking branch 'origin/master' into soc-2014-bge 2014-06-18 15:06:58 +01:00
f12c182a46 Game Engine Scene Graph - whitespace cleanup 2014-06-16 23:24:03 +01:00
1ada96fbf0 makeScreenshot - adding frame number to the filename 2014-06-14 08:30:09 +01:00
9c95ea33f1 BGE cleanup: removing unused async logic bricks
This code was never run and is an outdated copy from the code above.
If someday this is needed again, it is better to start clean.
2014-06-12 11:54:23 +01:00
02f9b2c4eb Merge branch 'master' into soc-2014-bge 2014-06-11 08:36:07 +01:00
140a3aca7c BGE: python API cleanup - bge submodules definitions 2014-06-06 08:33:15 +01:00
d503f8a621 BGE: python API cleanup - using PyDoc_STRVAR instead of static char* 2014-06-06 07:43:23 +01:00
8060887089 Documentation update: references to OpenGL tutorials in the python bgl module 2014-06-04 21:13:05 +01:00
14fceb64cc BGE: python API initialization cleanup
-Removing unused parameters
-Updating some parts to match bpy_interface.c initialization
2014-06-04 09:27:20 +01:00
b8fbe686bf commiting patch to fix T30173 2014-05-29 08:58:00 +01:00
05db026d8a commiting patch to fix T30173 2014-05-26 10:38:12 +01:00
53 changed files with 1067 additions and 1639 deletions

View File

@@ -34,7 +34,7 @@ PROJECT_NAME = Blender
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or
# if some version control system is used. # 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 # 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 # for a project that appears at the top of each page and should give viewer

View File

@@ -7,7 +7,7 @@
* These pages document the source code of blender. * These pages document the source code of blender.
* *
* \subsection implinks Important Links * \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. * - <a href="http://wiki.blender.org/index.php/Dev:Contents">Development documents</a> on our wiki.
* *
* \subsection blother Other * \subsection blother Other

View File

@@ -124,13 +124,13 @@ base class --- :class:`SCA_IObject`
.. attribute:: groupMembers .. 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 :type: :class:`CListValue` of :class:`KX_GameObject` or None
.. attribute:: groupObject .. 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 :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. :arg name: name of the property that added to the debug list.
:type name: string :type name: string
:arg debug: the debug state. :arg debug: the debug state.
:type debug: boolean :type debug: boolean

View File

@@ -8,19 +8,17 @@ This module wraps OpenGL constants and functions, making them available from
within Blender Python. within Blender Python.
The complete list can be retrieved from the module itself, by listing its 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 than enough material to teach OpenGL programming, from books to many
collections of tutorials. collections of tutorials.
The "red book": "I{OpenGL Programming Guide: The Official Guide to Learning 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.
OpenGL}" and the online NeHe tutorials are two of the best resources.
.. note:: .. note::
You can use the :class:`Image` type to load and set textures. You can use the :class:`Image` type to load and set textures.
See :class:`Image.gl_load` and :class:`Image.gl_load`, See :class:`Image.gl_load` and :class:`Image.gl_load`,
for example. for example.
`OpenGL.org <http://www.opengl.org>`_
`NeHe GameDev <http://nehe.gamedev.net>`_
.. function:: glAccum(op, value): .. function:: glAccum(op, value):

BIN
extern/bullet2/Bullet_User_Manual.pdf vendored Normal file

Binary file not shown.

View File

@@ -56,7 +56,7 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
layout.prop(game, "jump_speed") layout.prop(game, "jump_speed")
layout.prop(game, "fall_speed") layout.prop(game, "fall_speed")
elif physics_type in {'DYNAMIC', 'RIGID_BODY'}: elif physics_type in {'DYNAMIC', 'RIGID_BODY', 'VEHICLE'}:
split = layout.split() split = layout.split()
col = split.column() col = split.column()
@@ -209,7 +209,7 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
def poll(cls, context): def poll(cls, context):
game = context.object.game game = context.object.game
rd = context.scene.render 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): def draw_header(self, context):
game = context.active_object.game game = context.active_object.game
@@ -226,8 +226,9 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
row = layout.row() row = layout.row()
row.prop(game, "collision_margin", text="Margin", slider=True) 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): class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
bl_label = "Create Obstacle" bl_label = "Create Obstacle"

View File

@@ -56,6 +56,10 @@ class RENDERLAYER_PT_layers(RenderLayerButtonsPanel, Panel):
scene = context.scene scene = context.scene
rd = scene.render rd = scene.render
if rd.engine == 'BLENDER_GAME':
layout.label("Not available in the Game Engine")
return
row = layout.row() row = layout.row()
col = row.column() col = row.column()
col.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2) col.template_list("RENDERLAYER_UL_renderlayers", "", rd, "layers", rd.layers, "active_index", rows=2)

View File

@@ -62,7 +62,8 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel):
layout.prop(scene, "camera") layout.prop(scene, "camera")
layout.prop(scene, "background_set", text="Background") 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): class SCENE_PT_unit(SceneButtonsPanel, Panel):

View File

@@ -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]) static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4])
{ {
float *fp1, *fp2; float fac1 = (1.0f / (1.0f + fabsf(ob->sf)) );
float fac1, fac2;
int a;
/* include framerate */ if (fac1 >= 1.0f)
fac1 = (1.0f / (1.0f + fabsf(ob->sf))); return false;
if (fac1 >= 1.0f) return false;
fac2 = 1.0f - fac1;
fp1 = obmat[0]; blend_m4_m4m4(obmat, slowmat, obmat, fac1);
fp2 = slowmat[0];
for (a = 0; a < 16; a++, fp1++, fp2++) {
fp1[0] = fac1 * fp1[0] + fac2 * fp2[0];
}
return true; return true;
} }

View File

@@ -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 */ /* Ignore collisions by default for non-mesh objects */
if (type != OB_MESH) { if (type != OB_MESH) {
ob->body_type = OB_BODY_TYPE_NO_COLLISION; 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); DAG_id_type_tag(bmain, ID_OB);

View File

@@ -560,6 +560,8 @@ enum {
OB_CHARACTER = 1 << 22, OB_CHARACTER = 1 << 22,
OB_RECORD_ANIMATION = 1 << 23, OB_RECORD_ANIMATION = 1 << 23,
OB_VEHICLE = 1 << 24,
}; };
/* ob->gameflag2 */ /* ob->gameflag2 */
@@ -586,6 +588,7 @@ enum {
OB_BODY_TYPE_SENSOR = 6, OB_BODY_TYPE_SENSOR = 6,
OB_BODY_TYPE_NAVMESH = 7, OB_BODY_TYPE_NAVMESH = 7,
OB_BODY_TYPE_CHARACTER = 8, OB_BODY_TYPE_CHARACTER = 8,
OB_BODY_TYPE_VEHICLE = 9,
}; };
/* ob->depsflag */ /* ob->depsflag */

View File

@@ -508,7 +508,9 @@ static EnumPropertyItem *rna_Object_collision_bounds_itemf(bContext *UNUSED(C),
EnumPropertyItem *item = NULL; EnumPropertyItem *item = NULL;
int totitem = 0; 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); RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_CONVEX_HULL);
if (ob->body_type != OB_BODY_TYPE_SOFT) { 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) { else if (ob->gameflag & OB_CHARACTER) {
ob->body_type = OB_BODY_TYPE_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) { else if (ob->gameflag & OB_SENSOR) {
ob->body_type = OB_BODY_TYPE_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) { switch (ob->body_type) {
case OB_BODY_TYPE_SENSOR: case OB_BODY_TYPE_SENSOR:
ob->gameflag |= OB_SENSOR | OB_COLLISION; 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); OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
break; break;
case OB_BODY_TYPE_OCCLUDER: case OB_BODY_TYPE_OCCLUDER:
ob->gameflag |= OB_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; break;
case OB_BODY_TYPE_NAVMESH: case OB_BODY_TYPE_NAVMESH:
ob->gameflag |= OB_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) { if (ob->type == OB_MESH) {
/* could be moved into mesh UI but for now ensure mesh data layer */ /* 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; break;
case OB_BODY_TYPE_NO_COLLISION: 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; break;
case OB_BODY_TYPE_CHARACTER: case OB_BODY_TYPE_CHARACTER:
ob->gameflag |= OB_COLLISION | OB_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); OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
break; break;
case OB_BODY_TYPE_STATIC: case OB_BODY_TYPE_STATIC:
ob->gameflag |= OB_COLLISION; 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; break;
case OB_BODY_TYPE_DYNAMIC: case OB_BODY_TYPE_DYNAMIC:
ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_ACTOR; 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; break;
case OB_BODY_TYPE_RIGID: case OB_BODY_TYPE_RIGID:
ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_RIGID_BODY | OB_ACTOR; 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; break;
default: default:
case OB_BODY_TYPE_SOFT: case OB_BODY_TYPE_SOFT:
ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_SOFT_BODY | OB_ACTOR; 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 */ /* assume triangle mesh, if no bounds chosen for soft body */
if ((ob->gameflag & OB_BOUNDS) && (ob->boundtype < OB_BOUND_TRIANGLE_MESH)) { 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_NAVMESH, "NAVMESH", 0, "Navigation Mesh", "Navigation mesh"},
{OB_BODY_TYPE_CHARACTER, "CHARACTER", 0, "Character", {OB_BODY_TYPE_CHARACTER, "CHARACTER", 0, "Character",
"Simple kinematic physics appropriate for game characters"}, "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} {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_float_sdna(prop, NULL, "max_vel");
RNA_def_property_range(prop, 0.0, 1000.0); RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed"); RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed");
/* Vehicle physics */
/* Character physics */ /* Character physics */
prop = RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE); prop = RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "step_height"); 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_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall"); RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall");
/* Collision Masks */ /* Collision Masks */
prop = RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER); prop = RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1); RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1);

View File

@@ -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 // create a scene converter, create and convert the startingscene
KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine); KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
ketsjiengine->SetSceneConverter(sceneconverter); ketsjiengine->SetSceneConverter(sceneconverter);
sceneconverter->addInitFromFrame=false;
if (always_use_expand_framing) if (always_use_expand_framing)
sceneconverter->SetAlwaysUseExpandFraming(true); sceneconverter->SetAlwaysUseExpandFraming(true);

View File

@@ -67,6 +67,7 @@ m_frame_rect(rect)
// area boundaries needed for mouse coordinates in Letterbox framing mode // area boundaries needed for mouse coordinates in Letterbox framing mode
m_area_left = ar->winrct.xmin; m_area_left = ar->winrct.xmin;
m_area_top = ar->winrct.ymax; m_area_top = ar->winrct.ymax;
m_frame = 1;
glGetIntegerv(GL_VIEWPORT, (GLint *)m_viewport); glGetIntegerv(GL_VIEWPORT, (GLint *)m_viewport);
} }
@@ -350,6 +351,8 @@ void KX_BlenderCanvas::MakeScreenShot(const char *filename)
char path[FILE_MAX]; char path[FILE_MAX];
BLI_strncpy(path, filename, sizeof(path)); BLI_strncpy(path, filename, sizeof(path));
BLI_path_abs(path, G.main->name); 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); BKE_add_image_extension_from_type(path, im_format.imtype);
/* create and save imbuf */ /* create and save imbuf */

View File

@@ -210,6 +210,7 @@ private:
RAS_Rect m_area_rect; RAS_Rect m_area_rect;
int m_area_left; int m_area_left;
int m_area_top; int m_area_top;
int m_frame;
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC

View File

@@ -52,23 +52,13 @@
#include <algorithm> #include <algorithm>
#include "BL_BlenderDataConversion.h" #include "BL_BlenderDataConversion.h"
#include "KX_BlenderScalarInterpolator.h"
#include "RAS_IPolygonMaterial.h" #include "MT_Matrix3x3.h"
#include "MT_MinMax.h"
// Expressions
#include "ListValue.h"
#include "IntValue.h"
// Collision & Fuzzics LTD
#include "PHY_Pro.h" #include "PHY_Pro.h"
#include "PHY_IPhysicsEnvironment.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_MeshObject.h"
#include "RAS_IRasterizer.h" #include "RAS_IRasterizer.h"
#include "RAS_ILightObject.h" #include "RAS_ILightObject.h"
@@ -76,31 +66,27 @@
#include "KX_ConvertActuators.h" #include "KX_ConvertActuators.h"
#include "KX_ConvertControllers.h" #include "KX_ConvertControllers.h"
#include "KX_ConvertSensors.h" #include "KX_ConvertSensors.h"
#include "SCA_LogicManager.h" #include "SCA_LogicManager.h"
#include "SCA_EventManager.h"
#include "SCA_TimeEventManager.h" #include "SCA_TimeEventManager.h"
#include "KX_ClientObjectInfo.h"
#include "KX_Scene.h"
#include "KX_GameObject.h"
#include "KX_Light.h" #include "KX_Light.h"
#include "KX_Camera.h" #include "KX_Camera.h"
#include "KX_ClientObjectInfo.h"
#include "KX_EmptyObject.h" #include "KX_EmptyObject.h"
#include "KX_FontObject.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_TexMatrix.h"
#include "RAS_ICanvas.h" #include "RAS_ICanvas.h"
#include "RAS_MaterialBucket.h"
//#include "KX_BlenderPolyMaterial.h"
#include "RAS_Polygon.h" #include "RAS_Polygon.h"
#include "RAS_TexVert.h" #include "RAS_TexVert.h"
#include "RAS_BucketManager.h" #include "RAS_BucketManager.h"
#include "RAS_IPolygonMaterial.h"
#include "BL_Material.h" #include "BL_Material.h"
#include "KX_BlenderMaterial.h" #include "KX_BlenderMaterial.h"
#include "BL_Texture.h" #include "BL_Texture.h"
#include "DNA_action_types.h"
#include "BKE_main.h" #include "BKE_main.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_object.h" #include "BKE_object.h"
@@ -109,9 +95,10 @@
#include "BL_SkinDeformer.h" #include "BL_SkinDeformer.h"
#include "BL_MeshDeformer.h" #include "BL_MeshDeformer.h"
#include "KX_SoftBodyDeformer.h" #include "KX_SoftBodyDeformer.h"
//#include "BL_ArmatureController.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BlenderWorldInfo.h" #include "BlenderWorldInfo.h"
#include "KX_KetsjiEngine.h" #include "KX_KetsjiEngine.h"
@@ -143,13 +130,14 @@
#include "DNA_sound_types.h" #include "DNA_sound_types.h"
#include "DNA_key_types.h" #include "DNA_key_types.h"
#include "DNA_armature_types.h" #include "DNA_armature_types.h"
#include "DNA_action_types.h"
#include "DNA_object_force.h" #include "DNA_object_force.h"
#include "DNA_constraint_types.h"
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BKE_key.h" #include "BKE_key.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "MT_Point3.h"
#include "BLI_math.h" #include "BLI_math.h"
@@ -170,48 +158,28 @@ extern Material defmaterial; /* material.c */
#include "KX_BlenderInputDevice.h" #include "KX_BlenderInputDevice.h"
#include "KX_ConvertProperties.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_Node.h"
#include "SG_BBox.h" #include "SG_BBox.h"
#include "SG_Tree.h" #include "KX_SG_NodeRelationships.h"
#include "KX_SG_BoneParentNodeRelationship.h"
#ifdef WITH_BULLET #ifdef WITH_BULLET
#include "CcdPhysicsEnvironment.h" #include "CcdPhysicsEnvironment.h"
#include "CcdGraphicController.h" #include "CcdGraphicController.h"
#endif #endif
#include "KX_MotionState.h" #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 "BL_ArmatureObject.h" #include "BL_ArmatureObject.h"
#include "BL_DeformableGameObject.h" #include "BL_DeformableGameObject.h"
#include "KX_NavMeshObject.h" #include "KX_NavMeshObject.h"
#include "KX_ObstacleSimulation.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" #include "BLI_threads.h"
static bool default_light_mode = 0; static bool default_light_mode = 0;
static std::map<int, SCA_IInputDevice::KX_EnumInputs> create_translate_table() 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(); 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) static unsigned int KX_rgbaint2uint_new(unsigned int icol)
{ {
union union
@@ -889,10 +862,10 @@ static bool ConvertMaterial(
// swap the material color, so MCol on bitmap font works // swap the material color, so MCol on bitmap font works
if (validmat && (use_vcol == false) && (mat->game.flag & GEMAT_TEXT)) if (validmat && (use_vcol == false) && (mat->game.flag & GEMAT_TEXT))
{ {
rgb[0] = KX_rgbaint2uint_new(rgb[0]); material->rgb[0] = KX_rgbaint2uint_new(rgb[0]);
rgb[1] = KX_rgbaint2uint_new(rgb[1]); material->rgb[1] = KX_rgbaint2uint_new(rgb[1]);
rgb[2] = KX_rgbaint2uint_new(rgb[2]); material->rgb[2] = KX_rgbaint2uint_new(rgb[2]);
rgb[3] = KX_rgbaint2uint_new(rgb[3]); material->rgb[3] = KX_rgbaint2uint_new(rgb[3]);
} }
if (validmat) if (validmat)
@@ -1389,16 +1362,14 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
} }
bool isCompoundChild = false; 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 /* 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 && (parent->gameflag & (OB_DYNAMIC | OB_COLLISION))) {
if( (parent->gameflag & OB_CHILD)!=0 && (blenderobject->gameflag & OB_CHILD) && !(parent->gameflag & OB_SOFT_BODY)) {
if ((parent->gameflag & OB_CHILD) != 0 && (blenderobject->gameflag & OB_CHILD))
{
isCompoundChild = true; isCompoundChild = true;
} }
} }
if (processCompoundChildren != isCompoundChild) if (processCompoundChildren != isCompoundChild)
return; return;
@@ -1711,9 +1682,6 @@ struct parentChildLink {
SG_Node* m_gamechildnode; SG_Node* m_gamechildnode;
}; };
#include "DNA_constraint_types.h"
//XXX #include "BIF_editconstraint.h"
static bPoseChannel *get_active_posechannel2(Object *ob) static bPoseChannel *get_active_posechannel2(Object *ob)
{ {
bArmature *arm= (bArmature*)ob->data; bArmature *arm= (bArmature*)ob->data;
@@ -1747,20 +1715,15 @@ static ListBase *get_active_constraints2(Object *ob)
return NULL; 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;
bConstraint *curcon; ListBase* conlist = get_active_constraints2(ob);
conlist = get_active_constraints2(ob);
if (conlist) { if (conlist) {
for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) { for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) {
printf("%i\n",curcon->type); 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 */ * note: all var names match args are passed from the caller */
static void bl_ConvertBlenderObject_Single( static void bl_ConvertBlenderObject_Single(
KX_BlenderSceneConverter *converter, KX_BlenderSceneConverter *converter,
Scene *blenderscene, Object *blenderobject, Object *blenderobject,
vector<MT_Vector3> &inivel, vector<MT_Vector3> &iniang,
vector<parentChildLink> &vec_parent_child, vector<parentChildLink> &vec_parent_child,
CListValue* logicbrick_conversionlist, CListValue* logicbrick_conversionlist,
CListValue* objectlist, CListValue* inactivelist, CListValue* sumolist, CListValue* objectlist, CListValue* inactivelist, CListValue* sumolist,
KX_Scene* kxscene, KX_GameObject* gameobj, KX_Scene* kxscene, KX_GameObject* gameobj,
SCA_LogicManager* logicmgr, SCA_TimeEventManager* timemgr, SCA_LogicManager* logicmgr, SCA_TimeEventManager* timemgr,
bool isInActiveLayer bool isInActiveLayer
) )
{ {
MT_Point3 posPrev; sumolist->Add(gameobj->AddRef());
MT_Matrix3x3 angor;
if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra;
BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
gameobj->SetName(blenderobject->id.name + 2);
/* Setting local coordinates according to current local+delta */
MT_Point3 pos( MT_Point3 pos(
blenderobject->loc[0]+blenderobject->dloc[0], blenderobject->loc[0]+blenderobject->dloc[0],
blenderobject->loc[1]+blenderobject->dloc[1], blenderobject->loc[1]+blenderobject->dloc[1],
@@ -1804,97 +1769,61 @@ static void bl_ConvertBlenderObject_Single(
MT_Matrix3x3 rotation; MT_Matrix3x3 rotation;
float rotmat[3][3]; float rotmat[3][3];
BKE_object_rot_to_mat3(blenderobject, rotmat, false); BKE_object_rot_to_mat3(blenderobject, rotmat, true);
rotation.setValue3x3((float*)rotmat); rotation.setValue3x3((float*)rotmat);
MT_Vector3 scale(blenderobject->size); MT_Vector3 scale(
blenderobject->size[0]*blenderobject->dscale[0],
if (converter->addInitFromFrame) {//rcruiz blenderobject->size[1]*blenderobject->dscale[1],
blenderscene->r.cfra=blenderscene->r.sfra-1; blenderobject->size[2]*blenderobject->dscale[2]
//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();
}
gameobj->NodeSetLocalPosition(pos); gameobj->NodeSetLocalPosition(pos);
gameobj->NodeSetLocalOrientation(rotation); gameobj->NodeSetLocalOrientation(rotation);
gameobj->NodeSetLocalScale(scale); gameobj->NodeSetLocalScale(scale);
gameobj->NodeUpdateGS(0);
sumolist->Add(gameobj->AddRef()); /* if the node has a parent, add a parent/child link */
if (blenderobject->parent != 0)
BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
gameobj->SetName(blenderobject->id.name + 2);
// update children/parent hierarchy
if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
{ {
// blender has an additional 'parentinverse' offset in each object SG_Callbacks callbacks(
SG_Callbacks callback(NULL,NULL,NULL,KX_Scene::KX_ScenegraphUpdateFunc,KX_Scene::KX_ScenegraphRescheduleFunc); NULL, /* replicationfunc, */
SG_Node* parentinversenode = new SG_Node(NULL,kxscene,callback); NULL, /* destructionfunc,*/
NULL, /* updatefunc, */
KX_Scene::KX_ScenegraphUpdateFunc, /* schedulefunc, */
KX_Scene::KX_ScenegraphRescheduleFunc); /* reschedulefunc */
// define a normal parent relationship for this node. /*
KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New(); * when an object gets parented, an inverse parenting matrix is kept,
parentinversenode->SetParentRelation(parent_relation); * 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; parentChildLink pclink;
pclink.m_blenderchild = blenderobject; pclink.m_blenderchild = blenderobject;
pclink.m_gamechildnode = parentinversenode; pclink.m_gamechildnode = parentinversenode;
vec_parent_child.push_back(pclink); vec_parent_child.push_back(pclink);
float* fl = (float*) blenderobject->parentinv; /* extract location, orientation and scale out of the inverse parent matrix */
MT_Transform parinvtrans(fl); float invp_loc[3], invp_rot[3][3], invp_size[3];
parentinversenode->SetLocalPosition(parinvtrans.getOrigin()); mat4_to_loc_rot_size(invp_loc, invp_rot, invp_size, blenderobject->parentinv);
// 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 invp_rot_mt;
MT_Matrix3x3 ori(parinvtrans.getBasis()); invp_rot_mt.setValue3x3((float *) invp_rot);
MT_Vector3 x(ori.getColumn(0)); parentinversenode->SetLocalPosition(MT_Point3(invp_loc));
MT_Vector3 y(ori.getColumn(1)); parentinversenode->SetLocalOrientation(invp_rot_mt);
MT_Vector3 z(ori.getColumn(2)); parentinversenode->SetLocalScale(MT_Vector3(invp_size));
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);
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 // needed for python scripting
logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj); logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
@@ -1909,18 +1838,11 @@ static void bl_ConvertBlenderObject_Single(
logicbrick_conversionlist->Add(gameobj->AddRef()); logicbrick_conversionlist->Add(gameobj->AddRef());
if (converter->addInitFromFrame) {
posPrev=gameobj->NodeGetWorldPosition();
angor=gameobj->NodeGetWorldOrientation();
}
if (isInActiveLayer) if (isInActiveLayer)
{ {
objectlist->Add(gameobj->AddRef()); objectlist->Add(gameobj->AddRef());
//tf.Add(gameobj->GetSGNode());
gameobj->NodeUpdateGS(0);
gameobj->AddMeshUser(); gameobj->AddMeshUser();
} }
else else
{ {
@@ -1928,11 +1850,6 @@ static void bl_ConvertBlenderObject_Single(
//at the end of this function if it is not a root object //at the end of this function if it is not a root object
inactivelist->Add(gameobj->AddRef()); 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 \ #define BL_CONVERTBLENDEROBJECT_SINGLE \
bl_ConvertBlenderObject_Single(converter, \ bl_ConvertBlenderObject_Single(converter, \
blenderscene, blenderobject, \ blenderobject, \
inivel, iniang, \
vec_parent_child, \ vec_parent_child, \
logicbrick_conversionlist, \ logicbrick_conversionlist, \
objectlist, inactivelist, sumolist, \ objectlist, inactivelist, sumolist, \
@@ -1974,7 +1890,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
RAS_FrameSettings::RAS_FrameType frame_type; RAS_FrameSettings::RAS_FrameType frame_type;
int aspect_width; int aspect_width;
int aspect_height; int aspect_height;
vector<MT_Vector3> inivel,iniang;
set<Group*> grouplist; // list of groups to be converted set<Group*> grouplist; // list of groups to be converted
set<Object*> allblobj; // all objects converted set<Object*> allblobj; // all objects converted
set<Object*> groupobj; // objects from groups (never in active layer) 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 // no occlusion culling by default
kxscene->SetDbvtOcclusionRes(0); kxscene->SetDbvtOcclusionRes(0);
/* Objects' Conversion */
int activeLayerBitInfo = blenderscene->lay; int activeLayerBitInfo = blenderscene->lay;
// list of all object converted, active and inactive // list of all object converted, active and inactive
CListValue* sumolist = new CListValue(); CListValue* sumolist = new CListValue();
vector<parentChildLink> vec_parent_child; vector<parentChildLink> vec_parent_child;
CListValue* objectlist = kxscene->GetObjectList(); CListValue* objectlist = kxscene->GetObjectList();
CListValue* inactivelist = kxscene->GetInactiveList(); CListValue* inactivelist = kxscene->GetInactiveList();
CListValue* parentlist = kxscene->GetRootParentList(); CListValue* parentlist = kxscene->GetRootParentList();
SCA_LogicManager* logicmgr = kxscene->GetLogicManager(); SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager(); SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
CListValue* logicbrick_conversionlist = new CListValue(); CListValue* logicbrick_conversionlist = new CListValue();
//SG_TreeFactory tf;
// Convert actions to actionmap // Convert actions to actionmap
bAction *curAct; bAction *curAct;
for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next) for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
@@ -2046,6 +1962,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
} }
SetDefaultLightMode(blenderscene); SetDefaultLightMode(blenderscene);
// Let's support scene set. // Let's support scene set.
// Beware of name conflict in linked data, it will not crash but will create confusion // 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 // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have
@@ -2061,23 +1978,15 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
rendertools, rendertools,
converter, converter,
libloading); 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 (gameobj)
{ {
if (addobj) /* macro calls object conversion funcs */
{ /* macro calls object conversion funcs */ BL_CONVERTBLENDEROBJECT_SINGLE;
BL_CONVERTBLENDEROBJECT_SINGLE;
if (gameobj->IsDupliGroup()) { if (gameobj->IsDupliGroup()) {
grouplist.insert(blenderobject->dup_group); grouplist.insert(blenderobject->dup_group);
}
} }
/* Note about memory leak issues: /* Note about memory leak issues:
@@ -2121,22 +2030,12 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
rendertools, rendertools,
converter, converter,
libloading); 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 (gameobj)
{ {
if (addobj) /* macro calls object conversion funcs */
{ /* macro calls object conversion funcs */ BL_CONVERTBLENDEROBJECT_SINGLE;
BL_CONVERTBLENDEROBJECT_SINGLE;
}
if (gameobj->IsDupliGroup()) if (gameobj->IsDupliGroup())
{ {
@@ -2146,7 +2045,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
} }
} }
/* see comment above re: mem leaks */ /* see comment above re: mem leaks */
gameobj->Release(); gameobj->Release();
} }
@@ -2183,14 +2081,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
} }
} }
} }
// create hierarchy information
int i; int i;
/* Build the scene graph relations */
vector<parentChildLink>::iterator pcit; vector<parentChildLink>::iterator pcit;
for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit) for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
{ {
struct Object* blenderchild = pcit->m_blenderchild; struct Object* blenderchild = pcit->m_blenderchild;
struct Object* blenderparent = blenderchild->parent; struct Object* blenderparent = blenderchild->parent;
KX_GameObject* parentobj = converter->FindGameObject(blenderparent); KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
@@ -2228,33 +2126,28 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
continue; continue;
} }
/* override the parent relation type if not normal.
* If the type is not supported, the NormalParentRelation is kept. */
switch (blenderchild->partype) switch (blenderchild->partype)
{ {
case PARVERT1: case PARVERT1:
{ {
// creat a new vertex parent relationship for this node. pcit->m_gamechildnode->SetParentRelation(KX_VertexParentRelation::New());
KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
break; break;
} }
case PARSLOW: case PARSLOW:
{ {
// creat a new slow parent relationship for this node. pcit->m_gamechildnode->SetParentRelation(KX_SlowParentRelation::New(blenderchild->sf));
KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
break; break;
} }
case PARBONE: case PARBONE:
{ {
// parent this to a bone
Bone *parent_bone = BKE_armature_find_bone_name(BKE_armature_from_object(blenderchild->parent), Bone *parent_bone = BKE_armature_find_bone_name(BKE_armature_from_object(blenderchild->parent),
blenderchild->parsubstr); blenderchild->parsubstr);
if (parent_bone) { if (parent_bone) {
KX_BoneParentRelation *bone_parent_relation = KX_BoneParentRelation::New(parent_bone); pcit->m_gamechildnode->SetParentRelation(KX_BoneParentRelation::New(parent_bone));
pcit->m_gamechildnode->SetParentRelation(bone_parent_relation);
} }
break; break;
} }
case PARSKEL: // skinned - ignore case PARSKEL: // skinned - ignore
@@ -2267,19 +2160,19 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// unhandled // unhandled
break; break;
} }
parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode); parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode);
} }
vec_parent_child.clear(); 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) for (i=0;i<sumolist->GetCount();++i)
{ {
KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
if (gameobj->GetSGNode()->GetSGParent() == 0) if (gameobj->GetSGNode()->GetSGParent() == 0)
{ {
parentlist->Add(gameobj->AddRef()); 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++) for (i=0; i<sumolist->GetCount();i++)
{ {
KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
if (gameobj->GetMeshCount() > 0) if (gameobj->GetMeshCount() > 0)
{ {
MT_Point3 box[2]; MT_Point3 box[2];
gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity()); gameobj->GetSGNode()->BBox().getmm(box, MT_Transform::Identity());
@@ -2304,6 +2197,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (occlusion) if (occlusion)
kxscene->SetDbvtOcclusionRes(blenderscene->gm.occlusionRes); kxscene->SetDbvtOcclusionRes(blenderscene->gm.occlusionRes);
} }
if (blenderscene->world) if (blenderscene->world)
kxscene->GetPhysicsEnvironment()->SetNumTimeSubSteps(blenderscene->gm.physubstep); kxscene->GetPhysicsEnvironment()->SetNumTimeSubSteps(blenderscene->gm.physubstep);
@@ -2338,7 +2233,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
} }
bool processCompoundChildren = false; bool processCompoundChildren = false;
// create physics information // create physics information
for (i=0;i<sumolist->GetCount();i++) 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; int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,converter,processCompoundChildren); 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++) for (i=0;i<sumolist->GetCount();i++)
{ {
KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i); KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
struct Object* blenderobject = gameobj->GetBlenderObject(); struct Object* blenderobject = gameobj->GetBlenderObject();
ListBase *conlist; ListBase *conlist;
bConstraint *curcon; bConstraint *curcon;
conlist = get_active_constraints2(blenderobject);
if ((gameobj->GetLayer()&activeLayerBitInfo)==0) if ((gameobj->GetLayer()&activeLayerBitInfo)==0)
continue; continue;
conlist = get_active_constraints2(blenderobject);
if (conlist) { if (conlist) {
for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) { for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) {
if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT) { if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT) {
@@ -2405,15 +2286,13 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
PHY_IPhysicsController* physctr2 = 0; PHY_IPhysicsController* physctr2 = 0;
if (dat->tar) if (dat->tar) {
{
KX_GameObject *gotar=getGameOb(dat->tar->id.name+2,sumolist); KX_GameObject *gotar=getGameOb(dat->tar->id.name+2,sumolist);
if (gotar && ((gotar->GetLayer()&activeLayerBitInfo)!=0) && gotar->GetPhysicsController()) if (gotar && ((gotar->GetLayer()&activeLayerBitInfo)!=0) && gotar->GetPhysicsController())
physctr2 = gotar->GetPhysicsController(); physctr2 = gotar->GetPhysicsController();
} }
if (gameobj->GetPhysicsController()) if (gameobj->GetPhysicsController()) {
{
PHY_IPhysicsController* physctrl = gameobj->GetPhysicsController(); PHY_IPhysicsController* physctrl = gameobj->GetPhysicsController();
//we need to pass a full constraint frame, not just axis //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 axis0 = localCFrame.getColumn(0);
MT_Vector3 axis1 = localCFrame.getColumn(1); MT_Vector3 axis1 = localCFrame.getColumn(1);
MT_Vector3 axis2 = localCFrame.getColumn(2); MT_Vector3 axis2 = localCFrame.getColumn(2);
int constraintId = kxscene->GetPhysicsEnvironment()->CreateConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX, int constraintId = kxscene->GetPhysicsEnvironment()->CreateConstraint(physctrl,physctr2,(PHY_ConstraintType)dat->type,(float)dat->pivX,
(float)dat->pivY,(float)dat->pivZ, (float)dat->pivY,(float)dat->pivZ,
(float)axis0.x(),(float)axis0.y(),(float)axis0.z(), (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
(float)axis1.x(),(float)axis1.y(),(float)axis1.z(), (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
(float)axis2.x(),(float)axis2.y(),(float)axis2.z(),dat->flag); (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 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 dof;
int dofbit=1; int dofbit=1;
for (dof=0;dof<6;dof++) for (dof=0;dof<6;dof++) {
{ if (dat->flag & dofbit) {
if (dat->flag & dofbit)
{
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]); kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
} else } else {
{
//minLimit > maxLimit means free(disabled limit) for this degree of freedom //minLimit > maxLimit means free(disabled limit) for this degree of freedom
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1); kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
} }
dofbit<<=1; dofbit<<=1;
} }
} } else if (dat->type == PHY_CONE_TWIST_CONSTRAINT) {
else if (dat->type == PHY_CONE_TWIST_CONSTRAINT)
{
int dof; int dof;
int dofbit = 1<<3; // bitflag use_angular_limit_x int dofbit = 1<<3; // bitflag use_angular_limit_x
for (dof=3;dof<6;dof++) for (dof=3;dof<6;dof++) {
{ if (dat->flag & dofbit) {
if (dat->flag & dofbit)
{
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]); kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
} } else {
else
{
//maxLimit < 0 means free(disabled limit) for this degree of freedom //maxLimit < 0 means free(disabled limit) for this degree of freedom
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1); kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
} }
dofbit<<=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 dof = 3; // dof for angular x
int dofbit = 1<<3; // bitflag use_angular_limit_x int dofbit = 1<<3; // bitflag use_angular_limit_x
if (dat->flag & dofbit) if (dat->flag & dofbit) {
{
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof, kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,
dat->minLimit[dof],dat->maxLimit[dof]); dat->minLimit[dof],dat->maxLimit[dof]);
} else } else {
{
//minLimit > maxLimit means free(disabled limit) for this degree of freedom //minLimit > maxLimit means free(disabled limit) for this degree of freedom
kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1); 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 // convert logic bricks, sensors, controllers and actuators
for (i=0;i<logicbrick_conversionlist->GetCount();i++) for (i=0;i<logicbrick_conversionlist->GetCount();i++)
{ {
@@ -2573,8 +2435,6 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->ResetState(); gameobj->ResetState();
} }
#endif //CONVERT_LOGIC
logicbrick_conversionlist->Release(); logicbrick_conversionlist->Release();
// Calculate the scene btree - // Calculate the scene btree -
@@ -2601,7 +2461,3 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
bucketmanager->OptimizeBuckets(distance); bucketmanager->OptimizeBuckets(distance);
} }
SCA_IInputDevice::KX_EnumInputs ConvertKeyCode(int key_code)
{
return gReverseKeyTranslateTable[key_code];
}

View File

@@ -529,76 +529,59 @@ void KX_BlenderSceneConverter::CacheBlenderMaterial(KX_Scene *scene, struct Mate
m_mat_cache[scene][mat] = blmat; m_mat_cache[scene][mat] = blmat;
} }
BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(KX_Scene *scene, struct Material *mat) BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(KX_Scene *scene, struct Material *mat)
{ {
return (m_use_mat_cache) ? m_mat_cache[scene][mat] : NULL; return (m_use_mat_cache) ? m_mat_cache[scene][mat] : NULL;
} }
void KX_BlenderSceneConverter::RegisterInterpolatorList(
BL_InterpolatorList *actList, void KX_BlenderSceneConverter::RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act)
struct bAction *for_act)
{ {
m_map_blender_to_gameAdtList.insert(CHashedPtr(for_act), actList); 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)]; BL_InterpolatorList **listp = m_map_blender_to_gameAdtList[CHashedPtr(for_act)];
return listp?*listp:NULL; 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); 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)]; SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
return actp?*actp:NULL; 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); 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)]; SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
return contp?*contp:NULL; return contp?*contp:NULL;
} }
void KX_BlenderSceneConverter::RegisterWorldInfo( void KX_BlenderSceneConverter::RegisterWorldInfo(KX_WorldInfo *worldinfo)
KX_WorldInfo *worldinfo)
{ {
m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo)); m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
} }
void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo) 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(); KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
int numScenes = scenes->size(); int numScenes = scenes->size();
@@ -614,7 +597,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{ {
KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g); KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
if (gameObj->IsRecordAnimation()) { if (gameObj->IsRecordAnimation()) {
Object* blenderObject = gameObj->GetBlenderObject(); Object* blenderObject = gameObj->GetBlenderObject();
if (blenderObject) if (blenderObject)
{ {
@@ -625,21 +608,21 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{ //clear the curve data { //clear the curve data
if (clearIpo) {//rcruiz if (clearIpo) {//rcruiz
IpoCurve *icu1; IpoCurve *icu1;
int numCurves = 0; int numCurves = 0;
for ( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) { for ( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) {
IpoCurve* tmpicu = icu1; IpoCurve* tmpicu = icu1;
/*int i; /*int i;
BezTriple *bezt; BezTriple *bezt;
for ( bezt = tmpicu->bezt, i = 0; i < tmpicu->totvert; i++, 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]); 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; icu1 = icu1->next;
numCurves++; numCurves++;
BLI_remlink( &( blenderObject->ipo->curve ), tmpicu ); BLI_remlink( &( blenderObject->ipo->curve ), tmpicu );
if ( tmpicu->bezt ) if ( tmpicu->bezt )
MEM_freeN( 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() void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo()
{ {
if (addInitFromFrame) { //TODO the functionality should be rewritten
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);
}
}
}
}
} }

View File

@@ -69,6 +69,7 @@ GPC_Canvas::GPC_Canvas(
m_displayarea.m_y1 = 0; m_displayarea.m_y1 = 0;
m_displayarea.m_x2 = width; m_displayarea.m_x2 = width;
m_displayarea.m_y2 = height; m_displayarea.m_y2 = height;
m_frame = 1;
glGetIntegerv(GL_VIEWPORT, (GLint*)m_viewport); glGetIntegerv(GL_VIEWPORT, (GLint*)m_viewport);
} }
@@ -180,6 +181,8 @@ MakeScreenShot(
char path[FILE_MAX]; char path[FILE_MAX];
BLI_strncpy(path, filename, sizeof(path)); BLI_strncpy(path, filename, sizeof(path));
BLI_path_abs(path, G.main->name); 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); BKE_add_image_extension_from_type(path, im_format.imtype);
// create and save imbuf // create and save imbuf

View File

@@ -56,6 +56,8 @@ protected:
/** Rect that defines the area used for rendering, /** Rect that defines the area used for rendering,
* relative to the context */ * relative to the context */
RAS_Rect m_displayarea; RAS_Rect m_displayarea;
/** Frame counter for screenshots */
int m_frame;
int m_viewport[4]; int m_viewport[4];

View File

@@ -47,10 +47,10 @@ BL_Material::BL_Material()
void BL_Material::Initialize() void BL_Material::Initialize()
{ {
rgb[0] = 0; rgb[0] = 0xFFFFFFFFL;
rgb[1] = 0; rgb[1] = 0xFFFFFFFFL;
rgb[2] = 0; rgb[2] = 0xFFFFFFFFL;
rgb[3] = 0; rgb[3] = 0xFFFFFFFFL;
IdMode = 0; IdMode = 0;
ras_mode = 0; ras_mode = 0;
glslmat = 0; glslmat = 0;

View File

@@ -124,14 +124,10 @@ KX_GameObject::KX_GameObject(
{ {
m_ignore_activity_culling = false; m_ignore_activity_culling = false;
m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR); 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. m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks);
m_pSGNode->SetParentRelation(KX_NormalParentRelation::New());
KX_NormalParentRelation * parent_relation = }
KX_NormalParentRelation::New();
m_pSGNode->SetParentRelation(parent_relation);
};
@@ -157,8 +153,7 @@ KX_GameObject::~KX_GameObject()
//if (m_sumoObj) //if (m_sumoObj)
// delete m_sumoObj; // delete m_sumoObj;
delete m_pClient_info; delete m_pClient_info;
//if (m_pSGNode)
// delete m_pSGNode;
if (m_pSGNode) if (m_pSGNode)
{ {
// must go through controllers and make sure they will not use us anymore // 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); m_pPhysicsController->RelativeTranslate(dloc,local);
} }
GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local); GetSGNode()->RelativeTranslate(dloc,local);
} }
} }

View File

@@ -45,8 +45,8 @@ class KX_ISceneConverter
{ {
public: public:
KX_ISceneConverter() :addInitFromFrame(false) {}//this addInitFromFrame is a back hack, todo remove KX_ISceneConverter() {}
virtual ~KX_ISceneConverter () {}; virtual ~KX_ISceneConverter () {}
/* /*
* scenename: name of the scene to be converted, * scenename: name of the scene to be converted,
@@ -59,7 +59,7 @@ public:
class RAS_IRasterizer* rendertools, class RAS_IRasterizer* rendertools,
class RAS_ICanvas* canvas, class RAS_ICanvas* canvas,
bool libloading=false)=0; bool libloading=false)=0;
virtual void RemoveScene(class KX_Scene *scene)=0; virtual void RemoveScene(class KX_Scene *scene)=0;
// handle any pending merges from asynchronous loads // handle any pending merges from asynchronous loads
@@ -69,11 +69,9 @@ public:
virtual void SetNewFileName(const STR_String& filename) = 0; virtual void SetNewFileName(const STR_String& filename) = 0;
virtual bool TryAndLoadNewFile() = 0; virtual bool TryAndLoadNewFile() = 0;
bool addInitFromFrame;//rcruiz
virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo) = 0; virtual void ResetPhysicsObjectsAnimationIpo(bool clearIpo) = 0;
///this generates ipo curves for position, rotation, allowing to use game physics in animation ///this generates ipo curves for position, rotation, allowing to use game physics in animation
virtual void WritePhysicsObjectToAnimationIpo(int frameNumber) = 0; virtual void WritePhysicsObjectToAnimationIpo(int frameNumber) = 0;
virtual void TestHandlesPhysicsObjectToAnimationIpo() = 0; virtual void TestHandlesPhysicsObjectToAnimationIpo() = 0;

View File

@@ -80,9 +80,6 @@
#include "KX_NavMeshObject.h" #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_LOGIC_TIC_RATE 60.0
//#define DEFAULT_PHYSICS_TIC_RATE 60.0 //#define DEFAULT_PHYSICS_TIC_RATE 60.0
@@ -741,85 +738,6 @@ bool KX_KetsjiEngine::NextFrame()
frames--; 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 // Start logging time spend outside main loop
m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true); m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true);

View File

@@ -36,6 +36,7 @@ enum e_PhysicsEngine
{ {
NoSelection = -1, NoSelection = -1,
UseNone = 0, UseNone = 0,
/* UseEnji=1, UseSumo, useDynamo and useODE were removed */
UseBullet = 5, UseBullet = 5,
}; };

View File

@@ -56,38 +56,75 @@
// if there is a better way (without global), please do so! // if there is a better way (without global), please do so!
static PHY_IPhysicsEnvironment* g_CurrentActivePhysicsEnvironment = NULL; static PHY_IPhysicsEnvironment* g_CurrentActivePhysicsEnvironment = NULL;
static char PhysicsConstraints_module_documentation[] =
"This is the Python API for the Physics Constraints";
PyDoc_STRVAR(PhysicsConstraints_module_documentation,
"This is the Python API for the Physics Constraints"
);
static char gPySetGravity__doc__[] = "setGravity(float x,float y,float z)"; PyDoc_STRVAR(gPySetGravity__doc__,
static char gPySetDebugMode__doc__[] = "setDebugMode(int mode)"; "setGravity(float x,float y,float z)\n"
"");
PyDoc_STRVAR(gPySetDebugMode__doc__,
"setDebugMode(int mode)\n"
"");
static char gPySetNumIterations__doc__[] = "setNumIterations(int numiter) This sets the number of iterations for an iterative constraint solver"; PyDoc_STRVAR(gPySetNumIterations__doc__,
static char gPySetNumTimeSubSteps__doc__[] = "setNumTimeSubSteps(int numsubstep) This sets the number of substeps for each physics proceed. Tradeoff quality for performance."; "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)");
static char gPySetDeactivationTime__doc__[] = "setDeactivationTime(float time) This sets the time after which a resting rigidbody gets deactived"; PyDoc_STRVAR(gPySetCcdMode__doc__,
static char gPySetDeactivationLinearTreshold__doc__[] = "setDeactivationLinearTreshold(float linearTreshold)"; "setCcdMode(int ccdMode)\n"
static char gPySetDeactivationAngularTreshold__doc__[] = "setDeactivationAngularTreshold(float angularTreshold)"; "Very experimental, not recommended");
static char gPySetContactBreakingTreshold__doc__[] = "setContactBreakingTreshold(float breakingTreshold) Reasonable default is 0.02 (if units are meters)"; PyDoc_STRVAR(gPySetSorConstant__doc__,
"setSorConstant(float sor)\n"
static char gPySetCcdMode__doc__[] = "setCcdMode(int ccdMode) Very experimental, not recommended"; "Very experimental, not recommended");
static char gPySetSorConstant__doc__[] = "setSorConstant(float sor) Very experimental, not recommended"; PyDoc_STRVAR(gPySetSolverTau__doc__,
static char gPySetSolverTau__doc__[] = "setTau(float tau) Very experimental, not recommended"; "setTau(float tau)\n"
static char gPySetSolverDamping__doc__[] = "setDamping(float damping) Very experimental, not recommended"; "Very experimental, not recommended");
static char gPySetLinearAirDamping__doc__[] = "setLinearAirDamping(float damping) Very experimental, not recommended"; PyDoc_STRVAR(gPySetSolverDamping__doc__,
static char gPySetUseEpa__doc__[] = "setUseEpa(int epa) Very experimental, not recommended"; "setDamping(float damping)\n"
static char gPySetSolverType__doc__[] = "setSolverType(int solverType) Very experimental, not recommended"; "Very experimental, not recommended");
PyDoc_STRVAR(gPySetLinearAirDamping__doc__,
"setLinearAirDamping(float damping)\n"
static char gPyCreateConstraint__doc__[] = "createConstraint(ob1,ob2,float restLength,float restitution,float damping)"; "Very experimental, not recommended");
static char gPyGetVehicleConstraint__doc__[] = "getVehicleConstraint(int constraintId)"; PyDoc_STRVAR(gPySetUseEpa__doc__,
static char gPyGetCharacter__doc__[] = "getCharacter(KX_GameObject obj)"; "setUseEpa(int epa)\n"
static char gPyRemoveConstraint__doc__[] = "removeConstraint(int constraintId)"; "Very experimental, not recommended");
static char gPyGetAppliedImpulse__doc__[] = "getAppliedImpulse(int constraintId)"; 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 = { static struct PyModuleDef PhysicsConstraints_module_def = {
{}, /* m_base */ PyModuleDef_HEAD_INIT,
"PhysicsConstraints", /* m_name */ "PhysicsConstraints", /* m_name */
PhysicsConstraints_module_documentation, /* m_doc */ PhysicsConstraints_module_documentation, /* m_doc */
0, /* m_size */ 0, /* m_size */
@@ -688,7 +725,7 @@ static struct PyModuleDef PhysicsConstraints_module_def = {
0, /* m_free */ 0, /* m_free */
}; };
PyObject *initPythonConstraintBinding() PyMODINIT_FUNC initConstraintPythonBinding()
{ {
PyObject *ErrorObject; PyObject *ErrorObject;
@@ -747,7 +784,7 @@ PyObject *initPythonConstraintBinding()
Py_FatalError("can't initialize module PhysicsConstraints"); Py_FatalError("can't initialize module PhysicsConstraints");
} }
return d; return m;
} }
#if 0 #if 0

View File

@@ -36,7 +36,8 @@
#include <Python.h> #include <Python.h>
PyObject* initPythonConstraintBinding(); PyMODINIT_FUNC initConstraintPythonBinding();
void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env); void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env);
PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment(); PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment();
#endif /* WITH_PYTHON */ #endif /* WITH_PYTHON */

View File

@@ -223,8 +223,11 @@ static void KX_MACRO_addTypesToDict_fn(PyObject *dict, const char *name, long va
// List of methods defined in the module // List of methods defined in the module
static PyObject *ErrorObject; 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 *) static PyObject *gPyGetRandomFloat(PyObject *)
{ {
return PyFloat_FromDouble(MT_random()); return PyFloat_FromDouble(MT_random());
@@ -242,15 +245,15 @@ static PyObject *gPySetGravity(PyObject *, PyObject *value)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static char gPyExpandPath_doc[] = PyDoc_STRVAR(gPyExpandPath_doc,
"(path) - Converts a blender internal path into a proper file system path.\n\ "expandPath(path)\n"
path - the string path to convert.\n\n\ "Converts a blender internal path into a proper file system path.\n"
Use / as directory separator in path\n\ " path - the string path to convert.\n"
You can use '//' at the start of the string to define a relative path;\n\ "Use / as directory separator in path\n"
Blender replaces that string by the directory of the current .blend or runtime\n\ "You can use '//' at the start of the string to define a relative path."
file to make a full path name.\n\ "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."; "The function also converts the directory separator to the local file system format."
);
static PyObject *gPyExpandPath(PyObject *, PyObject *args) static PyObject *gPyExpandPath(PyObject *, PyObject *args)
{ {
char expanded[FILE_MAX]; char expanded[FILE_MAX];
@@ -264,10 +267,10 @@ static PyObject *gPyExpandPath(PyObject *, PyObject *args)
return PyC_UnicodeFromByte(expanded); return PyC_UnicodeFromByte(expanded);
} }
static char gPyStartGame_doc[] = PyDoc_STRVAR(gPyStartGame_doc,
"startGame(blend)\n\ "startGame(blend)\n"
Loads the blend file"; "Loads the blend file"
);
static PyObject *gPyStartGame(PyObject *, PyObject *args) static PyObject *gPyStartGame(PyObject *, PyObject *args)
{ {
char* blendfile; char* blendfile;
@@ -281,10 +284,10 @@ static PyObject *gPyStartGame(PyObject *, PyObject *args)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static char gPyEndGame_doc[] = PyDoc_STRVAR(gPyEndGame_doc,
"endGame()\n\ "endGame()\n"
Ends the current game"; "Ends the current game"
);
static PyObject *gPyEndGame(PyObject *) static PyObject *gPyEndGame(PyObject *)
{ {
gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_QUIT_GAME); gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_QUIT_GAME);
@@ -294,10 +297,10 @@ static PyObject *gPyEndGame(PyObject *)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static char gPyRestartGame_doc[] = PyDoc_STRVAR(gPyRestartGame_doc,
"restartGame()\n\ "restartGame()\n"
Restarts the current game by reloading the .blend file"; "Restarts the current game by reloading the .blend file"
);
static PyObject *gPyRestartGame(PyObject *) static PyObject *gPyRestartGame(PyObject *)
{ {
gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_RESTART_GAME); gp_KetsjiEngine->RequestExit(KX_EXIT_REQUEST_RESTART_GAME);
@@ -306,10 +309,10 @@ static PyObject *gPyRestartGame(PyObject *)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static char gPySaveGlobalDict_doc[] = PyDoc_STRVAR(gPySaveGlobalDict_doc,
"saveGlobalDict()\n" "saveGlobalDict()\n"
"Saves bge.logic.globalDict to a file"; "Saves bge.logic.globalDict to a file"
);
static PyObject *gPySaveGlobalDict(PyObject *) static PyObject *gPySaveGlobalDict(PyObject *)
{ {
char marshal_path[512]; char marshal_path[512];
@@ -343,10 +346,10 @@ static PyObject *gPySaveGlobalDict(PyObject *)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static char gPyLoadGlobalDict_doc[] = PyDoc_STRVAR(gPyLoadGlobalDict_doc,
"LoadGlobalDict()\n" "LoadGlobalDict()\n"
"Loads bge.logic.globalDict from a file"; "Loads bge.logic.globalDict from a file"
);
static PyObject *gPyLoadGlobalDict(PyObject *) static PyObject *gPyLoadGlobalDict(PyObject *)
{ {
char marshal_path[512]; char marshal_path[512];
@@ -384,23 +387,23 @@ static PyObject *gPyLoadGlobalDict(PyObject *)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static char gPyGetProfileInfo_doc[] = PyDoc_STRVAR(gPyGetProfileInfo_doc,
"getProfileInfo()\n" "getProfileInfo()\n"
"returns a dictionary with profiling information"; "returns a dictionary with profiling information"
);
static PyObject *gPyGetProfileInfo(PyObject *) static PyObject *gPyGetProfileInfo(PyObject *)
{ {
return gp_KetsjiEngine->GetPyProfileDict(); return gp_KetsjiEngine->GetPyProfileDict();
} }
static char gPySendMessage_doc[] = PyDoc_STRVAR(gPySendMessage_doc,
"sendMessage(subject, [body, to, from])\n\ "sendMessage(subject, [body, to, from])\n"
sends a message in same manner as a message actuator\ "sends a message in same manner as a message actuator"
subject = Subject of the message\ " subject = Subject of the message"
body = Message body\ " body = Message body"
to = Name of object to send the message to\ " to = Name of object to send the message to"
from = Name of object to send the string from"; " from = Name of object to send the string from"
);
static PyObject *gPySendMessage(PyObject *, PyObject *args) static PyObject *gPySendMessage(PyObject *, PyObject *args)
{ {
char* subject; char* subject;
@@ -560,11 +563,12 @@ static PyObject *gPyGetBlendFileList(PyObject *, PyObject *args)
return list; return list;
} }
static char gPyAddScene_doc[] = PyDoc_STRVAR(gPyAddScene_doc,
"addScene(name, [overlay])\n\ "addScene(name, [overlay])\n"
adds a scene to the game engine\n\ "Adds a scene to the game engine.\n"
name = Name of the scene\n\ " name = Name of the scene\n"
overlay = Overlay or underlay"; " overlay = Overlay or underlay"
);
static PyObject *gPyAddScene(PyObject *, PyObject *args) static PyObject *gPyAddScene(PyObject *, PyObject *args)
{ {
char* name; char* name;
@@ -578,17 +582,19 @@ static PyObject *gPyAddScene(PyObject *, PyObject *args)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static const char *gPyGetCurrentScene_doc = PyDoc_STRVAR(gPyGetCurrentScene_doc,
"getCurrentScene()\n" "getCurrentScene()\n"
"Gets a reference to the current scene.\n"; "Gets a reference to the current scene."
);
static PyObject *gPyGetCurrentScene(PyObject *self) static PyObject *gPyGetCurrentScene(PyObject *self)
{ {
return gp_KetsjiScene->GetProxy(); return gp_KetsjiScene->GetProxy();
} }
static const char *gPyGetSceneList_doc = PyDoc_STRVAR(gPyGetSceneList_doc,
"getSceneList()\n" "getSceneList()\n"
"Return a list of converted scenes.\n"; "Return a list of converted scenes."
);
static PyObject *gPyGetSceneList(PyObject *self) static PyObject *gPyGetSceneList(PyObject *self)
{ {
KX_KetsjiEngine* m_engine = KX_GetActiveEngine(); 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[] = { static struct PyMethodDef rasterizer_methods[] = {
{"getWindowWidth",(PyCFunction) gPyGetWindowWidth, {"getWindowWidth",(PyCFunction) gPyGetWindowWidth,
METH_VARARGS, "getWindowWidth doc"}, METH_VARARGS, "getWindowWidth doc"},
@@ -1525,15 +1536,11 @@ static struct PyMethodDef rasterizer_methods[] = {
{ NULL, (PyCFunction) NULL, 0, NULL } { 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[] = PyDoc_STRVAR(GameLogic_module_documentation,
"This is the Python API for the game engine of Rasterizer" "This is the Python API for the game engine of bge.logic"
; );
static struct PyModuleDef GameLogic_module_def = { static struct PyModuleDef GameLogic_module_def = {
{}, /* m_base */ {}, /* m_base */
@@ -1547,17 +1554,14 @@ static struct PyModuleDef GameLogic_module_def = {
0, /* m_free */ 0, /* m_free */
}; };
PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack to get gravity hook PyMODINIT_FUNC initGameLogicPythonBinding()
{ {
PyObject *m; PyObject *m;
PyObject *d; PyObject *d;
PyObject *item; /* temp PyObject *storage */ PyObject *item; /* temp PyObject *storage */
gp_KetsjiEngine = engine;
gp_KetsjiScene = scene;
gUseVisibilityTemp=false; gUseVisibilityTemp=false;
PyObjectPlus::ClearDeprecationWarning(); /* Not that nice to call here but makes sure warnings are reset between loading scenes */ PyObjectPlus::ClearDeprecationWarning(); /* Not that nice to call here but makes sure warnings are reset between loading scenes */
/* Use existing module where possible /* Use existing module where possible
@@ -2053,7 +2057,61 @@ void removeImportMain(struct Main *maggie)
bpy_import_main_extra_remove(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[] = { static struct _inittab bge_internal_modules[] = {
{"mathutils", PyInit_mathutils}, {"mathutils", PyInit_mathutils},
{"bgl", BPyInit_bgl}, {"bgl", BPyInit_bgl},
@@ -2066,7 +2124,7 @@ static struct _inittab bge_internal_modules[] = {
* Python is not initialized. * Python is not initialized.
* see bpy_interface.c's BPY_python_start() which shares the same functionality in blender. * 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 /* Yet another gotcha in the py api
* Cant run PySys_SetArgv more than once because this adds the * 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; static bool first_time = true;
const char * const py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); const char * const py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);
#if 0 // TODO - py3 /* not essential but nice to set our name */
STR_String pname = progname; static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */
Py_SetProgramName(pname.Ptr()); BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar));
#endif 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) { if (py_path_bundle != NULL) {
Py_NoSiteFlag = 1; Py_NoSiteFlag = 1; /* inhibits the automatic importing of 'site' */
} }
#endif
Py_FrozenFlag = 1; Py_FrozenFlag = 1;
@@ -2108,12 +2172,14 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
PySys_SetObject("argv", py_argv); PySys_SetObject("argv", py_argv);
Py_DECREF(py_argv); Py_DECREF(py_argv);
} }
/* Initialize thread support (also acquires lock) */ /* Initialize thread support (also acquires lock) */
PyEval_InitThreads(); PyEval_InitThreads();
bpy_import_init(PyEval_GetBuiltins()); 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 */ /* mathutils types are used by the BGE even if we don't import them */
{ {
PyObject *mod = PyImport_ImportModuleLevel("mathutils", NULL, NULL, NULL, 0); PyObject *mod = PyImport_ImportModuleLevel("mathutils", NULL, NULL, NULL, 0);
@@ -2128,12 +2194,12 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
} }
#endif #endif
initPyTypes();
bpy_import_main_set(maggie); bpy_import_main_set(maggie);
initPySysObjects(maggie); initPySysObjects(maggie);
initPyTypes();
first_time = false; first_time = false;
PyObjectPlus::ClearDeprecationWarning(); PyObjectPlus::ClearDeprecationWarning();
@@ -2170,12 +2236,11 @@ void exitGamePlayerPythonScripting()
/** /**
* Python is already initialized. * Python is already initialized.
*/ */
PyObject *initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie) PyObject *initGamePythonScripting(Main *maggie)
{ {
#if 0 // XXX TODO Py3 /* no need to Py_SetProgramName, it was already taken care of in BPY_python_start */
STR_String pname = progname;
Py_SetProgramName(pname.Ptr()); PyDict_SetItemString(PyImport_GetModuleDict(), "bge", initBGE());
#endif
#ifdef WITH_AUDASPACE #ifdef WITH_AUDASPACE
/* accessing a SoundActuator's sound results in a crash if aud is not initialized... */ /* 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, void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene *startscene, Main *blenderdata,
PyObject *pyGlobalDict, PyObject **gameLogic, PyObject **gameLogic_keys, int argc, char** argv) 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 */ if (argv) /* player only */
dictionaryobject= initGamePlayerPythonScripting("Ketsji", psl_Lowest, blenderdata, argc, argv); dictionaryobject= initGamePlayerPythonScripting(blenderdata, argc, argv);
else else
dictionaryobject= initGamePythonScripting("Ketsji", psl_Lowest, blenderdata); dictionaryobject= initGamePythonScripting(blenderdata);
ketsjiengine->SetPyNamespace(dictionaryobject); 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) if (pyGlobalDict)
PyDict_SetItemString(PyModule_GetDict(*gameLogic), "globalDict", pyGlobalDict); // Same as importing the module. PyDict_SetItemString(PyModule_GetDict(*gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
*gameLogic_keys = PyDict_Keys(PyModule_GetDict(*gameLogic)); *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 = { static struct PyModuleDef Rasterizer_module_def = {
{}, /* m_base */ PyModuleDef_HEAD_INIT,
"Rasterizer", /* m_name */ "Rasterizer", /* m_name */
Rasterizer_module_documentation, /* m_doc */ Rasterizer_module_documentation, /* m_doc */
0, /* m_size */ 0, /* m_size */
@@ -2277,12 +2323,8 @@ static struct PyModuleDef Rasterizer_module_def = {
0, /* m_free */ 0, /* m_free */
}; };
PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) PyMODINIT_FUNC initRasterizerPythonBinding()
{ {
gp_Canvas = canvas;
gp_Rasterizer = rasty;
PyObject *m; PyObject *m;
PyObject *d; PyObject *d;
@@ -2328,7 +2370,7 @@ PyObject *initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas)
Py_FatalError("can't initialize module Rasterizer"); 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 */ /* GameKeys: symbolic constants for key mapping */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static char GameKeys_module_documentation[] = PyDoc_STRVAR(GameKeys_module_documentation,
"This modules provides defines for key-codes" "This modules provides defines for key-codes"
; );
static char gPyEventToString_doc[] = PyDoc_STRVAR(gPyEventToString_doc,
"EventToString(event) - Take a valid event from the GameKeys module or Keyboard Sensor and return a name" "EventToString(event)\n"
; "Take a valid event from the GameKeys module or Keyboard Sensor and return a name"
);
static PyObject *gPyEventToString(PyObject *, PyObject *value) static PyObject *gPyEventToString(PyObject *, PyObject *value)
{ {
@@ -2371,9 +2414,11 @@ static PyObject *gPyEventToString(PyObject *, PyObject *value)
return ret; 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) static PyObject *gPyEventToCharacter(PyObject *, PyObject *args)
{ {
@@ -2399,7 +2444,7 @@ static struct PyMethodDef gamekeys_methods[] = {
}; };
static struct PyModuleDef GameKeys_module_def = { static struct PyModuleDef GameKeys_module_def = {
{}, /* m_base */ PyModuleDef_HEAD_INIT,
"GameKeys", /* m_name */ "GameKeys", /* m_name */
GameKeys_module_documentation, /* m_doc */ GameKeys_module_documentation, /* m_doc */
0, /* m_size */ 0, /* m_size */
@@ -2410,11 +2455,11 @@ static struct PyModuleDef GameKeys_module_def = {
0, /* m_free */ 0, /* m_free */
}; };
PyObject *initGameKeys() PyMODINIT_FUNC initGameKeysPythonBinding()
{ {
PyObject *m; PyObject *m;
PyObject *d; PyObject *d;
/* Use existing module where possible */ /* Use existing module where possible */
m = PyImport_ImportModule( "GameKeys" ); m = PyImport_ImportModule( "GameKeys" );
if (m) { if (m) {
@@ -2423,7 +2468,7 @@ PyObject *initGameKeys()
} }
else { else {
PyErr_Clear(); PyErr_Clear();
// Create the module and add the functions // Create the module and add the functions
m = PyModule_Create(&GameKeys_module_def); m = PyModule_Create(&GameKeys_module_def);
PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m); PyDict_SetItemString(PySys_GetObject("modules"), GameKeys_module_def.m_name, m);
@@ -2572,7 +2617,7 @@ PyObject *initGameKeys()
Py_FatalError("can't initialize module GameKeys"); Py_FatalError("can't initialize module GameKeys");
} }
return d; return m;
} }
// utility function for loading and saving the globalDict // utility function for loading and saving the globalDict

View File

@@ -36,6 +36,9 @@
#include "STR_String.h" #include "STR_String.h"
#include "MT_Vector3.h" #include "MT_Vector3.h"
class KX_KetsjiEngine;
class KX_Scene;
typedef enum { typedef enum {
psl_Lowest = 0, psl_Lowest = 0,
psl_Highest, psl_Highest,
@@ -44,13 +47,13 @@ typedef enum {
extern bool gUseVisibilityTemp; extern bool gUseVisibilityTemp;
#ifdef WITH_PYTHON #ifdef WITH_PYTHON
PyObject *initGameLogic(class KX_KetsjiEngine *engine, class KX_Scene *ketsjiscene); PyMODINIT_FUNC initBGE(void);
PyObject *initGameKeys(); PyMODINIT_FUNC initGameLogicPythonBinding(void);
PyObject *initRasterizer(class RAS_IRasterizer *rasty,class RAS_ICanvas *canvas); PyMODINIT_FUNC initGameKeysPythonBinding(void);
PyObject *initGamePlayerPythonScripting(const STR_String &progname, TPythonSecurityLevel level, PyMODINIT_FUNC initRasterizerPythonBinding(void);
struct Main *maggie, int argc, char **argv); PyMODINIT_FUNC initVideoTexturePythonBinding(void);
PyObject *initVideoTexture(void); PyObject *initGamePlayerPythonScripting(struct Main *maggie, int argc, char **argv);
PyObject *initGamePythonScripting(const STR_String &progname, TPythonSecurityLevel level, struct Main *maggie); PyObject *initGamePythonScripting(struct Main *maggie);
void exitGamePlayerPythonScripting(); void exitGamePlayerPythonScripting();
void exitGamePythonScripting(); void exitGamePythonScripting();
@@ -69,9 +72,9 @@ void removeImportMain(struct Main *maggie);
class KX_KetsjiEngine; class KX_KetsjiEngine;
class KX_Scene; class KX_Scene;
void KX_SetActiveScene(class KX_Scene *scene); void KX_SetActiveScene(KX_Scene *scene);
class KX_Scene *KX_GetActiveScene(); KX_Scene *KX_GetActiveScene();
class KX_KetsjiEngine *KX_GetActiveEngine(); KX_KetsjiEngine *KX_GetActiveEngine();
typedef int (*PyNextFrameFunc)(void *); typedef int (*PyNextFrameFunc)(void *);

View File

@@ -171,8 +171,10 @@ void initPyTypes(void)
* ..... * .....
*/ */
/* Use existing module where possible */
PyObject *mod = initGameTypesPythonBinding();
/* For now just do PyType_Ready */ /* For now just do PyType_Ready */
PyObject *mod = PyModule_New("GameTypes");
PyObject *dict = PyModule_GetDict(mod); PyObject *dict = PyModule_GetDict(mod);
PyDict_SetItemString(PySys_GetObject("modules"), "GameTypes", mod); PyDict_SetItemString(PySys_GetObject("modules"), "GameTypes", mod);
Py_DECREF(mod); Py_DECREF(mod);
@@ -269,4 +271,42 @@ void initPyTypes(void)
#endif #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 #endif // WITH_PYTHON

View File

@@ -33,7 +33,9 @@
#define __KX_PYTHON_INIT_TYPES__ #define __KX_PYTHON_INIT_TYPES__
#ifdef WITH_PYTHON #ifdef WITH_PYTHON
#include <Python.h>
void initPyTypes(void); void initPyTypes(void);
PyMODINIT_FUNC initGameTypesPythonBinding(void);
#endif #endif
#endif /* __KX_PYTHON_INIT_TYPES__ */ #endif /* __KX_PYTHON_INIT_TYPES__ */

View File

@@ -38,44 +38,24 @@
#include "BL_ArmatureObject.h" #include "BL_ArmatureObject.h"
/** KX_BoneParentRelation* KX_BoneParentRelation::New(Bone* bone)
* Implementation of classes defined in KX_SG_BoneParentNodeRelationship.h {
*/
/**
* first of all KX_SG_BoneParentRelation
*/
KX_BoneParentRelation *
KX_BoneParentRelation::
New(Bone* bone
) {
return new KX_BoneParentRelation(bone); return new KX_BoneParentRelation(bone);
} }
bool bool KX_BoneParentRelation::UpdateChildCoordinates(SG_Spatial * child, const SG_Spatial * parent, bool& parentUpdated)
KX_BoneParentRelation:: {
UpdateChildCoordinates(
SG_Spatial * child,
const SG_Spatial * parent,
bool& parentUpdated
) {
MT_assert(child != NULL); MT_assert(child != NULL);
// This way of accessing child coordinates is a bit cumbersome // This way of accessing child coordinates is a bit cumbersome
// be nice to have non constant reference access to these values. // 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_Vector3 child_w_scale;
MT_Point3 child_w_pos; MT_Point3 child_w_pos;
MT_Matrix3x3 child_w_rotation; MT_Matrix3x3 child_w_orientation;
bool valid_parent_transform = false; bool valid_parent_transform = false;
@@ -88,68 +68,62 @@ UpdateChildCoordinates(
if (armature->GetBoneMatrix(m_bone, parent_matrix)) if (armature->GetBoneMatrix(m_bone, parent_matrix))
{ {
// Get the child's transform, and the bone matrix. // Get the child's transform, and the bone matrix.
MT_Matrix4x4 child_transform ( MT_Matrix4x4 child_transform (
MT_Transform(child_pos + MT_Vector3(0.0, armature->GetBoneLength(m_bone), 0.0), MT_Transform(
child_rotation.scaled( child_l_pos + MT_Vector3(0.0, armature->GetBoneLength(m_bone), 0.0),
child_scale[0], child_l_orientation.scaled(child_l_scale[0], child_l_scale[1], child_l_scale[2])));
child_scale[1],
child_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
// The child's world transform is parent * child
parent_matrix = parent->GetWorldTransform() * parent_matrix;
child_transform = parent_matrix * child_transform;
// Recompute the child transform components from the transform. // Recompute the child transform components from the transform.
child_w_scale.setValue( child_w_scale.setValue(
MT_Vector3(child_transform[0][0], child_transform[0][1], child_transform[0][2]).length(), 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[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()); 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[1][0], child_transform[1][1], child_transform[1][2],
child_transform[2][0], child_transform[2][1], child_transform[2][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]); child_w_pos = MT_Point3(child_transform[0][3], child_transform[1][3], child_transform[2][3]);
valid_parent_transform = true; valid_parent_transform = true;
} }
} }
} }
if (valid_parent_transform) if (valid_parent_transform)
{ {
child->SetWorldScale(child_w_scale); child->SetWorldScale(child_w_scale);
child->SetWorldPosition(child_w_pos); child->SetWorldPosition(child_w_pos);
child->SetWorldOrientation(child_w_rotation); child->SetWorldOrientation(child_w_orientation);
} }
else { else {
/* the parent is null or not an armature */
child->SetWorldFromLocalTransform(); child->SetWorldFromLocalTransform();
} }
parentUpdated = true; //this variable is going to be used to update the children of this child
child->ClearModified(); child->ClearModified();
// this node must always be updated, so reschedule it for next time // this node must always be updated, so reschedule it for next time
child->ActivateRecheduleUpdateCallback(); child->ActivateRecheduleUpdateCallback();
return valid_parent_transform; return valid_parent_transform;
} }
SG_ParentRelation * SG_ParentRelation* KX_BoneParentRelation::NewCopy()
KX_BoneParentRelation:: {
NewCopy( return new KX_BoneParentRelation(m_bone);
) {
KX_BoneParentRelation* bone_parent = new KX_BoneParentRelation(m_bone);
return bone_parent;
} }
KX_BoneParentRelation:: KX_BoneParentRelation::~KX_BoneParentRelation()
~KX_BoneParentRelation( {
) {
//nothing to do //nothing to do
} }
KX_BoneParentRelation:: KX_BoneParentRelation::KX_BoneParentRelation(Bone* bone)
KX_BoneParentRelation(Bone* bone : m_bone(bone)
)
: m_bone(bone)
{ {
// nothing to do // nothing to do
} }

View File

@@ -39,53 +39,33 @@
struct Bone; struct Bone;
/** /**
* Bone parent relationship parents a child SG_Spatial frame to a * Bone parent relationship parents a child SG_Spatial frame to a bone in an armature object.
* bone in an armature object.
*/ */
class KX_BoneParentRelation : public SG_ParentRelation class KX_BoneParentRelation : public SG_ParentRelation
{ {
public : public :
/** /**
* Allocate and construct a new KX_SG_BoneParentRelation * Allocate and construct a new KX_SG_BoneParentRelation on the heap.
* 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
*/ */
static KX_BoneParentRelation* New(Bone* bone);
static
KX_BoneParentRelation *
New(Bone* bone
);
/** /**
* Updates the childs world coordinates relative to the parent's * Updates the child's world coordinates based upon the local ones and relative to the parent's world coordinates.
* world coordinates.
*
* Parent should be a BL_ArmatureObject. * Parent should be a BL_ArmatureObject.
*/ */
bool bool UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated);
UpdateChildCoordinates(
SG_Spatial * child,
const SG_Spatial * parent,
bool& parentUpdated
);
/** /**
* Create a copy of this relationship * Create a copy of this relationship
*/ */
SG_ParentRelation * SG_ParentRelation* NewCopy();
NewCopy(
);
~KX_BoneParentRelation( ~KX_BoneParentRelation();
);
private : private :
Bone* m_bone; Bone* m_bone;
KX_BoneParentRelation(Bone* bone KX_BoneParentRelation(Bone* bone);
);
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
@@ -93,4 +73,4 @@ private :
#endif #endif
}; };
#endif #endif /* __KX_SG_BONEPARENTNODERELATIONSHIP_H__ */

View File

@@ -32,267 +32,214 @@
#include "KX_SG_NodeRelationships.h" #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* KX_NormalParentRelation::New()
KX_NormalParentRelation:: {
New(
) {
return new KX_NormalParentRelation(); return new KX_NormalParentRelation();
} }
bool bool KX_NormalParentRelation::UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated)
KX_NormalParentRelation:: {
UpdateChildCoordinates(
SG_Spatial * child,
const SG_Spatial * parent,
bool& parentUpdated
) {
MT_assert(child != NULL); MT_assert(child != NULL);
/* If nothing changed in the parent or child, there is nothing to do here */
if (!parentUpdated && !child->IsModified()) if (!parentUpdated && !child->IsModified())
return false; return false;
parentUpdated = true; /* 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) { /* Simple case */ if (parent==NULL) {
child->SetWorldFromLocalTransform(); 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 { else {
// the childs world locations which we will update. const MT_Vector3 & parent_world_scale = parent->GetWorldScaling();
const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); const MT_Point3 & parent_world_pos = parent->GetWorldPosition();
const MT_Point3 & p_world_pos = parent->GetWorldPosition(); const MT_Matrix3x3 & parent_world_ori = parent->GetWorldOrientation();
const MT_Matrix3x3 & p_world_rotation = 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();
child->SetWorldScale(p_world_scale * child->GetLocalScale()); const MT_Vector3 & new_world_scale = parent_world_scale * child_local_scale;
child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation()); const MT_Matrix3x3 & new_world_ori = parent_world_ori * child_local_ori;
child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition())); const MT_Point3 & new_world_pos = parent_world_pos + (new_world_scale * (new_world_ori * child_local_pos));
child->ClearModified();
return true; 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 * SG_ParentRelation* KX_NormalParentRelation::NewCopy()
KX_NormalParentRelation:: {
NewCopy(
) {
return new KX_NormalParentRelation(); return new KX_NormalParentRelation();
} }
KX_NormalParentRelation:: KX_NormalParentRelation::~KX_NormalParentRelation()
~KX_NormalParentRelation(
) {
//nothing to do
}
KX_NormalParentRelation::
KX_NormalParentRelation(
) {
// nothing to do
}
/**
* Next KX_VertexParentRelation
*/
KX_VertexParentRelation *
KX_VertexParentRelation::
New(
) {
return new KX_VertexParentRelation();
}
/**
* Method inherited from KX_ParentRelation
*/
bool
KX_VertexParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
const SG_Spatial * parent,
bool& parentUpdated
) {
MT_assert(child != NULL);
if (!parentUpdated && !child->IsModified())
return false;
child->SetWorldScale(child->GetLocalScale());
if (parent)
child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition());
else
child->SetWorldPosition(child->GetLocalPosition());
child->SetWorldOrientation(child->GetLocalOrientation());
child->ClearModified();
return true; //parent != NULL;
}
/**
* Method inherited from KX_ParentRelation
*/
SG_ParentRelation *
KX_VertexParentRelation::
NewCopy(
) {
return new KX_VertexParentRelation();
};
KX_VertexParentRelation::
~KX_VertexParentRelation(
) {
//nothing to do
}
KX_VertexParentRelation::
KX_VertexParentRelation(
) {
//nothing to do
}
/**
* Slow parent relationship
*/
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
) {
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);
if (m_initialized) {
// get the current world positions
child_w_scale = child->GetWorldScaling();
child_w_pos = child->GetWorldPosition();
child_w_rotation = child->GetWorldOrientation();
// 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;
m_initialized = true;
}
} else {
child_w_scale = child_scale;
child_w_pos = child_pos;
child_w_rotation = child_rotation;
}
child->SetWorldScale(child_w_scale);
child->SetWorldPosition(child_w_pos);
child->SetWorldOrientation(child_w_rotation);
child->ClearModified();
// this node must always be updated, so reschedule it for next time
child->ActivateRecheduleUpdateCallback();
return true; //parent != NULL;
}
/**
* Method inherited from KX_ParentRelation
*/
SG_ParentRelation *
KX_SlowParentRelation::
NewCopy(
) {
return new KX_SlowParentRelation(m_relax);
}
KX_SlowParentRelation::
KX_SlowParentRelation(
MT_Scalar relaxation
):
m_relax(relaxation),
m_initialized(false)
{ {
//nothing to do //nothing to do
} }
KX_SlowParentRelation:: KX_NormalParentRelation::KX_NormalParentRelation()
~KX_SlowParentRelation( {
) { // nothing to do
}
/**
* KX_VertexParentRelation - the child only inherits the position, not the orientation or scale
*/
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;
/* 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;
}
SG_ParentRelation* KX_VertexParentRelation::NewCopy()
{
return new KX_VertexParentRelation();
}
KX_VertexParentRelation::~KX_VertexParentRelation()
{
//nothing to do
}
KX_VertexParentRelation::KX_VertexParentRelation()
{
//nothing to do //nothing to do
} }
/**
* 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);
}
bool KX_SlowParentRelation::UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated)
{
MT_assert(child != NULL);
/* 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 */
const MT_Vector3 & current_world_scale = child->GetWorldScaling();
const MT_Matrix3x3 & current_world_ori = child->GetWorldOrientation();
const MT_Point3 & current_world_pos = child->GetWorldPosition();
/* 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);
//FIXME: update physics controller.
} else {
/**
* 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;
}
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();
// this node must always be updated, so reschedule it for next time
child->ActivateRecheduleUpdateCallback();
return true;
}
SG_ParentRelation* KX_SlowParentRelation::NewCopy()
{
return new KX_SlowParentRelation(m_relax);
}
KX_SlowParentRelation::KX_SlowParentRelation(MT_Scalar relaxation)
:m_initialized(false)
{
m_relax = fabs(relaxation);
m_weight = MT_Scalar(1)/(m_relax + 1);
}
KX_SlowParentRelation::~KX_SlowParentRelation()
{
//nothing to do
}

View File

@@ -28,15 +28,14 @@
/** \file KX_SG_NodeRelationships.h /** \file KX_SG_NodeRelationships.h
* \ingroup ketsji * \ingroup ketsji
* \section KX_SG_NodeRelationships * \section KX_SG_NodeRelationships
* This file provides common concrete implementations of * This file provides common concrete implementations of
* SG_ParentRelation used by the game engine. These are * SG_ParentRelation used by the game engine. These are:
* KX_SlowParentRelation a slow parent relationship. * - KX_NormalParentRelation a normal parent relationship where
* KX_NormalParentRelation a normal parent relationship where * orientation, position and scale are inherited from the parent by
* orientation and position are inherited from the parent by
* the child. * the child.
* KX_VertexParentRelation only location information is * - KX_VertexParentRelation only location information is inherited by the child.
* inherited by the child. * - KX_SlowParentRelation a slow parent relationship.
*/ */
#ifndef __KX_SG_NODERELATIONSHIPS_H__ #ifndef __KX_SG_NODERELATIONSHIPS_H__
@@ -50,41 +49,28 @@ class KX_NormalParentRelation : public SG_ParentRelation
public : public :
/** /**
* Allocate and construct a new KX_NormalParentRelation * Allocate and construct a new KX_NormalParentRelation on the heap.
* on the heap.
*/ */
static KX_NormalParentRelation* New();
static
KX_NormalParentRelation *
New(
);
/** /**
* Method inherited from KX_ParentRelation * 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 * 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 : private :
KX_NormalParentRelation( KX_NormalParentRelation();
);
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
@@ -99,47 +85,33 @@ class KX_VertexParentRelation : public SG_ParentRelation
public : public :
/** /**
* Allocate and construct a new KX_VertexParentRelation * Allocate and construct a new KX_VertexParentRelation on the heap.
* on the heap.
*/ */
static KX_VertexParentRelation* New();
static
KX_VertexParentRelation *
New(
);
/** /**
* Method inherited from KX_ParentRelation * 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 * 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 bool IsVertexRelation()
IsVertexRelation( {
) {
return true; return true;
} }
private : private :
KX_VertexParentRelation( KX_VertexParentRelation();
);
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
@@ -154,72 +126,43 @@ class KX_SlowParentRelation : public SG_ParentRelation
public : public :
/** /**
* Allocate and construct a new KX_VertexParentRelation * Allocate and construct a new KX_SlowParentRelation on the heap.
* on the heap.
*/ */
static KX_SlowParentRelation* New(MT_Scalar relaxation);
static /**
KX_SlowParentRelation *
New(
MT_Scalar relaxation
);
/**
* Method inherited from KX_ParentRelation * 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 * 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(
);
MT_Scalar ~KX_SlowParentRelation();
GetTimeOffset(
) { return m_relax; }
void
SetTimeOffset(
MT_Scalar relaxation
) { m_relax = relaxation; }
~KX_SlowParentRelation( bool IsSlowRelation()
); {
bool
IsSlowRelation(
) {
return true; return true;
} }
MT_Scalar GetTimeOffset() { return m_relax; }
void SetTimeOffset(MT_Scalar relaxation) { m_relax = relaxation; }
private : private :
KX_SlowParentRelation( KX_SlowParentRelation(MT_Scalar relaxation);
MT_Scalar relaxation
);
// the relaxation coefficient. MT_Scalar m_relax; /* the relaxation coefficient. the bigger, the slower */
MT_Scalar m_weight; /*inverse relax coefficient, computed only once for calculations*/
MT_Scalar m_relax;
/** /**
* Looks like a hack flag to me. * 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; bool m_initialized;
@@ -228,4 +171,4 @@ private :
#endif #endif
}; };
#endif #endif /* __KX_SG_NODERELATIONSHIPS_H__ */

View File

@@ -867,8 +867,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
m_map_gameobject_to_replica.clear(); m_map_gameobject_to_replica.clear();
m_groupGameObjects.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* originalobj = (KX_GameObject*) originalobject;
KX_GameObject* parentobj = (KX_GameObject*) parentobject; KX_GameObject* parentobj = (KX_GameObject*) parentobject;
@@ -877,9 +875,10 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
// lets create a replica // lets create a replica
KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj); 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) if (lifespan > 0)
{ {
// add a timebomb to this object
// for now, convert between so called frames and realtime // for now, convert between so called frames and realtime
m_tempObjectList->Add(replica->AddRef()); 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 // 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 // get the rootnode's scale
MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale(); MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
// set the replica's relative scale with the rootnode's scale // set the replica's relative scale with the rootnode's scale
replica->NodeSetRelativeScale(newscale); replica->NodeSetRelativeScale(newscale);

View File

@@ -272,6 +272,7 @@ struct CcdConstructionInfo
m_bSoft(false), m_bSoft(false),
m_bSensor(false), m_bSensor(false),
m_bCharacter(false), m_bCharacter(false),
m_bVehicle(false),
m_bGimpact(false), m_bGimpact(false),
m_collisionFilterGroup(DefaultFilter), m_collisionFilterGroup(DefaultFilter),
m_collisionFilterMask(AllFilter), m_collisionFilterMask(AllFilter),
@@ -299,8 +300,8 @@ struct CcdConstructionInfo
btVector3 m_linearFactor; btVector3 m_linearFactor;
btVector3 m_angularFactor; btVector3 m_angularFactor;
btScalar m_mass; btScalar m_mass;
btScalar m_clamp_vel_min; btScalar m_clamp_vel_min;
btScalar m_clamp_vel_max; btScalar m_clamp_vel_max;
btScalar m_restitution; btScalar m_restitution;
btScalar m_friction; btScalar m_friction;
btScalar m_linearDamping; btScalar m_linearDamping;
@@ -356,6 +357,7 @@ struct CcdConstructionInfo
bool m_bSoft; bool m_bSoft;
bool m_bSensor; bool m_bSensor;
bool m_bCharacter; bool m_bCharacter;
bool m_bVehicle;
bool m_bGimpact; // use Gimpact for mesh body bool m_bGimpact; // use Gimpact for mesh body
///optional use of collision group/mask: ///optional use of collision group/mask:

View File

@@ -58,14 +58,13 @@ extern "C" {
#define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80 #define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
#ifdef NEW_BULLET_VEHICLE_SUPPORT /* Vehicle Controller */
#include "BulletDynamics/Vehicle/btRaycastVehicle.h" #include "BulletDynamics/Vehicle/btRaycastVehicle.h"
#include "BulletDynamics/Vehicle/btVehicleRaycaster.h" #include "BulletDynamics/Vehicle/btVehicleRaycaster.h"
#include "BulletDynamics/Vehicle/btWheelInfo.h" #include "BulletDynamics/Vehicle/btWheelInfo.h"
#include "PHY_IVehicle.h" #include "PHY_IVehicle.h"
static btRaycastVehicle::btVehicleTuning gTuning; static btRaycastVehicle::btVehicleTuning gTuning;
#endif //NEW_BULLET_VEHICLE_SUPPORT
#include "LinearMath/btAabbUtil2.h" #include "LinearMath/btAabbUtil2.h"
#include "MT_Matrix4x4.h" #include "MT_Matrix4x4.h"
#include "MT_Vector3.h" #include "MT_Vector3.h"
@@ -97,220 +96,200 @@ void DrawRasterizerLine(const float* from,const float* to,int color);
#endif //_MSC_VER #endif //_MSC_VER
#endif //WIN32 #endif //WIN32
#ifdef NEW_BULLET_VEHICLE_SUPPORT
class WrapperVehicle : public PHY_IVehicle class WrapperVehicle : public PHY_IVehicle
{ {
btRaycastVehicle *m_vehicle;
btRaycastVehicle* m_vehicle; PHY_IPhysicsController *m_chassis;
PHY_IPhysicsController* m_chassis;
public: public:
WrapperVehicle(btRaycastVehicle* vehicle,PHY_IPhysicsController* chassis) WrapperVehicle(btRaycastVehicle* vehicle,PHY_IPhysicsController* chassis)
:m_vehicle(vehicle), :m_vehicle(vehicle),
m_chassis(chassis) m_chassis(chassis)
{ {}
}
~WrapperVehicle() ~WrapperVehicle()
{ {
delete m_vehicle; delete m_vehicle;
} }
btRaycastVehicle* GetVehicle() btRaycastVehicle* GetVehicle()
{ {
return m_vehicle; return m_vehicle;
} }
PHY_IPhysicsController* GetChassis() PHY_IPhysicsController* GetChassis()
{ {
return m_chassis; return m_chassis;
} }
virtual void AddWheel( virtual void AddWheel(
PHY_IMotionState* motionState, PHY_IMotionState *motionState,
MT_Vector3 connectionPoint, MT_Vector3 connectionPoint,
MT_Vector3 downDirection, MT_Vector3 downDirection,
MT_Vector3 axleDirection, MT_Vector3 axleDirection,
float suspensionRestLength, float suspensionRestLength,
float wheelRadius, float wheelRadius,
bool hasSteering bool hasSteering
) )
{ {
btVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]); btVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]);
btVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]); btVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]);
btVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]); btVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]);
btWheelInfo& info = m_vehicle->addWheel( connectionPointCS0,
btWheelInfo& info = m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxle, wheelDirectionCS0,
suspensionRestLength,wheelRadius,gTuning,hasSteering); wheelAxle,
suspensionRestLength,
wheelRadius,
gTuning,
hasSteering
);
info.m_clientInfo = motionState; info.m_clientInfo = motionState;
} }
void SyncWheels() void SyncWheels()
{ {
int numWheels = GetNumWheels(); int numWheels = GetNumWheels();
int i; int i;
for (i=0;i<numWheels;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);
m_vehicle->updateWheelTransform(i,false); m_vehicle->updateWheelTransform(i,false);
btTransform trans = m_vehicle->getWheelInfo(i).m_worldTransform; btTransform trans = m_vehicle->getWheelInfo(i).m_worldTransform;
btQuaternion orn = trans.getRotation(); btQuaternion orn = trans.getRotation();
const btVector3& pos = trans.getOrigin(); 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->SetWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]);
motionState->SetWorldPosition(pos.x(),pos.y(),pos.z()); motionState->SetWorldPosition(pos.x(),pos.y(),pos.z());
} }
} }
virtual int GetNumWheels() const virtual int GetNumWheels() const
{ {
return m_vehicle->getNumWheels(); 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); if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) {
posX = trans.getOrigin().x(); btTransform trans = m_vehicle->getWheelTransformWS(wheelIndex);
posY = trans.getOrigin().y(); posX = trans.getOrigin().x();
posZ = trans.getOrigin().z(); 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 float GetWheelRotation(int wheelIndex) const 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
{ {
float rotation = 0.f; float rotation = 0.f;
if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) if ((wheelIndex>=0) && (wheelIndex<m_vehicle->getNumWheels())) {
{
btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
rotation = info.m_rotation; rotation = info.m_rotation;
} }
return rotation; return rotation;
} }
virtual int GetUserConstraintId() const
virtual int GetUserConstraintId() const
{ {
return m_vehicle->getUserConstraintId(); return m_vehicle->getUserConstraintId();
} }
virtual int GetUserConstraintType() const virtual int GetUserConstraintType() const
{ {
return m_vehicle->getUserConstraintType(); return m_vehicle->getUserConstraintType();
} }
virtual void SetSteeringValue(float steering,int wheelIndex) virtual void SetSteeringValue(float steering, int wheelIndex)
{ {
m_vehicle->setSteeringValue(steering,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); 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); btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
info.m_brake = braking; 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); btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
info.m_frictionSlip = friction; 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); btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
info.m_suspensionStiffness = suspensionStiffness; 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); btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
info.m_wheelsDampingRelaxation = suspensionDamping; 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); btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
info.m_wheelsDampingCompression = suspensionCompression; 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); btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex);
info.m_rollInfluence = rollInfluence; 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); m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex);
} }
}; };
class BlenderVehicleRaycaster: public btDefaultVehicleRaycaster class BlenderVehicleRaycaster: public btDefaultVehicleRaycaster
{ {
btDynamicsWorld* m_dynamicsWorld; btDynamicsWorld *m_dynamicsWorld;
public: public:
BlenderVehicleRaycaster(btDynamicsWorld* world) BlenderVehicleRaycaster(btDynamicsWorld *world)
:btDefaultVehicleRaycaster(world), m_dynamicsWorld(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); btCollisionWorld::ClosestRayResultCallback rayCallback(from,to);
// We override btDefaultVehicleRaycaster so we can set this flag, otherwise our // We override btDefaultVehicleRaycaster so we can set this flag, otherwise our
@@ -319,12 +298,9 @@ public:
m_dynamicsWorld->rayTest(from, to, rayCallback); m_dynamicsWorld->rayTest(from, to, rayCallback);
if (rayCallback.hasHit()) if (rayCallback.hasHit()) {
{
const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
if (body && body->hasContactResponse()) if (body && body->hasContactResponse()) {
{
result.m_hitPointInWorld = rayCallback.m_hitPointWorld; result.m_hitPointInWorld = rayCallback.m_hitPointWorld;
result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld; result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld;
result.m_hitNormalInWorld.normalize(); result.m_hitNormalInWorld.normalize();
@@ -335,7 +311,7 @@ public:
return 0; return 0;
} }
}; };
#endif //NEW_BULLET_VEHICLE_SUPPORT
class CcdOverlapFilterCallBack : public btOverlapFilterCallback class CcdOverlapFilterCallBack : public btOverlapFilterCallback
{ {
@@ -1967,10 +1943,7 @@ void CcdPhysicsEnvironment::MergeEnvironment(PHY_IPhysicsEnvironment *other_env)
CcdPhysicsEnvironment::~CcdPhysicsEnvironment() CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
{ {
#ifdef NEW_BULLET_VEHICLE_SUPPORT
m_wrapperVehicles.clear(); m_wrapperVehicles.clear();
#endif //NEW_BULLET_VEHICLE_SUPPORT
//m_broadphase->DestroyScene(); //m_broadphase->DestroyScene();
//delete broadphase ? release reference on broadphase ? //delete broadphase ? release reference on broadphase ?
@@ -2373,16 +2346,14 @@ bool CcdOverlapFilterCallBack::needBroadphaseCollision(btBroadphaseProxy* proxy0
} }
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//complex constraint for vehicles //complex constraint for vehicles
PHY_IVehicle* CcdPhysicsEnvironment::GetVehicleConstraint(int constraintId) PHY_IVehicle* CcdPhysicsEnvironment::GetVehicleConstraint(int constraintId)
{ {
int i; int i;
int numVehicles = m_wrapperVehicles.size(); int numVehicles = m_wrapperVehicles.size();
for (i=0;i<numVehicles;i++)
{ for (i=0; i<numVehicles; i++) {
WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i];
if (wrapperVehicle->GetVehicle()->getUserConstraintId() == constraintId) if (wrapperVehicle->GetVehicle()->getUserConstraintId() == constraintId)
return wrapperVehicle; return wrapperVehicle;
@@ -2391,8 +2362,6 @@ PHY_IVehicle* CcdPhysicsEnvironment::GetVehicleConstraint(int constraintId)
return 0; return 0;
} }
#endif //NEW_BULLET_VEHICLE_SUPPORT
PHY_ICharacter* CcdPhysicsEnvironment::GetCharacterController(KX_GameObject *ob) PHY_ICharacter* CcdPhysicsEnvironment::GetCharacterController(KX_GameObject *ob)
{ {
@@ -2865,7 +2834,6 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
return hinge->getUserConstraintId(); return hinge->getUserConstraintId();
break; break;
} }
#ifdef NEW_BULLET_VEHICLE_SUPPORT
case PHY_VEHICLE_CONSTRAINT: case PHY_VEHICLE_CONSTRAINT:
{ {
@@ -2882,7 +2850,6 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
break; break;
}; };
#endif //NEW_BULLET_VEHICLE_SUPPORT
default: default:
{ {
@@ -3039,6 +3006,7 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
bool isbulletdyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;; bool isbulletdyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;;
bool isbulletsensor = (blenderobject->gameflag & OB_SENSOR) != 0; bool isbulletsensor = (blenderobject->gameflag & OB_SENSOR) != 0;
bool isbulletchar = (blenderobject->gameflag & OB_CHARACTER) != 0; bool isbulletchar = (blenderobject->gameflag & OB_CHARACTER) != 0;
bool isbulletvehicle = (blenderobject->gameflag & OB_VEHICLE) != 0;
bool isbulletsoftbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0; bool isbulletsoftbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
bool isbulletrigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0; bool isbulletrigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
bool useGimpact = false; bool useGimpact = false;
@@ -3065,7 +3033,7 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
{ {
ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; 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; 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; bounds = OB_BOUND_TRIANGLE_MESH;
else if (blenderobject->gameflag & OB_CHARACTER) else if (blenderobject->gameflag & OB_CHARACTER)
bounds = OB_BOUND_SPHERE; bounds = OB_BOUND_SPHERE;
else if (blenderobject->gameflag & OB_VEHICLE)
bounds = OB_BOUND_BOX;
} }
else else
{ {
@@ -3455,19 +3425,20 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
ci.m_collisionFilterGroup = ci.m_collisionFilterGroup =
(isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) : (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) :
(isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) :
(isbulletchar) ? short(CcdConstructionInfo::CharacterFilter) : (isbulletchar || isbulletvehicle) ? short(CcdConstructionInfo::CharacterFilter) :
short(CcdConstructionInfo::StaticFilter); short(CcdConstructionInfo::StaticFilter);
ci.m_collisionFilterMask = ci.m_collisionFilterMask =
(isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) : (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) :
(isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) :
(isbulletchar) ? short(CcdConstructionInfo::AllFilter) : (isbulletchar || isbulletvehicle) ? short(CcdConstructionInfo::AllFilter) :
short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
ci.m_bRigid = isbulletdyna && isbulletrigidbody; ci.m_bRigid = isbulletdyna && isbulletrigidbody;
ci.m_bSoft = isbulletsoftbody; ci.m_bSoft = isbulletsoftbody;
ci.m_bDyna = isbulletdyna; ci.m_bDyna = isbulletdyna;
ci.m_bSensor = isbulletsensor; ci.m_bSensor = isbulletsensor;
ci.m_bCharacter = isbulletchar; ci.m_bCharacter = isbulletchar;
ci.m_bVehicle = isbulletvehicle;
ci.m_bGimpact = useGimpact; ci.m_bGimpact = useGimpact;
MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]); ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);

View File

@@ -39,9 +39,6 @@ class btCollisionDispatcher;
class btDispatcher; class btDispatcher;
//#include "btBroadphaseInterface.h" //#include "btBroadphaseInterface.h"
//switch on/off new vehicle support
#define NEW_BULLET_VEHICLE_SUPPORT 1
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
class WrapperVehicle; class WrapperVehicle;
@@ -176,16 +173,8 @@ protected:
virtual void CallbackTriggers(); 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 // Character physics wrapper
virtual PHY_ICharacter* GetCharacterController(class KX_GameObject* ob); virtual PHY_ICharacter* GetCharacterController(class KX_GameObject* ob);

View File

@@ -14,8 +14,8 @@
class PHY_ICharacter class PHY_ICharacter
{ {
public: public:
virtual ~PHY_ICharacter(){}; virtual ~PHY_ICharacter(){}
virtual void Jump()= 0; virtual void Jump()= 0;
virtual bool OnGround()= 0; virtual bool OnGround()= 0;

View File

@@ -18,7 +18,7 @@ class PHY_IMotionState;
class PHY_IVehicle class PHY_IVehicle
{ {
public: public:
virtual ~PHY_IVehicle(){}; virtual ~PHY_IVehicle(){}
virtual void AddWheel( virtual void AddWheel(
PHY_IMotionState* motionState, PHY_IMotionState* motionState,

View File

@@ -31,16 +31,12 @@
#include "SG_Controller.h" #include "SG_Controller.h"
void void SG_Controller::SetObject(SG_IObject* obj)
SG_Controller::
SetObject(SG_IObject* obj)
{ {
m_pObject = obj; // no checks yet ? m_pObject = obj; // no checks yet ?
} }
void void SG_Controller::ClearObject()
SG_Controller:: {
ClearObject(
) {
m_pObject = NULL; m_pObject = NULL;
} }

View File

@@ -40,45 +40,24 @@
/** /**
* A scenegraph controller * A scenegraph controller
*/ */
class SG_Controller class SG_Controller
{ {
public: public:
SG_Controller( SG_Controller():
) : m_pObject(NULL)
m_pObject(NULL) { {}
}
virtual virtual ~SG_Controller() {}
~SG_Controller(
) {};
virtual virtual bool Update(double time)=0;
bool
Update(
double time
)=0;
virtual virtual void SetObject (SG_IObject* object);
void
SetObject (
SG_IObject* object
);
void void ClearObject();
ClearObject(
);
virtual virtual void SetSimulatedTime(double time)=0;
void
SetSimulatedTime(
double time
)=0;
virtual virtual SG_Controller* GetReplica(class SG_Node* destnode)=0;
SG_Controller*
GetReplica(
class SG_Node* destnode
)=0;
/** /**
* Hacky way of passing options to specific controllers * Hacky way of passing options to specific controllers
@@ -89,12 +68,7 @@ public:
* \attention necessary because the identity of the controller * \attention necessary because the identity of the controller
* \attention is lost on the way here. * \attention is lost on the way here.
*/ */
virtual virtual void SetOption(int option, int value)=0;
void
SetOption(
int option,
int value
)=0;
/** /**
* Option-identifiers: SG_CONTR_<controller-type>_<option>. * Option-identifiers: SG_CONTR_<controller-type>_<option>.
@@ -114,7 +88,7 @@ public:
}; };
protected: protected:
SG_IObject* m_pObject; SG_IObject* m_pObject;
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_Controller") MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_Controller")

View File

@@ -37,12 +37,7 @@
SG_Stage gSG_Stage = SG_STAGE_UNKNOWN; SG_Stage gSG_Stage = SG_STAGE_UNKNOWN;
SG_IObject:: SG_IObject::SG_IObject(void* clientobj, void* clientinfo, SG_Callbacks& callbacks):
SG_IObject(
void* clientobj,
void* clientinfo,
SG_Callbacks& callbacks
):
SG_QList(), SG_QList(),
m_SGclientObject(clientobj), m_SGclientObject(clientobj),
m_SGclientInfo(clientinfo) m_SGclientInfo(clientinfo)
@@ -50,10 +45,7 @@ SG_IObject(
m_callbacks = callbacks; m_callbacks = callbacks;
} }
SG_IObject:: SG_IObject::SG_IObject(const SG_IObject &other):
SG_IObject(
const SG_IObject &other
) :
SG_QList(), SG_QList(),
m_SGclientObject(other.m_SGclientObject), m_SGclientObject(other.m_SGclientObject),
m_SGclientInfo(other.m_SGclientInfo), m_SGclientInfo(other.m_SGclientInfo),
@@ -62,28 +54,17 @@ SG_IObject(
//nothing to do //nothing to do
} }
void void SG_IObject::AddSGController(SG_Controller* cont) {
SG_IObject::
AddSGController(
SG_Controller* cont
) {
m_SGcontrollers.push_back(cont); m_SGcontrollers.push_back(cont);
} }
void void SG_IObject::RemoveSGController(SG_Controller* cont)
SG_IObject:: {
RemoveSGController(
SG_Controller* cont
) {
SGControllerList::iterator contit;
m_SGcontrollers.erase(std::remove(m_SGcontrollers.begin(), m_SGcontrollers.end(), cont)); m_SGcontrollers.erase(std::remove(m_SGcontrollers.begin(), m_SGcontrollers.end(), cont));
} }
void void SG_IObject::RemoveAllControllers()
SG_IObject:: {
RemoveAllControllers(
) {
m_SGcontrollers.clear(); m_SGcontrollers.clear();
} }
@@ -98,9 +79,7 @@ void SG_IObject::SetControllerTime(double time)
/// Needed for replication /// Needed for replication
SG_IObject::~SG_IObject()
SG_IObject::
~SG_IObject()
{ {
SGControllerList::iterator contit; SGControllerList::iterator contit;

View File

@@ -63,7 +63,6 @@ inline void SG_SetActiveStage(SG_Stage stage)
{ {
gSG_Stage = stage; gSG_Stage = stage;
} }
class SG_Controller; class SG_Controller;
@@ -103,20 +102,22 @@ typedef bool (*SG_RescheduleUpdateCallback)(
/** /**
* SG_Callbacks hold 2 call backs to the outside world. * SG_ReplicationNewCallback is meant to be called when objects are replicated.
* The first is meant to be called when objects are replicated.
* And allows the outside world to synchronize external objects * And allows the outside world to synchronize external objects
* with replicated nodes and their children. * with replicated nodes and their children.
* The second is called when a node is destroyed and again *
* is their for synchronization purposes * SG_DestructionNewCallback is called when a node is destroyed and again
* These callbacks may both be NULL. * is for synchronization purposes
* The efficacy of this approach has not been proved some *
* alternatives might be to perform all replication and destruction * These callbacks may be NULL.
* externally. * The efficacy of this approach has not been proved.
* To define a class interface rather than a simple function * Some alternatives might be
* call back so that replication information can be transmitted from * 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. * parent->child.
*/ */
struct SG_Callbacks struct SG_Callbacks
{ {
SG_Callbacks( SG_Callbacks(
@@ -173,21 +174,14 @@ public:
* responsibility of this class. It will be deleted when * responsibility of this class. It will be deleted when
* this object is deleted. * this object is deleted.
*/ */
void AddSGController(SG_Controller* cont);
void
AddSGController(
SG_Controller* cont
);
/** /**
* Remove a pointer to a controller from this node. * Remove a pointer to a controller from this node.
* This does not delete the controller itself! Be careful to * This does not delete the controller itself! Be careful to
* avoid memory leaks. * avoid memory leaks.
*/ */
void void RemoveSGController(SG_Controller* cont);
RemoveSGController(
SG_Controller* cont
);
/** /**
* Clear the array of pointers to controllers associated with * Clear the array of pointers to controllers associated with
@@ -195,10 +189,7 @@ public:
* This should be used very carefully to avoid memory * This should be used very carefully to avoid memory
* leaks. * leaks.
*/ */
void RemoveAllControllers();
void
RemoveAllControllers(
);
/// Needed for replication /// Needed for replication
@@ -279,17 +270,10 @@ public:
void SetControllerTime(double time); void SetControllerTime(double time);
virtual virtual void Destruct() = 0;
void
Destruct(
) = 0;
protected : protected :
bool ActivateReplicationCallback(SG_IObject *replica)
bool
ActivateReplicationCallback(
SG_IObject *replica
)
{ {
if (m_callbacks.m_replicafunc) if (m_callbacks.m_replicafunc)
{ {
@@ -301,9 +285,7 @@ protected :
} }
void void ActivateDestructionCallback()
ActivateDestructionCallback(
)
{ {
if (m_callbacks.m_destructionfunc) if (m_callbacks.m_destructionfunc)
{ {
@@ -317,9 +299,7 @@ protected :
} }
} }
void void ActivateUpdateTransformCallback()
ActivateUpdateTransformCallback(
)
{ {
if (m_callbacks.m_updatefunc) if (m_callbacks.m_updatefunc)
{ {
@@ -328,9 +308,7 @@ protected :
} }
} }
bool bool ActivateScheduleUpdateCallback()
ActivateScheduleUpdateCallback(
)
{ {
// HACK, this check assumes that the scheduled nodes are put on a DList (see SG_Node.h) // 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 // The early check on Empty() allows up to avoid calling the callback function
@@ -343,9 +321,7 @@ protected :
return false; return false;
} }
void void ActivateRecheduleUpdateCallback()
ActivateRecheduleUpdateCallback(
)
{ {
if (m_callbacks.m_reschedulefunc) if (m_callbacks.m_reschedulefunc)
{ {

View File

@@ -37,21 +37,14 @@
using namespace std; using namespace std;
SG_Node::SG_Node( SG_Node::SG_Node(void* clientobj, void* clientinfo, SG_Callbacks& callbacks):
void* clientobj, SG_Spatial(clientobj,clientinfo,callbacks),
void* clientinfo,
SG_Callbacks& callbacks
)
: SG_Spatial(clientobj,clientinfo,callbacks),
m_SGparent(NULL) m_SGparent(NULL)
{ {
m_modified = true; m_modified = true;
} }
SG_Node::SG_Node( SG_Node::SG_Node(const SG_Node & other):
const SG_Node & other
) :
SG_Spatial(other), SG_Spatial(other),
m_children(other.m_children), m_children(other.m_children),
m_SGparent(other.m_SGparent) m_SGparent(other.m_SGparent)
@@ -74,11 +67,8 @@ SG_Node* SG_Node::GetSGReplica()
return replica; return replica;
} }
void void SG_Node::ProcessSGReplica(SG_Node** replica)
SG_Node:: {
ProcessSGReplica(
SG_Node** replica
) {
// Apply the replication call back function. // Apply the replication call back function.
if (!ActivateReplicationCallback(*replica)) if (!ActivateReplicationCallback(*replica))
{ {
@@ -115,10 +105,7 @@ ProcessSGReplica(
} }
} }
void SG_Node::Destruct()
void
SG_Node::
Destruct()
{ {
// Not entirely sure what Destruct() expects to happen. // Not entirely sure what Destruct() expects to happen.
// I think it probably means just to call the DestructionCallback // I think it probably means just to call the DestructionCallback
@@ -142,11 +129,8 @@ Destruct()
ActivateDestructionCallback(); ActivateDestructionCallback();
} }
const const SG_Node* SG_Node::GetRootSGParent() const
SG_Node * {
SG_Node::
GetRootSGParent(
) const {
return (m_SGparent ? (const SG_Node*) m_SGparent->GetRootSGParent() : (const SG_Node*) this); 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); (child->m_SGparent == this) ? true : IsAncessor(child->m_SGparent);
} }
void void SG_Node::DisconnectFromParent()
SG_Node:: {
DisconnectFromParent(
) {
if (m_SGparent) if (m_SGparent)
{ {
m_SGparent->RemoveChild(this); m_SGparent->RemoveChild(this);
@@ -188,9 +170,6 @@ void SG_Node::RemoveChild(SG_Node* child)
void SG_Node::UpdateWorldData(double time, bool parentUpdated) void SG_Node::UpdateWorldData(double time, bool parentUpdated)
{ {
//if (!GetSGParent())
// return;
if (UpdateSpatialData(GetSGParent(),time,parentUpdated)) if (UpdateSpatialData(GetSGParent(),time,parentUpdated))
// to update the // to update the
ActivateUpdateTransformCallback(); ActivateUpdateTransformCallback();
@@ -209,7 +188,6 @@ void SG_Node::UpdateWorldData(double time, bool parentUpdated)
void SG_Node::SetSimulatedTime(double time,bool recurse) void SG_Node::SetSimulatedTime(double time,bool recurse)
{ {
// update the controllers of this node. // update the controllers of this node.
SetControllerTime(time); SetControllerTime(time);
@@ -223,5 +201,3 @@ void SG_Node::SetSimulatedTime(double time,bool recurse)
} }
} }

View File

@@ -43,19 +43,11 @@ typedef std::vector<SG_Node*> NodeList;
class SG_Node : public SG_Spatial class SG_Node : public SG_Spatial
{ {
public: public:
SG_Node( SG_Node(void* clientobj, void* clientinfo, SG_Callbacks& callbacks);
void* clientobj, SG_Node(const SG_Node & other);
void* clientinfo,
SG_Callbacks& callbacks
);
SG_Node(
const SG_Node & other
);
virtual ~SG_Node(); virtual ~SG_Node();
/** /**
* Add a child to this object. This also informs the child of * Add a child to this object. This also informs the child of
* it's parent. * it's parent.
@@ -63,10 +55,7 @@ public:
* make a deep copy. * make a deep copy.
*/ */
void void AddChild(SG_Node* child);
AddChild(
SG_Node* child
);
/** /**
* Remove a child node from this object. This just removes the 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. * 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. * 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 * Return true if the node is the ancestor of child
*/ */
bool bool IsAncessor(const SG_Node* child) const;
IsAncessor(
const SG_Node* child
) const;
/** /**
* Get the current list of children. Do not use this interface for * Get the current list of children. Do not use this interface for
* adding or removing children please use the methods of this class for * adding or removing children please use the methods of this class for
* that. * that.
* \return a reference to the list of children of this node. * \return a reference to the list of children of this node.
*/ */
NodeList& GetSGChildren() NodeList& GetSGChildren()
{ {
return this->m_children; return this->m_children;
@@ -103,7 +85,6 @@ public:
* Get the current list of children. * Get the current list of children.
* \return a const reference to the current list of children of this node. * \return a const reference to the current list of children of this node.
*/ */
const NodeList& GetSGChildren() const const NodeList& GetSGChildren() const
{ {
return this->m_children; return this->m_children;
@@ -112,7 +93,6 @@ public:
/** /**
* Clear the list of children associated with this node * Clear the list of children associated with this node
*/ */
void ClearSGChildren() void ClearSGChildren()
{ {
m_children.clear(); m_children.clear();
@@ -130,7 +110,6 @@ public:
/** /**
* Set the parent of this node. * Set the parent of this node.
*/ */
void SetSGParent(SG_Node* parent) void SetSGParent(SG_Node* parent)
{ {
m_SGparent = parent; m_SGparent = parent;
@@ -139,19 +118,12 @@ public:
/** /**
* Return the top node in this node's Scene graph hierarchy * 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 * Disconnect this node from it's parent
*/ */
void DisconnectFromParent();
void
DisconnectFromParent(
);
/** /**
* Return vertex parent status. * Return vertex parent status.
@@ -165,11 +137,9 @@ public:
return false; return false;
} }
/** /**
* Return slow parent status. * Return slow parent status.
*/ */
bool IsSlowParent() bool IsSlowParent()
{ {
if (m_parent_relation) if (m_parent_relation)
@@ -180,29 +150,17 @@ public:
} }
/** /**
* Update the spatial data of this node. Iterate through * Update the spatial data of this node. Iterate through
* the children of this node and update their world data. * 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 * Update the simulation time of this node. Iterate through
* the children nodes and update their simulated time. * 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 * Schedule this node for update by placing it in head queue
@@ -243,21 +201,12 @@ public:
/** /**
* Node replication functions. * Node replication functions.
*/ */
SG_Node* GetSGReplica();
SG_Node* void Destruct();
GetSGReplica(
);
void
Destruct(
);
private: private:
void ProcessSGReplica(SG_Node** replica);
void
ProcessSGReplica(
SG_Node** replica
);
/** /**
* The list of children of this node. * The list of children of this node.

View File

@@ -32,17 +32,18 @@
* *
* \section SG_ParentRelationSection SG_ParentRelation * \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. * It allows you to specify how child nodes react to parent nodes.
*
* Normally a child will use it's parent's transforms to compute * Normally a child will use it's parent's transforms to compute
* it's own global transforms. How this is performed depends on * its own global transforms. How this is performed depends on
* the type of relation. For example if the parent is a vertex * the type of relation. For example if the parent is a vertex
* parent to this child then the child should not inherit any * parent to this child then the child should only inherit
* rotation information from the parent. Or if the parent is a * location information from the parent. Or if the parent is a
* 'slow parent' to this child then the child should react * 'slow parent' to this child then the child should react
* slowly to changes in the parent's position. The exact relation * slowly to changes in the parent's position. The exact relation
* is left for you to implement by filling out this interface * is left for you to implement by filling out this interface
* with concrete examples. * with concrete examples.
* *
* There is exactly one SG_ParentRelation per SG_Node. Subclasses * There is exactly one SG_ParentRelation per SG_Node. Subclasses
* should not be value types and should be allocated on the heap. * should not be value types and should be allocated on the heap.
@@ -57,26 +58,16 @@ class SG_Spatial;
class SG_ParentRelation { class SG_ParentRelation {
public : 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 * You must provide a way of duplicating an
@@ -85,55 +76,41 @@ public :
* on the heap. Responsibility for deleting the * on the heap. Responsibility for deleting the
* duplicate resides with the caller of this method. * 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 * Vertex Parent Relation are special: they don't propagate rotation
*/ */
virtual virtual bool IsVertexRelation()
bool {
IsVertexRelation(
) {
return false; return false;
} }
/** /**
* Need this to see if we are able to adjust time-offset from the python api * Need this to see if we are able to adjust time-offset from the python api
*/ */
virtual virtual bool IsSlowRelation()
bool {
IsSlowRelation(
) {
return false; return false;
} }
protected : protected :
/** /**
* Protected constructors * Protected constructors this class is not meant to be instantiated.
* this class is not meant to be instantiated.
*/ */
SG_ParentRelation() {}
SG_ParentRelation(
) {
};
/** /**
* Copy construction should not be implemented * Copy construction should not be implemented
*/ */
SG_ParentRelation(const SG_ParentRelation &);
SG_ParentRelation(
const SG_ParentRelation &
);
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_ParentRelation") MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_ParentRelation")
#endif #endif
}; };
#endif #endif /* __SG_PARENTRELATION_H__ */

View File

@@ -35,46 +35,36 @@
#include "SG_Controller.h" #include "SG_Controller.h"
#include "SG_ParentRelation.h" #include "SG_ParentRelation.h"
SG_Spatial:: SG_Spatial::SG_Spatial(void* clientobj, void* clientinfo, SG_Callbacks& callbacks):
SG_Spatial(
void* clientobj,
void* clientinfo,
SG_Callbacks& callbacks
):
SG_IObject(clientobj,clientinfo,callbacks), SG_IObject(clientobj,clientinfo,callbacks),
m_localPosition(0.0,0.0,0.0), 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_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_localScaling(1.f,1.f,1.f),
m_worldPosition(0.0,0.0,0.0), 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_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_worldScaling(1.f,1.f,1.f),
m_parent_relation (NULL), m_parent_relation (NULL),
m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)), m_bbox(MT_Point3(-1.0, -1.0, -1.0), MT_Point3(1.0, 1.0, 1.0)),
m_radius(1.0), m_radius(1.0),
m_modified(false), m_modified(false),
m_ogldirty(false) m_ogldirty(false)
{ {}
}
SG_Spatial:: SG_Spatial::SG_Spatial(const SG_Spatial& other):
SG_Spatial(
const SG_Spatial& other
) :
SG_IObject(other), SG_IObject(other),
m_localPosition(other.m_localPosition), m_localPosition(other.m_localPosition),
m_localRotation(other.m_localRotation), m_localRotation(other.m_localRotation),
m_localScaling(other.m_localScaling), m_localScaling(other.m_localScaling),
m_worldPosition(other.m_worldPosition), m_worldPosition(other.m_worldPosition),
m_worldRotation(other.m_worldRotation), m_worldRotation(other.m_worldRotation),
m_worldScaling(other.m_worldScaling), m_worldScaling(other.m_worldScaling),
m_parent_relation(NULL), m_parent_relation(NULL),
m_bbox(other.m_bbox), m_bbox(other.m_bbox),
m_radius(other.m_radius), m_radius(other.m_radius),
m_modified(false), m_modified(false),
@@ -83,18 +73,13 @@ SG_Spatial(
// duplicate the parent relation for this object // duplicate the parent relation for this object
m_parent_relation = other.m_parent_relation->NewCopy(); m_parent_relation = other.m_parent_relation->NewCopy();
} }
SG_Spatial:: SG_Spatial::~SG_Spatial()
~SG_Spatial()
{ {
delete (m_parent_relation); delete (m_parent_relation);
} }
void void SG_Spatial::SetParentRelation(SG_ParentRelation *relation) {
SG_Spatial::
SetParentRelation(
SG_ParentRelation *relation
) {
delete (m_parent_relation); delete (m_parent_relation);
m_parent_relation = relation; m_parent_relation = relation;
SetModified(); SetModified();
@@ -107,20 +92,13 @@ SetParentRelation(
*/ */
bool bool SG_Spatial::UpdateSpatialData(const SG_Spatial *parent, double time, bool& parentUpdated)
SG_Spatial::
UpdateSpatialData(
const SG_Spatial *parent,
double time,
bool& parentUpdated)
{ {
bool bComputesWorldTransform = false; bool bComputesWorldTransform = false;
// update spatial controllers // update spatial controllers
SGControllerList::iterator cit = GetSGControllerList().begin(); SGControllerList::iterator cit = GetSGControllerList().begin();
SGControllerList::const_iterator c_end = GetSGControllerList().end(); SGControllerList::const_iterator c_end = GetSGControllerList().end();
for (;cit!=c_end;++cit) for (;cit!=c_end;++cit)
{ {
if ((*cit)->Update(time)) if ((*cit)->Update(time))
@@ -130,71 +108,39 @@ UpdateSpatialData(
// If none of the objects updated our values then we ask the // If none of the objects updated our values then we ask the
// parent_relation object owned by this class to update // parent_relation object owned by this class to update
// our world coordinates. // our world coordinates.
if (!bComputesWorldTransform) if (!bComputesWorldTransform)
bComputesWorldTransform = ComputeWorldTransforms(parent, parentUpdated); bComputesWorldTransform = ComputeWorldTransforms(parent, parentUpdated);
return bComputesWorldTransform; return bComputesWorldTransform;
} }
/**
* Position and translation methods
*/
void void SG_Spatial::RelativeTranslate(const MT_Vector3& trans, bool local)
SG_Spatial:: {
RelativeTranslate(
const MT_Vector3& trans,
const SG_Spatial *parent,
bool local
) {
if (local) { if (local) {
m_localPosition += m_localRotation * trans; m_localPosition += m_localScaling * (m_localRotation * trans);
} } else {
else { m_localPosition += trans;
if (parent) {
m_localPosition += trans * parent->GetWorldOrientation();
}
else {
m_localPosition += trans;
}
} }
SetModified(); SetModified();
} }
void SG_Spatial::RelativeRotate(const MT_Matrix3x3& rot, bool local) {
/**
* Scaling methods.
*/
/**
* Orientation and rotation methods.
*/
void
SG_Spatial::
RelativeRotate(
const MT_Matrix3x3& rot,
bool local
) {
m_localRotation = m_localRotation * ( m_localRotation = m_localRotation * (
local ? local ?
rot rot:
: (GetWorldOrientation().inverse() * rot * GetWorldOrientation()));
(GetWorldOrientation().inverse() * rot * GetWorldOrientation()));
SetModified(); SetModified();
} }
MT_Transform SG_Spatial::GetWorldTransform() const MT_Transform SG_Spatial::GetWorldTransform() const
{ {
return MT_Transform(m_worldPosition, return MT_Transform(m_worldPosition,
m_worldRotation.scaled( m_worldRotation.scaled(m_worldScaling[0], m_worldScaling[1], m_worldScaling[2]));
m_worldScaling[0], m_worldScaling[1], m_worldScaling[2]));
} }
bool SG_Spatial::inside(const MT_Point3 &point) const bool SG_Spatial::inside(const MT_Point3 &point) const

View File

@@ -53,11 +53,11 @@ class SG_Spatial : public SG_IObject
protected: protected:
MT_Point3 m_localPosition; MT_Point3 m_localPosition;
MT_Matrix3x3 m_localRotation; MT_Matrix3x3 m_localRotation;
MT_Vector3 m_localScaling; MT_Vector3 m_localScaling;
MT_Point3 m_worldPosition; MT_Point3 m_worldPosition;
MT_Matrix3x3 m_worldRotation; MT_Matrix3x3 m_worldRotation;
MT_Vector3 m_worldScaling; MT_Vector3 m_worldScaling;
SG_ParentRelation * m_parent_relation; SG_ParentRelation * m_parent_relation;
@@ -82,7 +82,8 @@ public:
{ {
m_ogldirty = false; m_ogldirty = false;
} }
/**
/**
* Define the relationship this node has with it's parent * Define the relationship this node has with it's parent
* node. You should pass an unshared instance of an SG_ParentRelation * node. You should pass an unshared instance of an SG_ParentRelation
* allocated on the heap to this method. Ownership of this * 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 * The relation is activated only if no controllers of this object
* updated the coordinates of the child. * updated the coordinates of the child.
*/ */
void SetParentRelation(SG_ParentRelation *relation);
void
SetParentRelation(
SG_ParentRelation *relation
);
SG_ParentRelation * GetParentRelation() SG_ParentRelation * GetParentRelation()
{ {
return m_parent_relation; return m_parent_relation;
@@ -111,19 +107,10 @@ public:
/** /**
* Apply a translation relative to the current position. * Apply a translation relative to the current position.
* if local then the translation is assumed to be in the * If local then the translation is assumed to be in the local coordinates of this object.
* local coordinates of this object. If not then the translation * If not then the translation is assumed to be in global coordinates.
* 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
*/ */
void RelativeTranslate(const MT_Vector3& trans, bool local);
void
RelativeTranslate(
const MT_Vector3& trans,
const SG_Spatial *parent,
bool local
);
void SetLocalPosition(const MT_Point3& trans) void SetLocalPosition(const MT_Point3& trans)
{ {
@@ -136,12 +123,7 @@ public:
m_worldPosition = trans; 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) void SetLocalOrientation(const MT_Matrix3x3& rot)
{ {
@@ -242,7 +224,7 @@ public:
bool inside(const MT_Point3 &point) const; bool inside(const MT_Point3 &point) const;
void getBBox(MT_Point3 *box) const; void getBBox(MT_Point3 *box) const;
void getAABBox(MT_Point3 *box) const; void getAABBox(MT_Point3 *box) const;
MT_Scalar Radius() const { return m_radius; } MT_Scalar Radius() const { return m_radius; }
void SetRadius(MT_Scalar radius) { m_radius = radius; } void SetRadius(MT_Scalar radius) { m_radius = radius; }
bool IsModified() { return m_modified; } bool IsModified() { return m_modified; }
@@ -260,16 +242,8 @@ protected:
* designed for direct instantiation * designed for direct instantiation
*/ */
SG_Spatial( SG_Spatial(void* clientobj, void* clientinfo, SG_Callbacks& callbacks);
void* clientobj, SG_Spatial(const SG_Spatial& other);
void* clientinfo,
SG_Callbacks& callbacks
);
SG_Spatial(
const SG_Spatial& other
);
virtual ~SG_Spatial(); virtual ~SG_Spatial();
@@ -278,12 +252,7 @@ protected:
* any controllers to update this object. * any controllers to update this object.
*/ */
bool bool UpdateSpatialData(const SG_Spatial *parent, double time, bool& parentUpdated);
UpdateSpatialData(
const SG_Spatial *parent,
double time,
bool& parentUpdated
);
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC

View File

@@ -28,14 +28,14 @@
/** \file SG_Tree.h /** \file SG_Tree.h
* \ingroup bgesg * \ingroup bgesg
*/ */
#ifndef __SG_TREE_H__ #ifndef __SG_TREE_H__
#define __SG_TREE_H__ #define __SG_TREE_H__
#include "MT_Point3.h" #include "MT_Point3.h"
#include "SG_BBox.h" #include "SG_BBox.h"
#include <set> #include <set>
class SG_Node; class SG_Node;
@@ -56,27 +56,27 @@ class SG_Tree
public: public:
SG_Tree(); SG_Tree();
SG_Tree(SG_Tree* left, SG_Tree* right); SG_Tree(SG_Tree* left, SG_Tree* right);
SG_Tree(SG_Node* client); SG_Tree(SG_Node* client);
~SG_Tree(); ~SG_Tree();
/** /**
* Computes the volume of the bounding box. * Computes the volume of the bounding box.
*/ */
MT_Scalar volume() const; MT_Scalar volume() const;
/** /**
* Prints the tree (for debugging.) * Prints the tree (for debugging.)
*/ */
void dump() const; void dump() const;
/** /**
* Returns the left node. * Returns the left node.
*/ */
SG_Tree *Left() const; SG_Tree *Left() const;
SG_Tree *Right() const; SG_Tree *Right() const;
SG_Node *Client() const; SG_Node *Client() const;
SG_Tree* Find(SG_Node *node); SG_Tree* Find(SG_Node *node);
/** /**
* Gets the eight corners of this treenode's bounding box, * Gets the eight corners of this treenode's bounding box,
@@ -101,9 +101,7 @@ public:
MT_Point3 Center() const { return m_center; } MT_Point3 Center() const { return m_center; }
MT_Scalar Radius() { return m_radius; } MT_Scalar Radius() { return m_radius; }
//friend class SG_TreeFactory;
struct greater struct greater
{ {
bool operator()(const SG_Tree *a, const SG_Tree *b) bool operator()(const SG_Tree *a, const SG_Tree *b)
@@ -111,9 +109,8 @@ public:
return a->volume() > b->volume(); return a->volume() > b->volume();
} }
}; };
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_Tree") MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_Tree")
#endif #endif
@@ -127,14 +124,14 @@ public:
* cf building an optimized Huffman tree. * cf building an optimized Huffman tree.
* \warning O(n^3)!!! * \warning O(n^3)!!!
*/ */
class SG_TreeFactory class SG_TreeFactory
{ {
typedef std::multiset<SG_Tree*, SG_Tree::greater> TreeSet; typedef std::multiset<SG_Tree*, SG_Tree::greater> TreeSet;
TreeSet m_objects; TreeSet m_objects;
public: public:
SG_TreeFactory(); SG_TreeFactory();
~SG_TreeFactory(); ~SG_TreeFactory();
/** /**
* Add a node to be added to the tree. * Add a node to be added to the tree.
*/ */
@@ -146,18 +143,18 @@ public:
* the Add method. * the Add method.
*/ */
SG_Tree* MakeTreeUp(); SG_Tree* MakeTreeUp();
/** /**
* Build the tree from the set of nodes top down. * Build the tree from the set of nodes top down.
*/ */
SG_Tree* MakeTreeDown(SG_BBox &bbox); SG_Tree* MakeTreeDown(SG_BBox &bbox);
SG_Tree* MakeTree(); SG_Tree* MakeTree();
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_TreeFactory") MEM_CXX_CLASS_ALLOC_FUNCS("GE:SG_TreeFactory")
#endif #endif
}; };
#endif /* __SG_BBOX_H__ */ #endif /* __SG_TREE_H__ */

View File

@@ -41,6 +41,7 @@
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_image_types.h" #include "DNA_image_types.h"
#include "IMB_imbuf_types.h" #include "IMB_imbuf_types.h"
#include "BKE_image.h"
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
@@ -158,6 +159,7 @@ static PyObject *Texture_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
// initialize object structure // initialize object structure
self->m_actTex = 0; self->m_actTex = 0;
self->m_orgSaved = false; self->m_orgSaved = false;
self->m_imgBuf = NULL;
self->m_imgTexture = NULL; self->m_imgTexture = NULL;
self->m_matTexture = NULL; self->m_matTexture = NULL;
self->m_mipmap = false; self->m_mipmap = false;
@@ -282,7 +284,11 @@ PyObject *Texture_close(Texture * self)
if (self->m_useMatTexture) if (self->m_useMatTexture)
self->m_matTexture->swapTexture(self->m_orgTex); self->m_matTexture->swapTexture(self->m_orgTex);
else else
{
self->m_imgTexture->bindcode = self->m_orgTex; 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 // drop actual texture
if (self->m_actTex != 0) 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); self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex);
else 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_orgTex = self->m_imgTexture->bindcode;
self->m_imgTexture->bindcode = self->m_actTex; self->m_imgTexture->bindcode = self->m_actTex;
} }

View File

@@ -43,6 +43,8 @@
#include "Exception.h" #include "Exception.h"
struct ImBuf;
// type Texture declaration // type Texture declaration
struct Texture struct Texture
{ {
@@ -58,6 +60,8 @@ struct Texture
// original texture saved // original texture saved
bool m_orgSaved; 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 // texture image for game materials
Image * m_imgTexture; Image * m_imgTexture;
// texture for blender materials // texture for blender materials

View File

@@ -157,10 +157,15 @@ static void registerAllTypes(void)
pyFilterTypes.add(&FilterBGR24Type, "FilterBGR24"); 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 = { static struct PyModuleDef VideoTexture_module_def = {
{}, /* m_base */ PyModuleDef_HEAD_INIT,
"VideoTexture", /* m_name */ "VideoTexture", /* m_name */
"Module that allows to play video files on textures in GameBlender.", /* m_doc */ VideoTexture_module_documentation, /* m_doc */
0, /* m_size */ 0, /* m_size */
moduleMethods, /* m_methods */ moduleMethods, /* m_methods */
0, /* m_reload */ 0, /* m_reload */
@@ -169,7 +174,7 @@ static struct PyModuleDef VideoTexture_module_def = {
0, /* m_free */ 0, /* m_free */
}; };
PyObject *initVideoTexture(void) PyMODINIT_FUNC initVideoTexturePythonBinding(void)
{ {
PyObject *m; PyObject *m;