1
1

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
# if some version control system is used.
PROJECT_NUMBER = "V2.6x"
PROJECT_NUMBER = "V2.7x"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer

View File

@@ -7,7 +7,7 @@
* These pages document the source code of blender.
*
* \subsection implinks Important Links
* - <a href="http://projects.blender.org">projects.blender.org</a> with <a href="http://projects.blender.org/tracker/index.php?group_id=9&atid=498">bug tracker</a>
* - <a href="http://developer.blender.org">developer.blender.org</a> with bug tracker
* - <a href="http://wiki.blender.org/index.php/Dev:Contents">Development documents</a> on our wiki.
*
* \subsection blother Other

View File

@@ -124,13 +124,13 @@ base class --- :class:`SCA_IObject`
.. attribute:: groupMembers
Returns the list of group members if the object is a group object, otherwise None is returned.
Returns the list of group members if the object is a group object (dupli group instance), otherwise None is returned.
:type: :class:`CListValue` of :class:`KX_GameObject` or None
.. attribute:: groupObject
Returns the group object that the object belongs to or None if the object is not part of a group.
Returns the group object (dupli group instance) that the object belongs to or None if the object is not part of a group.
:type: :class:`KX_GameObject` or None
@@ -876,4 +876,4 @@ base class --- :class:`SCA_IObject`
:arg name: name of the property that added to the debug list.
:type name: string
:arg debug: the debug state.
:type debug: boolean
:type debug: boolean

View File

@@ -8,19 +8,17 @@ This module wraps OpenGL constants and functions, making them available from
within Blender Python.
The complete list can be retrieved from the module itself, by listing its
contents: dir(bgl). A simple search on the net can point to more
contents: dir(bgl). A simple search on the web can point to more
than enough material to teach OpenGL programming, from books to many
collections of tutorials.
The "red book": "I{OpenGL Programming Guide: The Official Guide to Learning
OpenGL}" and the online NeHe tutorials are two of the best resources.
Here is a comprehensive `list of books <http://www.opengl.org/documentation/books/>`_ (non free). The `arcsynthesis tutorials <http://www.arcsynthesis.org/gltut/>`_ is one of the best resources to learn modern OpenGL and `g-truc <http://www.g-truc.net/post-tech-content-sample.html>`_ offers a set of extensive examples, including advanced features.
.. note::
You can use the :class:`Image` type to load and set textures.
See :class:`Image.gl_load` and :class:`Image.gl_load`,
for example.
`OpenGL.org <http://www.opengl.org>`_
`NeHe GameDev <http://nehe.gamedev.net>`_
.. function:: glAccum(op, value):

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, "fall_speed")
elif physics_type in {'DYNAMIC', 'RIGID_BODY'}:
elif physics_type in {'DYNAMIC', 'RIGID_BODY', 'VEHICLE'}:
split = layout.split()
col = split.column()
@@ -209,7 +209,7 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
def poll(cls, context):
game = context.object.game
rd = context.scene.render
return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC', 'CHARACTER'}) and (rd.engine in cls.COMPAT_ENGINES)
return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC', 'CHARACTER', 'VEHICLE'}) and (rd.engine in cls.COMPAT_ENGINES)
def draw_header(self, context):
game = context.active_object.game
@@ -226,8 +226,9 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
row = layout.row()
row.prop(game, "collision_margin", text="Margin", slider=True)
row.prop(game, "use_collision_compound", text="Compound")
sub = row.row()
sub.active = game.physics_type not in {'SOFT_BODY', 'CHARACTER', 'VEHICLE'}
sub.prop(game, "use_collision_compound", text="Compound")
class PHYSICS_PT_game_obstacles(PhysicsButtonsPanel, Panel):
bl_label = "Create Obstacle"

View File

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

View File

@@ -62,7 +62,8 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel):
layout.prop(scene, "camera")
layout.prop(scene, "background_set", text="Background")
layout.prop(scene, "active_clip", text="Active Clip")
if context.scene.render.engine != 'BLENDER_GAME':
layout.prop(scene, "active_clip", text="Active Clip")
class SCENE_PT_unit(SceneButtonsPanel, Panel):

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

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 */
if (type != OB_MESH) {
ob->body_type = OB_BODY_TYPE_NO_COLLISION;
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH); /* copied from rna_object.c */
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_VEHICLE | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH); /* copied from rna_object.c */
}
DAG_id_type_tag(bmain, ID_OB);

View File

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

View File

@@ -508,7 +508,9 @@ static EnumPropertyItem *rna_Object_collision_bounds_itemf(bContext *UNUSED(C),
EnumPropertyItem *item = NULL;
int totitem = 0;
RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_TRIANGLE_MESH);
if (ob->body_type != OB_BODY_TYPE_CHARACTER && ob->body_type != OB_BODY_TYPE_VEHICLE) {
RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_TRIANGLE_MESH);
}
RNA_enum_items_add_value(&item, &totitem, collision_bounds_items, OB_BOUND_CONVEX_HULL);
if (ob->body_type != OB_BODY_TYPE_SOFT) {
@@ -982,6 +984,9 @@ static int rna_GameObjectSettings_physics_type_get(PointerRNA *ptr)
else if (ob->gameflag & OB_CHARACTER) {
ob->body_type = OB_BODY_TYPE_CHARACTER;
}
else if (ob->gameflag & OB_VEHICLE) {
ob->body_type = OB_BODY_TYPE_VEHICLE;
}
else if (ob->gameflag & OB_SENSOR) {
ob->body_type = OB_BODY_TYPE_SENSOR;
}
@@ -1013,16 +1018,16 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value)
switch (ob->body_type) {
case OB_BODY_TYPE_SENSOR:
ob->gameflag |= OB_SENSOR | OB_COLLISION;
ob->gameflag &= ~(OB_OCCLUDER | OB_CHARACTER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
ob->gameflag &= ~(OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
break;
case OB_BODY_TYPE_OCCLUDER:
ob->gameflag |= OB_OCCLUDER;
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_DYNAMIC | OB_NAVMESH);
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_VEHICLE | OB_DYNAMIC | OB_NAVMESH);
break;
case OB_BODY_TYPE_NAVMESH:
ob->gameflag |= OB_NAVMESH;
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_DYNAMIC | OB_OCCLUDER);
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_VEHICLE | OB_DYNAMIC | OB_OCCLUDER);
if (ob->type == OB_MESH) {
/* could be moved into mesh UI but for now ensure mesh data layer */
@@ -1031,29 +1036,34 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value)
break;
case OB_BODY_TYPE_NO_COLLISION:
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH);
ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_VEHICLE | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH);
break;
case OB_BODY_TYPE_CHARACTER:
ob->gameflag |= OB_COLLISION | OB_CHARACTER;
ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_VEHICLE | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
break;
case OB_BODY_TYPE_VEHICLE:
ob->gameflag |= OB_COLLISION | OB_VEHICLE;
ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_CHARACTER | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
break;
case OB_BODY_TYPE_STATIC:
ob->gameflag |= OB_COLLISION;
ob->gameflag &= ~(OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH);
ob->gameflag &= ~(OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_SENSOR | OB_NAVMESH);
break;
case OB_BODY_TYPE_DYNAMIC:
ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_ACTOR;
ob->gameflag &= ~(OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH);
ob->gameflag &= ~(OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_SENSOR | OB_NAVMESH);
break;
case OB_BODY_TYPE_RIGID:
ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_RIGID_BODY | OB_ACTOR;
ob->gameflag &= ~(OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH);
ob->gameflag &= ~(OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_SENSOR | OB_NAVMESH);
break;
default:
case OB_BODY_TYPE_SOFT:
ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_SOFT_BODY | OB_ACTOR;
ob->gameflag &= ~(OB_RIGID_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH);
ob->gameflag &= ~(OB_RIGID_BODY | OB_OCCLUDER | OB_CHARACTER | OB_VEHICLE | OB_SENSOR | OB_NAVMESH);
/* assume triangle mesh, if no bounds chosen for soft body */
if ((ob->gameflag & OB_BOUNDS) && (ob->boundtype < OB_BOUND_TRIANGLE_MESH)) {
@@ -1638,6 +1648,8 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
{OB_BODY_TYPE_NAVMESH, "NAVMESH", 0, "Navigation Mesh", "Navigation mesh"},
{OB_BODY_TYPE_CHARACTER, "CHARACTER", 0, "Character",
"Simple kinematic physics appropriate for game characters"},
{OB_BODY_TYPE_VEHICLE, "VEHICLE", 0, "Vehicle",
"Simple kinematic physics appropriate for vehicles"},
{0, NULL, 0, NULL, NULL}
};
@@ -1735,7 +1747,9 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "max_vel");
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed");
/* Vehicle physics */
/* Character physics */
prop = RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "step_height");
@@ -1752,6 +1766,8 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall");
/* Collision Masks */
prop = RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1);

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
KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
ketsjiengine->SetSceneConverter(sceneconverter);
sceneconverter->addInitFromFrame=false;
if (always_use_expand_framing)
sceneconverter->SetAlwaysUseExpandFraming(true);

View File

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

View File

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

View File

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

View File

@@ -529,76 +529,59 @@ void KX_BlenderSceneConverter::CacheBlenderMaterial(KX_Scene *scene, struct Mate
m_mat_cache[scene][mat] = blmat;
}
BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(KX_Scene *scene, struct Material *mat)
{
return (m_use_mat_cache) ? m_mat_cache[scene][mat] : NULL;
}
void KX_BlenderSceneConverter::RegisterInterpolatorList(
BL_InterpolatorList *actList,
struct bAction *for_act)
void KX_BlenderSceneConverter::RegisterInterpolatorList(BL_InterpolatorList *actList, struct bAction *for_act)
{
m_map_blender_to_gameAdtList.insert(CHashedPtr(for_act), actList);
}
BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
struct bAction *for_act)
BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(struct bAction *for_act)
{
BL_InterpolatorList **listp = m_map_blender_to_gameAdtList[CHashedPtr(for_act)];
return listp?*listp:NULL;
}
void KX_BlenderSceneConverter::RegisterGameActuator(
SCA_IActuator *act,
struct bActuator *for_actuator)
void KX_BlenderSceneConverter::RegisterGameActuator(SCA_IActuator *act, struct bActuator *for_actuator)
{
m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
}
SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
struct bActuator *for_actuator)
SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(struct bActuator *for_actuator)
{
SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
return actp?*actp:NULL;
}
void KX_BlenderSceneConverter::RegisterGameController(
SCA_IController *cont,
struct bController *for_controller)
void KX_BlenderSceneConverter::RegisterGameController(SCA_IController *cont, struct bController *for_controller)
{
m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
}
SCA_IController *KX_BlenderSceneConverter::FindGameController(
struct bController *for_controller)
SCA_IController *KX_BlenderSceneConverter::FindGameController(struct bController *for_controller)
{
SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
return contp?*contp:NULL;
}
void KX_BlenderSceneConverter::RegisterWorldInfo(
KX_WorldInfo *worldinfo)
void KX_BlenderSceneConverter::RegisterWorldInfo(KX_WorldInfo *worldinfo)
{
m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
}
void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{
//TODO this entire function is deprecated, written for 2.4x
//the functionality should be rewritten, currently it does nothing
KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
int numScenes = scenes->size();
@@ -614,7 +597,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{
KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
if (gameObj->IsRecordAnimation()) {
Object* blenderObject = gameObj->GetBlenderObject();
if (blenderObject)
{
@@ -625,21 +608,21 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{ //clear the curve data
if (clearIpo) {//rcruiz
IpoCurve *icu1;
int numCurves = 0;
for ( icu1 = (IpoCurve*)ipo->curve.first; icu1; ) {
IpoCurve* tmpicu = icu1;
/*int i;
BezTriple *bezt;
for ( bezt = tmpicu->bezt, i = 0; i < tmpicu->totvert; i++, bezt++) {
printf("(%f,%f,%f),(%f,%f,%f),(%f,%f,%f)\n",bezt->vec[0][0],bezt->vec[0][1],bezt->vec[0][2],bezt->vec[1][0],bezt->vec[1][1],bezt->vec[1][2],bezt->vec[2][0],bezt->vec[2][1],bezt->vec[2][2]);
}*/
icu1 = icu1->next;
numCurves++;
BLI_remlink( &( blenderObject->ipo->curve ), tmpicu );
if ( tmpicu->bezt )
MEM_freeN( tmpicu->bezt );
@@ -657,8 +640,8 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
}
}
}
@@ -667,45 +650,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo()
{
if (addInitFromFrame) {
KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
int numScenes = scenes->size();
if (numScenes>=0) {
KX_Scene* scene = scenes->at(0);
CListValue* parentList = scene->GetRootParentList();
for (int ix=0;ix<parentList->GetCount();ix++) {
KX_GameObject* gameobj = (KX_GameObject*)parentList->GetValue(ix);
if (!gameobj->IsRecordAnimation()) {
Object* blenderobject = gameobj->GetBlenderObject();
if (!blenderobject)
continue;
if (blenderobject->type==OB_ARMATURE)
continue;
float eu[3];
mat4_to_eul(eu,blenderobject->obmat);
MT_Point3 pos = MT_Point3(
blenderobject->obmat[3][0],
blenderobject->obmat[3][1],
blenderobject->obmat[3][2]
);
MT_Vector3 eulxyz = MT_Vector3(
eu[0],
eu[1],
eu[2]
);
MT_Vector3 scale = MT_Vector3(
blenderobject->size[0],
blenderobject->size[1],
blenderobject->size[2]
);
gameobj->NodeSetLocalPosition(pos);
gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
gameobj->NodeSetLocalScale(scale);
gameobj->NodeUpdateGS(0);
}
}
}
}
//TODO the functionality should be rewritten
}

View File

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

View File

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

View File

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

View File

@@ -124,14 +124,10 @@ KX_GameObject::KX_GameObject(
{
m_ignore_activity_culling = false;
m_pClient_info = new KX_ClientObjectInfo(this, KX_ClientObjectInfo::ACTOR);
m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks);
// define the relationship between this node and it's parent.
KX_NormalParentRelation * parent_relation =
KX_NormalParentRelation::New();
m_pSGNode->SetParentRelation(parent_relation);
};
m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks);
m_pSGNode->SetParentRelation(KX_NormalParentRelation::New());
}
@@ -157,8 +153,7 @@ KX_GameObject::~KX_GameObject()
//if (m_sumoObj)
// delete m_sumoObj;
delete m_pClient_info;
//if (m_pSGNode)
// delete m_pSGNode;
if (m_pSGNode)
{
// must go through controllers and make sure they will not use us anymore
@@ -601,7 +596,7 @@ void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local)
{
m_pPhysicsController->RelativeTranslate(dloc,local);
}
GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local);
GetSGNode()->RelativeTranslate(dloc,local);
}
}

View File

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

View File

@@ -80,9 +80,6 @@
#include "KX_NavMeshObject.h"
// If define: little test for Nzc: guarded drawing. If the canvas is
// not valid, skip rendering this frame.
//#define NZC_GUARDED_OUTPUT
#define DEFAULT_LOGIC_TIC_RATE 60.0
//#define DEFAULT_PHYSICS_TIC_RATE 60.0
@@ -741,85 +738,6 @@ bool KX_KetsjiEngine::NextFrame()
frames--;
}
bool bUseAsyncLogicBricks= false;//true;
if (bUseAsyncLogicBricks)
{
// Logic update sub frame: this will let some logic bricks run at the
// full frame rate.
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
// for each scene, call the proceed functions
{
KX_Scene* scene = *sceneit;
if (!scene->IsSuspended())
{
// if the scene was suspended recalcutlate the delta tu "curtime"
m_suspendedtime = scene->getSuspendedTime();
if (scene->getSuspendedTime()!=0.0)
scene->setSuspendedDelta(scene->getSuspendedDelta()+m_clockTime-scene->getSuspendedTime());
m_suspendeddelta = scene->getSuspendedDelta();
// set Python hooks for each scene
#ifdef WITH_PYTHON
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
#endif
KX_SetActiveScene(scene);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
SG_SetActiveStage(SG_STAGE_PHYSICS1);
scene->UpdateParents(m_clockTime);
// Perform physics calculations on the scene. This can involve
// many iterations of the physics solver.
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
scene->GetPhysicsEnvironment()->ProceedDeltaTime(m_clockTime,timestep,timestep);
// Update scenegraph after physics step. This maps physics calculations
// into node positions.
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
SG_SetActiveStage(SG_STAGE_PHYSICS2);
scene->UpdateParents(m_clockTime);
// Do some cleanup work for this logic frame
m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
scene->LogicUpdateFrame(m_clockTime, false);
// Actuators can affect the scenegraph
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
SG_SetActiveStage(SG_STAGE_ACTUATOR);
scene->UpdateParents(m_clockTime);
scene->setSuspendedTime(0.0);
} // suspended
else
if (scene->getSuspendedTime()==0.0)
scene->setSuspendedTime(m_clockTime);
m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
}
}
// Handle the animations independently of the logic time step
if (GetRestrictAnimationFPS())
{
double clocktime = m_kxsystem->GetTimeInSeconds();
m_logger->StartLog(tc_animations, clocktime, true);
SG_SetActiveStage(SG_STAGE_ANIMATION_UPDATE);
double anim_timestep = 1.0/KX_GetActiveScene()->GetAnimationFPS();
if (clocktime - m_previousAnimTime > anim_timestep)
{
// Sanity/debug print to make sure we're actually going at the fps we want (should be close to anim_timestep)
// printf("Anim fps: %f\n", 1.0/(m_clockTime - m_previousAnimTime));
m_previousAnimTime = clocktime;
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
{
(*sceneit)->UpdateAnimations(clocktime);
}
}
}
// Start logging time spend outside main loop
m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true);

View File

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

View File

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

View File

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

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

View File

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

View File

@@ -171,8 +171,10 @@ void initPyTypes(void)
* .....
*/
/* Use existing module where possible */
PyObject *mod = initGameTypesPythonBinding();
/* For now just do PyType_Ready */
PyObject *mod = PyModule_New("GameTypes");
PyObject *dict = PyModule_GetDict(mod);
PyDict_SetItemString(PySys_GetObject("modules"), "GameTypes", mod);
Py_DECREF(mod);
@@ -269,4 +271,42 @@ void initPyTypes(void)
#endif
}
PyDoc_STRVAR(GameTypes_module_documentation,
"This module provides access to the game engine data types."
);
static struct PyModuleDef GameTypes_module_def = {
PyModuleDef_HEAD_INIT,
"GameTypes", /* m_name */
GameTypes_module_documentation, /* m_doc */
0, /* m_size */
NULL, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
PyMODINIT_FUNC initGameTypesPythonBinding(void)
{
PyObject *m;
/* Use existing module where possible */
m = PyImport_ImportModule( "GameTypes" );
if (m) {
Py_DECREF(m);
return m;
}
else {
PyErr_Clear();
// Create the module and add the functions
m = PyModule_Create(&GameTypes_module_def);
PyDict_SetItemString(PySys_GetObject("modules"), GameTypes_module_def.m_name, m);
}
return m;
}
#endif // WITH_PYTHON

View File

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

View File

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

View File

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

View File

@@ -32,267 +32,214 @@
#include "KX_SG_NodeRelationships.h"
/**
* Implementation of classes defined in KX_SG_NodeRelationships.h
*/
/**
* first of all KX_NormalParentRelation
* KX_NormalParentRelation - a regular parent/child relation, the child's coordinates are relative to the parent
*/
KX_NormalParentRelation *
KX_NormalParentRelation::
New(
) {
KX_NormalParentRelation* KX_NormalParentRelation::New()
{
return new KX_NormalParentRelation();
}
bool
KX_NormalParentRelation::
UpdateChildCoordinates(
SG_Spatial * child,
const SG_Spatial * parent,
bool& parentUpdated
) {
bool KX_NormalParentRelation::UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated)
{
MT_assert(child != NULL);
/* If nothing changed in the parent or child, there is nothing to do here */
if (!parentUpdated && !child->IsModified())
return false;
parentUpdated = true;
if (parent==NULL) { /* Simple case */
/* The child has no parent, it is a root object.
* The world and local coordinates should be the same and applied directly. */
if (parent==NULL) {
child->SetWorldFromLocalTransform();
child->ClearModified();
return true; //false;
}
/* The child has a parent. The child's coordinates are defined relative to the parent's.
* The parent's coordinates should be applied to the child's local ones to calculate the real world position. */
else {
// the childs world locations which we will update.
const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
const MT_Point3 & p_world_pos = parent->GetWorldPosition();
const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
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();
child->SetWorldScale(p_world_scale * child->GetLocalScale());
child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation());
child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition()));
child->ClearModified();
return true;
const MT_Vector3 & new_world_scale = parent_world_scale * child_local_scale;
const MT_Matrix3x3 & new_world_ori = parent_world_ori * child_local_ori;
const MT_Point3 & new_world_pos = parent_world_pos + (new_world_scale * (new_world_ori * child_local_pos));
child->SetWorldScale(new_world_scale);
child->SetWorldOrientation(new_world_ori);
child->SetWorldPosition(new_world_pos);
}
parentUpdated = true; //this variable is going to be used to update the children of this child
child->ClearModified();
return true;
}
SG_ParentRelation *
KX_NormalParentRelation::
NewCopy(
) {
SG_ParentRelation* KX_NormalParentRelation::NewCopy()
{
return new KX_NormalParentRelation();
}
KX_NormalParentRelation::
~KX_NormalParentRelation(
) {
//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)
KX_NormalParentRelation::~KX_NormalParentRelation()
{
//nothing to do
}
KX_SlowParentRelation::
~KX_SlowParentRelation(
) {
KX_NormalParentRelation::KX_NormalParentRelation()
{
// 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
}
/**
* 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
* \ingroup ketsji
* \section KX_SG_NodeRelationships
* This file provides common concrete implementations of
* SG_ParentRelation used by the game engine. These are
* KX_SlowParentRelation a slow parent relationship.
* KX_NormalParentRelation a normal parent relationship where
* orientation and position are inherited from the parent by
* \section KX_SG_NodeRelationships
* This file provides common concrete implementations of
* SG_ParentRelation used by the game engine. These are:
* - KX_NormalParentRelation a normal parent relationship where
* orientation, position and scale are inherited from the parent by
* the child.
* KX_VertexParentRelation only location information is
* inherited by the child.
* - KX_VertexParentRelation only location information is inherited by the child.
* - KX_SlowParentRelation a slow parent relationship.
*/
#ifndef __KX_SG_NODERELATIONSHIPS_H__
@@ -50,41 +49,28 @@ class KX_NormalParentRelation : public SG_ParentRelation
public :
/**
* Allocate and construct a new KX_NormalParentRelation
* on the heap.
* Allocate and construct a new KX_NormalParentRelation on the heap.
*/
static
KX_NormalParentRelation *
New(
);
static KX_NormalParentRelation* New();
/**
* Method inherited from KX_ParentRelation
* Update the child's global coordinates based upon the local ones and the parent's global coordinates.
*/
bool
UpdateChildCoordinates(
SG_Spatial * child,
const SG_Spatial * parent,
bool& parentUpdated
);
bool UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated);
/**
* Method inherited from KX_ParentRelation
* This should return a pointer to a new duplicate allocated on the heap.
* Responsibility for deleting the duplicate resides with the caller of this method.
*/
SG_ParentRelation *
NewCopy(
);
SG_ParentRelation* NewCopy();
~KX_NormalParentRelation(
);
~KX_NormalParentRelation();
private :
KX_NormalParentRelation(
);
KX_NormalParentRelation();
#ifdef WITH_CXX_GUARDEDALLOC
@@ -99,47 +85,33 @@ class KX_VertexParentRelation : public SG_ParentRelation
public :
/**
* Allocate and construct a new KX_VertexParentRelation
* on the heap.
* Allocate and construct a new KX_VertexParentRelation on the heap.
*/
static
KX_VertexParentRelation *
New(
);
static KX_VertexParentRelation* New();
/**
* Method inherited from KX_ParentRelation
* Update the child's global coordinates based upon the local ones and the parent's global coordinates.
*/
bool
UpdateChildCoordinates(
SG_Spatial * child,
const SG_Spatial * parent,
bool& parentUpdated
);
bool UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated);
/**
* Method inherited from KX_ParentRelation
* This should return a pointer to a new duplicate allocated on the heap.
* Responsibility for deleting the duplicate resides with the caller of this method.
*/
SG_ParentRelation *
NewCopy(
);
SG_ParentRelation * NewCopy();
~KX_VertexParentRelation(
);
~KX_VertexParentRelation();
bool
IsVertexRelation(
) {
bool IsVertexRelation()
{
return true;
}
private :
KX_VertexParentRelation(
);
KX_VertexParentRelation();
#ifdef WITH_CXX_GUARDEDALLOC
@@ -154,72 +126,43 @@ class KX_SlowParentRelation : public SG_ParentRelation
public :
/**
* Allocate and construct a new KX_VertexParentRelation
* on the heap.
* Allocate and construct a new KX_SlowParentRelation on the heap.
*/
static KX_SlowParentRelation* New(MT_Scalar relaxation);
static
KX_SlowParentRelation *
New(
MT_Scalar relaxation
);
/**
/**
* Method inherited from KX_ParentRelation
* Update the child's global coordinates based upon the local ones and the parent's global coordinates.
*/
bool UpdateChildCoordinates(SG_Spatial *child, const SG_Spatial *parent, bool &parentUpdated);
bool
UpdateChildCoordinates(
SG_Spatial * child,
const SG_Spatial * parent,
bool& parentUpdated
);
/**
/**
* Method inherited from KX_ParentRelation
* This should return a pointer to a new duplicate allocated on the heap.
* Responsibility for deleting the duplicate resides with the caller of this method.
*/
SG_ParentRelation *
NewCopy(
);
SG_ParentRelation* NewCopy();
MT_Scalar
GetTimeOffset(
) { return m_relax; }
void
SetTimeOffset(
MT_Scalar relaxation
) { m_relax = relaxation; }
~KX_SlowParentRelation();
~KX_SlowParentRelation(
);
bool
IsSlowRelation(
) {
bool IsSlowRelation()
{
return true;
}
MT_Scalar GetTimeOffset() { return m_relax; }
void SetTimeOffset(MT_Scalar relaxation) { m_relax = relaxation; }
private :
KX_SlowParentRelation(
MT_Scalar relaxation
);
KX_SlowParentRelation(MT_Scalar relaxation);
// the relaxation coefficient.
MT_Scalar m_relax;
MT_Scalar m_relax; /* the relaxation coefficient. the bigger, the slower */
MT_Scalar m_weight; /*inverse relax coefficient, computed only once for calculations*/
/**
* Looks like a hack flag to me.
* We need to compute valid world coordinates the first
* time we update spatial data of the child. This is done
* by just doing a normal parent relation the first time
* UpdateChildCoordinates is called and then doing the
* slow parent relation
*/
bool m_initialized;
@@ -228,4 +171,4 @@ private :
#endif
};
#endif
#endif /* __KX_SG_NODERELATIONSHIPS_H__ */

View File

@@ -867,8 +867,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
m_map_gameobject_to_replica.clear();
m_groupGameObjects.clear();
// todo: place a timebomb in the object, for temporarily objects :)
// lifespan of zero means 'this object lives forever'
KX_GameObject* originalobj = (KX_GameObject*) originalobject;
KX_GameObject* parentobj = (KX_GameObject*) parentobject;
@@ -877,9 +875,10 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
// lets create a replica
KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj);
// add a timebomb to this object
// lifespan of zero means 'this object lives forever'
if (lifespan > 0)
{
// add a timebomb to this object
// for now, convert between so called frames and realtime
m_tempObjectList->Add(replica->AddRef());
// this convert the life from frames to sort-of seconds, hard coded 0.02 that assumes we have 50 frames per second
@@ -915,7 +914,6 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
// get the rootnode's scale
MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
// set the replica's relative scale with the rootnode's scale
replica->NodeSetRelativeScale(newscale);

View File

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

View File

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

View File

@@ -39,9 +39,6 @@ class btCollisionDispatcher;
class btDispatcher;
//#include "btBroadphaseInterface.h"
//switch on/off new vehicle support
#define NEW_BULLET_VEHICLE_SUPPORT 1
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
class WrapperVehicle;
@@ -176,16 +173,8 @@ protected:
virtual void CallbackTriggers();
virtual PHY_IVehicle* GetVehicleConstraint(int constraintId);
#ifdef NEW_BULLET_VEHICLE_SUPPORT
//complex constraint for vehicles
virtual PHY_IVehicle* GetVehicleConstraint(int constraintId);
#else
virtual class PHY_IVehicle* GetVehicleConstraint(int constraintId)
{
return 0;
}
#endif /* NEW_BULLET_VEHICLE_SUPPORT */
// Character physics wrapper
virtual PHY_ICharacter* GetCharacterController(class KX_GameObject* ob);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -41,6 +41,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_image_types.h"
#include "IMB_imbuf_types.h"
#include "BKE_image.h"
#include "MEM_guardedalloc.h"
@@ -158,6 +159,7 @@ static PyObject *Texture_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
// initialize object structure
self->m_actTex = 0;
self->m_orgSaved = false;
self->m_imgBuf = NULL;
self->m_imgTexture = NULL;
self->m_matTexture = NULL;
self->m_mipmap = false;
@@ -282,7 +284,11 @@ PyObject *Texture_close(Texture * self)
if (self->m_useMatTexture)
self->m_matTexture->swapTexture(self->m_orgTex);
else
{
self->m_imgTexture->bindcode = self->m_orgTex;
BKE_image_release_ibuf(self->m_imgTexture, self->m_imgBuf, NULL);
self->m_imgBuf = NULL;
}
// drop actual texture
if (self->m_actTex != 0)
{
@@ -331,6 +337,12 @@ static PyObject *Texture_refresh(Texture *self, PyObject *args)
self->m_orgTex = self->m_matTexture->swapTexture(self->m_actTex);
else
{
// Swapping will work only if the GPU has already loaded the image.
// If not, it will delete and overwrite our texture on next render.
// To avoid that, we acquire the image buffer now.
// WARNING: GPU has a ImageUser to pass, we don't. Using NULL
// works on image file, not necessarily on other type of image.
self->m_imgBuf = BKE_image_acquire_ibuf(self->m_imgTexture, NULL, NULL);
self->m_orgTex = self->m_imgTexture->bindcode;
self->m_imgTexture->bindcode = self->m_actTex;
}

View File

@@ -43,6 +43,8 @@
#include "Exception.h"
struct ImBuf;
// type Texture declaration
struct Texture
{
@@ -58,6 +60,8 @@ struct Texture
// original texture saved
bool m_orgSaved;
// kernel image buffer, to make sure the image is loaded before we swap the bindcode
struct ImBuf *m_imgBuf;
// texture image for game materials
Image * m_imgTexture;
// texture for blender materials

View File

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