Compare commits
83 Commits
virtual-ar
...
soc-2014-b
Author | SHA1 | Date | |
---|---|---|---|
cb61c5aeee | |||
d7cabe7d6f | |||
1c57e68d5c | |||
7d3042f95f | |||
7fbc7b83c9 | |||
335f6653b7 | |||
8f3c65c9df | |||
12fa08d83f | |||
7361d5731e | |||
0a7af14163 | |||
65ffe0f541 | |||
47e5a16853 | |||
7195e8a4bc | |||
423ee21640 | |||
c31d921b0d | |||
4054df5b21 | |||
06a86b9076 | |||
bbf6b0535e | |||
1a1fcba188 | |||
5a511eb7cc | |||
1fd8030207 | |||
16741f0763 | |||
b4e374cfad | |||
c8bfd092a4 | |||
838e1d3e27 | |||
6203831b89 | |||
3f79ceb0ea | |||
52d2099700 | |||
b24560e4a8 | |||
514c53ef81 | |||
8468a28467 | |||
86d8f10200 | |||
88f2b48a4d | |||
c32a33f40c | |||
0be0aa99e4 | |||
8d53f17138 | |||
8b5ec204e9 | |||
de540d85a2 | |||
51810ed3a3 | |||
1730ed876a | |||
5ba18bc764 | |||
bf51d62e0e | |||
a26e8f6562 | |||
18841038d9 | |||
1ba0afc58e | |||
1890168b0d | |||
fa557d685f | |||
e3c6585502 | |||
2e5bd8d418 | |||
db6abb619c | |||
041beb65ca | |||
0eb272df75 | |||
d5b88e62ca | |||
43ae0f0dda | |||
610e2fdabd | |||
2a997e7933 | |||
4dd575305c | |||
ed9bd6b95d | |||
1ff3ca3c63 | |||
58373b8c2e | |||
ebae705c2e | |||
cdcd252146 | |||
5640131c20 | |||
aeae4c2d9d | |||
2420704ef2 | |||
3d35124a08 | |||
00d0d9677d | |||
f80b139a7d | |||
a7a58d9675 | |||
d1ca785cf5 | |||
4929cb8126 | |||
82313b4fc4 | |||
331f9fdfac | |||
f12c182a46 | |||
1ada96fbf0 | |||
9c95ea33f1 | |||
02f9b2c4eb | |||
140a3aca7c | |||
d503f8a621 | |||
8060887089 | |||
14fceb64cc | |||
b8fbe686bf | |||
05db026d8a |
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
BIN
extern/bullet2/Bullet_User_Manual.pdf
vendored
Normal file
Binary file not shown.
@@ -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"
|
||||
|
@@ -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)
|
||||
|
@@ -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):
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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
|
||||
|
@@ -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];
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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];
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -36,6 +36,7 @@ enum e_PhysicsEngine
|
||||
{
|
||||
NoSelection = -1,
|
||||
UseNone = 0,
|
||||
/* UseEnji=1, UseSumo, useDynamo and useODE were removed */
|
||||
UseBullet = 5,
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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
|
||||
|
@@ -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 *);
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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__ */
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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__ */
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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__ */
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -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]);
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -14,8 +14,8 @@
|
||||
|
||||
class PHY_ICharacter
|
||||
{
|
||||
public:
|
||||
virtual ~PHY_ICharacter(){};
|
||||
public:
|
||||
virtual ~PHY_ICharacter(){}
|
||||
|
||||
virtual void Jump()= 0;
|
||||
virtual bool OnGround()= 0;
|
||||
|
@@ -18,7 +18,7 @@ class PHY_IMotionState;
|
||||
class PHY_IVehicle
|
||||
{
|
||||
public:
|
||||
virtual ~PHY_IVehicle(){};
|
||||
virtual ~PHY_IVehicle(){}
|
||||
|
||||
virtual void AddWheel(
|
||||
PHY_IMotionState* motionState,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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")
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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__ */
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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__ */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user