Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine')
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp2
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp5
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderCanvas.h2
-rw-r--r--source/gameengine/CMakeLists.txt2
-rw-r--r--source/gameengine/Converter/BL_ArmatureConstraint.cpp2
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp163
-rw-r--r--source/gameengine/Converter/BlenderWorldInfo.cpp200
-rw-r--r--source/gameengine/Converter/BlenderWorldInfo.h82
-rw-r--r--source/gameengine/Converter/CMakeLists.txt4
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp651
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp974
-rw-r--r--source/gameengine/Expressions/CMakeLists.txt2
-rw-r--r--source/gameengine/Expressions/KX_PythonCallBack.cpp119
-rw-r--r--source/gameengine/Expressions/KX_PythonCallBack.h40
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp15
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h13
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h1
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp34
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h8
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp9
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp2
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.h2
-rw-r--r--source/gameengine/GamePlayer/ghost/CMakeLists.txt1
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp6
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp12
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Canvas.h2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp11
-rw-r--r--source/gameengine/GamePlayer/ghost/SConscript1
-rw-r--r--source/gameengine/Ketsji/BL_Action.cpp9
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp24
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp53
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h9
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h2
-rw-r--r--source/gameengine/Ketsji/KX_FontObject.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_FontObject.h1
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp307
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h41
-rw-r--r--source/gameengine/Ketsji/KX_IpoConvert.cpp88
-rw-r--r--source/gameengine/Ketsji/KX_IpoConvert.h3
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp71
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h2
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp29
-rw-r--r--source/gameengine/Ketsji/KX_Light.h4
-rw-r--r--source/gameengine/Ketsji/KX_MaterialIpoController.cpp15
-rw-r--r--source/gameengine/Ketsji/KX_MouseActuator.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp32
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h3
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp90
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp132
-rw-r--r--source/gameengine/Ketsji/KX_PythonInitTypes.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp233
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h17
-rw-r--r--source/gameengine/Ketsji/KX_SteeringActuator.cpp9
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp18
-rw-r--r--source/gameengine/Ketsji/KX_WorldInfo.cpp456
-rw-r--r--source/gameengine/Ketsji/KX_WorldInfo.h84
-rw-r--r--source/gameengine/Ketsji/KX_WorldIpoController.cpp31
-rw-r--r--source/gameengine/Ketsji/KX_WorldIpoController.h28
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp726
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h59
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp230
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h24
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h5
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h4
-rw-r--r--source/gameengine/Rasterizer/RAS_ICanvas.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h12
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp6
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h9
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp120
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h21
-rw-r--r--source/gameengine/VideoTexture/ImageRender.cpp27
-rw-r--r--source/gameengine/VideoTexture/ImageRender.h2
-rw-r--r--source/gameengine/VideoTexture/Texture.cpp14
76 files changed, 3020 insertions, 2420 deletions
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 511b61528f8..1a198920919 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -446,7 +446,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
rasterizer->SetEyeSeparation(scene->gm.eyeseparation);
}
- rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f);
+ rasterizer->SetBackColor(scene->gm.framing.col);
}
if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
index 3a31806fad4..e37818678d6 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
@@ -97,6 +97,11 @@ bool KX_BlenderCanvas::GetSwapInterval(int &intervalOut)
return wm_window_get_swap_interval(m_win, &intervalOut);
}
+void KX_BlenderCanvas::GetDisplayDimensions(int &width, int &height)
+{
+ wm_get_screensize(&width, &height);
+}
+
void KX_BlenderCanvas::ResizeWindow(int width, int height)
{
// Not implemented for the embedded player
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
index c150af21230..817a667d783 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.h
@@ -87,6 +87,8 @@ public:
int &intervalOut
);
+ void GetDisplayDimensions(int &width, int &height);
+
void
ResizeWindow(
int width,
diff --git a/source/gameengine/CMakeLists.txt b/source/gameengine/CMakeLists.txt
index cf7895e98ea..62523175f46 100644
--- a/source/gameengine/CMakeLists.txt
+++ b/source/gameengine/CMakeLists.txt
@@ -23,6 +23,8 @@
#
# ***** END GPL LICENSE BLOCK *****
+remove_extra_strict_flags()
+
# there are too many inter-includes so best define here
if(WITH_PYTHON)
blender_include_dirs_sys("${PYTHON_INCLUDE_DIRS}")
diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.cpp b/source/gameengine/Converter/BL_ArmatureConstraint.cpp
index e515574df8b..88d82e21d61 100644
--- a/source/gameengine/Converter/BL_ArmatureConstraint.cpp
+++ b/source/gameengine/Converter/BL_ArmatureConstraint.cpp
@@ -334,7 +334,7 @@ PyObject *BL_ArmatureConstraint::py_attr_getattr(void *self_v, const struct KX_P
}
switch (attr_order) {
case BCA_IKWEIGHT:
- return PyFloat_FromDouble((ikconstraint)?ikconstraint->weight : 0.0f);
+ return PyFloat_FromDouble(ikconstraint->weight);
case BCA_IKTYPE:
return PyLong_FromLong(ikconstraint->type);
case BCA_IKFLAG:
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index bc2fc0179fd..795a7a9ae87 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -268,7 +268,7 @@ void BL_ArmatureObject::LoadConstraints(KX_BlenderSceneConverter* converter)
// get the persistent pose structure
bPoseChannel* pchan;
bConstraint* pcon;
- bConstraintTypeInfo* cti;
+ const bConstraintTypeInfo* cti;
Object* blendtarget;
KX_GameObject* gametarget;
KX_GameObject* gamesubtarget;
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 7e0588fc7d0..3da0863508b 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -98,7 +98,7 @@
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
-#include "BlenderWorldInfo.h"
+#include "KX_WorldInfo.h"
#include "KX_KetsjiEngine.h"
#include "KX_BlenderSceneConverter.h"
@@ -995,7 +995,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
meshobj->m_sharedvertex_map.resize(totvert);
Material* ma = 0;
- bool collider = true;
MT_Point2 uvs[4][RAS_TexVert::MAX_UNIT];
unsigned int rgb[4] = {0};
@@ -1065,29 +1064,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene,
else
ma = mesh->mat ? mesh->mat[mface->mat_nr]:NULL;
- /* ckeck for texface since texface _only_ is used as a fallback */
- if (ma == NULL && tface == NULL) {
+ // Check for blender material
+ if (ma == NULL) {
ma= &defmaterial;
}
{
- bool visible = true;
- bool twoside = false;
RAS_MaterialBucket* bucket = material_from_mesh(ma, mface, tface, mcol, layers, lightlayer, rgb, uvs, tfaceName, scene, converter);
// set render flags
- if (ma)
- {
- visible = ((ma->game.flag & GEMAT_INVISIBLE)==0);
- twoside = ((ma->game.flag & GEMAT_BACKCULL)==0);
- collider = ((ma->game.flag & GEMAT_NOPHYSICS)==0);
- }
- else {
- visible = true;
- twoside = false;
- collider = true;
- }
+ bool visible = ((ma->game.flag & GEMAT_INVISIBLE)==0);
+ bool twoside = ((ma->game.flag & GEMAT_BACKCULL)==0);
+ bool collider = ((ma->game.flag & GEMAT_NOPHYSICS)==0);
/* mark face as flat, so vertices are split */
bool flat = (mface->flag & ME_SMOOTH) == 0;
@@ -1347,8 +1336,8 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
if (!(blenderobject->gameflag & OB_COLLISION)) {
// Respond to all collisions so that Near sensors work on No Collision
// objects.
- gameobj->SetUserCollisionGroup(0xff);
- gameobj->SetUserCollisionMask(0xff);
+ gameobj->SetUserCollisionGroup(0xffff);
+ gameobj->SetUserCollisionMask(0xffff);
return;
}
@@ -1554,6 +1543,10 @@ static KX_GameObject *gameobject_from_blenderobject(
}
gameobj->AddLodMesh(BL_ConvertMesh(lodmesh, lodmatob, kxscene, converter, libloading));
}
+ if (blenderscene->gm.lodflag & SCE_LOD_USE_HYST) {
+ kxscene->SetLodHysteresis(true);
+ kxscene->SetLodHysteresisValue(blenderscene->gm.scehysteresis);
+ }
}
// for all objects: check whether they want to
@@ -1647,7 +1640,7 @@ static KX_GameObject *gameobject_from_blenderobject(
case OB_FONT:
{
- bool do_color_management = !(blenderscene->gm.flag & GAME_GLSL_NO_COLOR_MANAGEMENT);
+ bool do_color_management = BKE_scene_check_color_management_enabled(blenderscene);
/* font objects have no bounding box */
gameobj = new KX_FontObject(kxscene,KX_Scene::m_callbacks, rendertools, ob, do_color_management);
@@ -1741,6 +1734,16 @@ static KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist)
}
+static bool bl_isConstraintInList(KX_GameObject *gameobj, set<KX_GameObject*> convertedlist)
+{
+ set<KX_GameObject*>::iterator gobit;
+ for (gobit = convertedlist.begin(); gobit != convertedlist.end(); gobit++) {
+ if ((*gobit)->GetName() == gameobj->GetName())
+ return true;
+ }
+ return false;
+}
+
/* helper for BL_ConvertBlenderObjects, avoids code duplication
* note: all var names match args are passed from the caller */
static void bl_ConvertBlenderObject_Single(
@@ -1900,6 +1903,12 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// is not in a separate thread.
BL_Texture::GetMaxUnits();
+ /* We have to ensure that group definitions are only converted once
+ * push all converted group members to this set.
+ * This will happen when a group instance is made from a linked group instance
+ * and both are on the active layer. */
+ set<KX_GameObject*> convertedlist;
+
if (alwaysUseExpandFraming) {
frame_type = RAS_FrameSettings::e_frame_extend;
aspect_width = canvas->GetWidth();
@@ -2031,6 +2040,11 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
converter,
libloading);
+ /* Insert object to the constraint game object list
+ * so we can check later if there is a instance in the scene or
+ * an instance and its actual group definition. */
+ convertedlist.insert((KX_GameObject*)gameobj->AddRef());
+
bool isInActiveLayer = false;
if (gameobj)
{
@@ -2270,97 +2284,54 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// 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;
+ PHY_IPhysicsEnvironment *physEnv = kxscene->GetPhysicsEnvironment();
+ KX_GameObject *gameobj = (KX_GameObject *)sumolist->GetValue(i);
+ struct Object *blenderobject = gameobj->GetBlenderObject();
+ ListBase *conlist = get_active_constraints2(blenderobject);
bConstraint *curcon;
- if ((gameobj->GetLayer()&activeLayerBitInfo)==0)
+ if (!conlist)
continue;
- conlist = get_active_constraints2(blenderobject);
- if (conlist) {
- for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) {
- if (curcon->type==CONSTRAINT_TYPE_RIGIDBODYJOINT) {
-
- bRigidBodyJointConstraint *dat=(bRigidBodyJointConstraint *)curcon->data;
+ for (curcon = (bConstraint *)conlist->first; curcon; curcon = (bConstraint *)curcon->next) {
+ if (curcon->type != CONSTRAINT_TYPE_RIGIDBODYJOINT)
+ continue;
- if (!dat->child && !(curcon->flag & CONSTRAINT_OFF)) {
+ bRigidBodyJointConstraint *dat = (bRigidBodyJointConstraint *)curcon->data;
+
+ /* Skip if no target or a child object is selected or constraints are deactivated */
+ if (!dat->tar || dat->child || (curcon->flag & CONSTRAINT_OFF))
+ continue;
- PHY_IPhysicsController* physctr2 = 0;
+ /* Store constraints of grouped and instanced objects for all layers */
+ gameobj->AddConstraint(dat);
+
+ /* Skipped already converted constraints.
+ * This will happen when a group instance is made from a linked group instance
+ * and both are on the active layer. */
+ if (bl_isConstraintInList(gameobj, convertedlist))
+ continue;
- if (dat->tar) {
- KX_GameObject *gotar=getGameOb(dat->tar->id.name+2,sumolist);
- if (gotar && ((gotar->GetLayer()&activeLayerBitInfo)!=0) && gotar->GetPhysicsController())
- physctr2 = gotar->GetPhysicsController();
- }
+ KX_GameObject *gotar = getGameOb(dat->tar->id.name + 2, sumolist);
- if (gameobj->GetPhysicsController()) {
- PHY_IPhysicsController* physctrl = gameobj->GetPhysicsController();
- //we need to pass a full constraint frame, not just axis
-
- //localConstraintFrameBasis
- MT_Matrix3x3 localCFrame(MT_Vector3(dat->axX,dat->axY,dat->axZ));
- 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 it is a generic 6DOF constraint, set all the limits accordingly
- if (dat->type == PHY_GENERIC_6DOF_CONSTRAINT) {
- int dof;
- int dofbit=1;
- for (dof=0;dof<6;dof++) {
- if (dat->flag & dofbit) {
- kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
- } else {
- //minLimit > maxLimit means free(disabled limit) for this degree of freedom
- kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
- }
- dofbit<<=1;
- }
- } 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) {
- kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,dat->minLimit[dof],dat->maxLimit[dof]);
- } 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) {
- int dof = 3; // dof for angular x
- int dofbit = 1<<3; // bitflag use_angular_limit_x
-
- if (dat->flag & dofbit) {
- kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,
- dat->minLimit[dof],dat->maxLimit[dof]);
- } else {
- //minLimit > maxLimit means free(disabled limit) for this degree of freedom
- kxscene->GetPhysicsEnvironment()->SetConstraintParam(constraintId,dof,1,-1);
- }
- }
- }
- }
- }
- }
+ if (gotar && (gotar->GetLayer()&activeLayerBitInfo) && gotar->GetPhysicsController() &&
+ (gameobj->GetLayer()&activeLayerBitInfo) && gameobj->GetPhysicsController())
+ {
+ physEnv->SetupObjectConstraints(gameobj, gotar, dat);
}
}
}
+ /* cleanup converted set of group objects */
+ set<KX_GameObject*>::iterator gobit;
+ for (gobit = convertedlist.begin(); gobit != convertedlist.end(); gobit++)
+ (*gobit)->Release();
+
+ convertedlist.clear();
sumolist->Release();
// convert world
- KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene, blenderscene->world);
+ KX_WorldInfo* worldinfo = new KX_WorldInfo(blenderscene, blenderscene->world);
converter->RegisterWorldInfo(worldinfo);
kxscene->SetWorldInfo(worldinfo);
diff --git a/source/gameengine/Converter/BlenderWorldInfo.cpp b/source/gameengine/Converter/BlenderWorldInfo.cpp
deleted file mode 100644
index 75beb5d0e0e..00000000000
--- a/source/gameengine/Converter/BlenderWorldInfo.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can [0]istribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file gameengine/Converter/BlenderWorldInfo.cpp
- * \ingroup bgeconv
- */
-
-
-#include <stdio.h> // printf()
-
-#include "BlenderWorldInfo.h"
-
-/* This little block needed for linking to Blender... */
-#ifdef WIN32
-#include "BLI_winstuff.h"
-#endif
-
-/* This list includes only data type definitions */
-#include "DNA_object_types.h"
-#include "DNA_material_types.h"
-#include "DNA_image_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_group_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_property_types.h"
-#include "DNA_text_types.h"
-#include "DNA_sensor_types.h"
-#include "DNA_controller_types.h"
-#include "DNA_actuator_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_world_types.h"
-#include "DNA_screen_types.h"
-
-#include "BLI_math.h"
-
-#include "BKE_global.h"
-#include "BKE_scene.h"
-/* end of blender include block */
-
-
-BlenderWorldInfo::BlenderWorldInfo(struct Scene *blenderscene, struct World *blenderworld)
-{
- if (blenderworld) {
- m_hasworld = true;
-
- // do we have mist?
- if ((blenderworld->mode) & WO_MIST) {
- m_hasmist = true;
- m_miststart = blenderworld->miststa;
- m_mistdistance = blenderworld->mistdist;
- copy_v3_v3(m_mistcolor, &blenderworld->horr);
- }
- else {
- m_hasmist = false;
- m_miststart = 0.0;
- m_mistdistance = 0.0;
- zero_v3(m_mistcolor);
- }
-
- copy_v3_v3(m_backgroundcolor, &blenderworld->horr);
- copy_v3_v3(m_ambientcolor, &blenderworld->ambr);
-
- if (BKE_scene_check_color_management_enabled(blenderscene)) {
- linearrgb_to_srgb_v3_v3(m_mistcolor, m_mistcolor);
- linearrgb_to_srgb_v3_v3(m_backgroundcolor, m_backgroundcolor);
- linearrgb_to_srgb_v3_v3(m_ambientcolor, m_ambientcolor);
- }
- }
- else {
- m_hasworld = false;
- }
-}
-
-BlenderWorldInfo::~BlenderWorldInfo()
-{
-}
-
-bool BlenderWorldInfo::hasWorld()
-{
- return m_hasworld;
-}
-
-bool BlenderWorldInfo::hasMist()
-{
- return m_hasmist;
-}
-
-float BlenderWorldInfo::getBackColorRed()
-{
- return m_backgroundcolor[0];
-}
-
-float BlenderWorldInfo::getBackColorGreen()
-{
- return m_backgroundcolor[1];
-}
-
-float BlenderWorldInfo::getBackColorBlue()
-{
- return m_backgroundcolor[2];
-}
-
-float BlenderWorldInfo::getAmbientColorRed()
-{
- return m_ambientcolor[0];
-}
-
-float BlenderWorldInfo::getAmbientColorGreen()
-{
- return m_ambientcolor[1];
-}
-
-float BlenderWorldInfo::getAmbientColorBlue()
-{
- return m_ambientcolor[2];
-}
-
-float BlenderWorldInfo::getMistStart()
-{
- return m_miststart;
-}
-
-float BlenderWorldInfo::getMistDistance()
-{
- return m_mistdistance;
-}
-
-float BlenderWorldInfo::getMistColorRed()
-{
- return m_mistcolor[0];
-}
-
-float BlenderWorldInfo::getMistColorGreen()
-{
- return m_mistcolor[1];
-}
-
-float BlenderWorldInfo::getMistColorBlue()
-{
- return m_mistcolor[2];
-}
-
-void BlenderWorldInfo::setBackColor(float r, float g, float b)
-{
- m_backgroundcolor[0] = r;
- m_backgroundcolor[1] = g;
- m_backgroundcolor[2] = b;
-}
-
-void BlenderWorldInfo::setMistStart(float d)
-{
- m_miststart = d;
-}
-
-void BlenderWorldInfo::setMistDistance(float d)
-{
- m_mistdistance = d;
-}
-
-void BlenderWorldInfo::setMistColorRed(float d)
-{
- m_mistcolor[0] = d;
-}
-
-void BlenderWorldInfo::setMistColorGreen(float d)
-{
- m_mistcolor[1] = d;
-}
-
-void BlenderWorldInfo::setMistColorBlue(float d)
-{
- m_mistcolor[2] = d;
-}
diff --git a/source/gameengine/Converter/BlenderWorldInfo.h b/source/gameengine/Converter/BlenderWorldInfo.h
deleted file mode 100644
index 2ac2d70b5d1..00000000000
--- a/source/gameengine/Converter/BlenderWorldInfo.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file BlenderWorldInfo.h
- * \ingroup bgeconv
- */
-
-#ifndef __BLENDERWORLDINFO_H__
-#define __BLENDERWORLDINFO_H__
-#include "MT_CmMatrix4x4.h"
-#include "KX_WorldInfo.h"
-
-class BlenderWorldInfo : public KX_WorldInfo
-{
- bool m_hasworld;
- float m_backgroundcolor[3];
-
- bool m_hasmist;
- float m_miststart;
- float m_mistdistance;
- float m_mistcolor[3];
-
- float m_ambientcolor[3];
-
-public:
- BlenderWorldInfo(struct Scene *blenderscene, struct World *blenderworld);
- ~BlenderWorldInfo();
-
- bool hasWorld();
- bool hasMist();
- float getBackColorRed();
- float getBackColorGreen();
- float getBackColorBlue();
-
- float getAmbientColorRed();
- float getAmbientColorGreen();
- float getAmbientColorBlue();
-
- float getMistStart();
- float getMistDistance();
- float getMistColorRed();
- float getMistColorGreen();
- float getMistColorBlue();
-
- void setBackColor(float r, float g, float b);
- void setMistStart(float d);
- void setMistDistance(float d);
- void setMistColorRed(float d);
- void setMistColorGreen(float d);
- void setMistColorBlue(float d);
-
-
-#ifdef WITH_CXX_GUARDEDALLOC
- MEM_CXX_CLASS_ALLOC_FUNCS("GE:BlenderWorldInfo")
-#endif
-};
-
-#endif /* __BLENDERWORLDINFO_H__ */
diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt
index 9c0d25e56ff..6d681dd166e 100644
--- a/source/gameengine/Converter/CMakeLists.txt
+++ b/source/gameengine/Converter/CMakeLists.txt
@@ -56,7 +56,7 @@ set(INC
set(INC_SYS
../../../intern/moto/include
../../../extern/recastnavigation/Detour/Include
- ../../../extern/Eigen3
+ ${EIGEN3_INCLUDE_DIRS}
${PTHREADS_INCLUDE_DIRS}
${BOOST_INCLUDE_DIR}
)
@@ -74,7 +74,6 @@ set(SRC
BL_ShapeActionActuator.cpp
BL_ShapeDeformer.cpp
BL_SkinDeformer.cpp
- BlenderWorldInfo.cpp
KX_BlenderScalarInterpolator.cpp
KX_BlenderSceneConverter.cpp
KX_ConvertActuators.cpp
@@ -96,7 +95,6 @@ set(SRC
BL_ShapeActionActuator.h
BL_ShapeDeformer.h
BL_SkinDeformer.h
- BlenderWorldInfo.h
KX_BlenderScalarInterpolator.h
KX_BlenderSceneConverter.h
KX_ConvertActuators.h
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 09cc74d717f..9e53d9e1569 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -58,7 +58,7 @@
#include "KX_LibLoadStatus.h"
#include "KX_BlenderScalarInterpolator.h"
#include "BL_BlenderDataConversion.h"
-#include "BlenderWorldInfo.h"
+#include "KX_WorldInfo.h"
/* This little block needed for linking to Blender... */
#ifdef WIN32
@@ -117,11 +117,9 @@ typedef struct ThreadInfo {
} ThreadInfo;
KX_BlenderSceneConverter::KX_BlenderSceneConverter(
- struct Main* maggie,
- class KX_KetsjiEngine* engine
- )
- : m_maggie(maggie),
- /*m_maggie_dyn(NULL),*/
+ Main *maggie,
+ KX_KetsjiEngine *engine)
+ :m_maggie(maggie),
m_ketsjiEngine(engine),
m_alwaysUseExpandFraming(false),
m_usemat(false),
@@ -134,13 +132,11 @@ KX_BlenderSceneConverter::KX_BlenderSceneConverter(
pthread_mutex_init(&m_threadinfo->merge_lock, NULL);
}
-
KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
{
// clears meshes, and hashmaps from blender to gameengine data
- int i;
// delete sumoshapes
-
+
if (m_threadinfo) {
vector<pthread_t>::iterator pit = m_threadinfo->threads.begin();
while (pit != m_threadinfo->threads.end()) {
@@ -153,104 +149,83 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
}
int numAdtLists = m_map_blender_to_gameAdtList.size();
- for (i=0; i<numAdtLists; i++) {
- BL_InterpolatorList *adtList= *m_map_blender_to_gameAdtList.at(i);
+ for (int i = 0; i < numAdtLists; i++) {
+ BL_InterpolatorList *adtList = *m_map_blender_to_gameAdtList.at(i);
delete (adtList);
}
- vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itw = m_worldinfos.begin();
+ vector<pair<KX_Scene *, KX_WorldInfo *> >::iterator itw = m_worldinfos.begin();
while (itw != m_worldinfos.end()) {
delete (*itw).second;
itw++;
}
m_worldinfos.clear();
- vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
+ vector<pair<KX_Scene *,RAS_IPolyMaterial *> >::iterator itp = m_polymaterials.begin();
while (itp != m_polymaterials.end()) {
- //m_polymat_cache.erase((*itp).second->GetBlenderMaterial());
delete (*itp).second;
itp++;
}
m_polymaterials.clear();
// delete after RAS_IPolyMaterial
- vector<pair<KX_Scene*,BL_Material *> >::iterator itmat = m_materials.begin();
+ vector<pair<KX_Scene *,BL_Material *> >::iterator itmat = m_materials.begin();
while (itmat != m_materials.end()) {
- //m_mat_cache.erase((*itmat).second->material);
delete (*itmat).second;
itmat++;
}
m_materials.clear();
-
- vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itm = m_meshobjects.begin();
+ vector<pair<KX_Scene *,RAS_MeshObject *> >::iterator itm = m_meshobjects.begin();
while (itm != m_meshobjects.end()) {
delete (*itm).second;
itm++;
}
m_meshobjects.clear();
-
/* free any data that was dynamically loaded */
- while (m_DynamicMaggie.size() != 0)
- {
+ while (m_DynamicMaggie.size() != 0) {
FreeBlendFile(m_DynamicMaggie[0]);
}
m_DynamicMaggie.clear();
}
-void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
+void KX_BlenderSceneConverter::SetNewFileName(const STR_String &filename)
{
m_newfilename = filename;
}
-
-
bool KX_BlenderSceneConverter::TryAndLoadNewFile()
{
bool result = false;
- // find the file
-/* if ()
- {
- result = true;
- }
- // if not, clear the newfilename
- else
- {
- m_newfilename = "";
- }
-*/
return result;
}
-Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String& name)
+Scene *KX_BlenderSceneConverter::GetBlenderSceneForName(const STR_String &name)
{
Scene *sce;
/**
* Find the specified scene by name, or NULL if nothing matches.
*/
- if ((sce= (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
+ if ((sce = (Scene *)BLI_findstring(&m_maggie->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
return sce;
- for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
- Main *main= *it;
+ for (vector<Main *>::iterator it=m_DynamicMaggie.begin(); !(it == m_DynamicMaggie.end()); it++) {
+ Main *main = *it;
if ((sce= (Scene *)BLI_findstring(&main->scene, name.ReadPtr(), offsetof(ID, name) + 2)))
return sce;
}
return NULL;
-
}
-void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
- class RAS_IRasterizer* rendertools,
- class RAS_ICanvas* canvas,
- bool libloading)
+void KX_BlenderSceneConverter::ConvertScene(KX_Scene *destinationscene, RAS_IRasterizer *rendertools,
+ RAS_ICanvas *canvas, bool libloading)
{
//find out which physics engine
Scene *blenderscene = destinationscene->GetBlenderScene();
@@ -266,13 +241,12 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
// when doing threaded conversion, so it's disabled for now.
// SG_SetActiveStage(SG_STAGE_CONVERTER);
- switch (blenderscene->gm.physicsEngine)
- {
+ switch (blenderscene->gm.physicsEngine) {
#ifdef WITH_BULLET
case WOPHY_BULLET:
{
SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
- int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
+ int visualizePhysics = SYS_GetCommandLineInt(syshandle, "show_physics", 0);
phy_env = CcdPhysicsEnvironment::Create(blenderscene, visualizePhysics);
physics_engine = UseBullet;
@@ -291,7 +265,8 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
destinationscene->SetPhysicsEnvironment(phy_env);
- BL_ConvertBlenderObjects(m_maggie,
+ BL_ConvertBlenderObjects(
+ m_maggie,
destinationscene,
m_ketsjiEngine,
physics_engine,
@@ -299,8 +274,7 @@ void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
canvas,
this,
m_alwaysUseExpandFraming,
- libloading
- );
+ libloading);
//These lookup are not needed during game
m_map_blender_to_gameactuator.clear();
@@ -326,30 +300,32 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
// delete the scene first as it will stop the use of entities
delete scene;
// delete the entities of this scene
- vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
+ vector<pair<KX_Scene *, KX_WorldInfo *> >::iterator worldit;
size = m_worldinfos.size();
- for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
+ for (i = 0, worldit = m_worldinfos.begin(); i < size; ) {
if ((*worldit).first == scene) {
delete (*worldit).second;
*worldit = m_worldinfos.back();
m_worldinfos.pop_back();
size--;
- } else {
+ }
+ else {
i++;
worldit++;
}
}
- vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit;
+ vector<pair<KX_Scene *, RAS_IPolyMaterial *> >::iterator polymit;
size = m_polymaterials.size();
- for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
+ for (i = 0, polymit = m_polymaterials.begin(); i < size; ) {
if ((*polymit).first == scene) {
m_polymat_cache[scene].erase((*polymit).second->GetBlenderMaterial());
delete (*polymit).second;
*polymit = m_polymaterials.back();
m_polymaterials.pop_back();
size--;
- } else {
+ }
+ else {
i++;
polymit++;
}
@@ -357,16 +333,17 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
m_polymat_cache.erase(scene);
- vector<pair<KX_Scene*,BL_Material*> >::iterator matit;
+ vector<pair<KX_Scene *, BL_Material *> >::iterator matit;
size = m_materials.size();
- for (i=0, matit=m_materials.begin(); i<size; ) {
+ for (i = 0, matit = m_materials.begin(); i < size; ) {
if ((*matit).first == scene) {
m_mat_cache[scene].erase((*matit).second->material);
delete (*matit).second;
*matit = m_materials.back();
m_materials.pop_back();
size--;
- } else {
+ }
+ else {
i++;
matit++;
}
@@ -374,15 +351,16 @@ void KX_BlenderSceneConverter::RemoveScene(KX_Scene *scene)
m_mat_cache.erase(scene);
- vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
+ vector<pair<KX_Scene *, RAS_MeshObject *> >::iterator meshit;
size = m_meshobjects.size();
- for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
+ for (i = 0, meshit = m_meshobjects.begin(); i < size; ) {
if ((*meshit).first == scene) {
delete (*meshit).second;
*meshit = m_meshobjects.back();
m_meshobjects.pop_back();
size--;
- } else {
+ }
+ else {
i++;
meshit++;
}
@@ -425,43 +403,34 @@ bool KX_BlenderSceneConverter::GetCacheMaterials()
void KX_BlenderSceneConverter::RegisterBlenderMaterial(BL_Material *mat)
{
// First make sure we don't register the material twice
- vector<pair<KX_Scene*,BL_Material*> >::iterator it;
+ vector<pair<KX_Scene *, BL_Material *> >::iterator it;
for (it = m_materials.begin(); it != m_materials.end(); ++it)
if (it->second == mat)
return;
- m_materials.push_back(pair<KX_Scene*,BL_Material *>(m_currentScene,mat));
+ m_materials.push_back(pair<KX_Scene *, BL_Material *> (m_currentScene, mat));
}
-
-
-void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(
- bool to_what)
+void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(bool to_what)
{
m_alwaysUseExpandFraming= to_what;
}
-
-
-void KX_BlenderSceneConverter::RegisterGameObject(
- KX_GameObject *gameobject,
- struct Object *for_blenderobject)
+void KX_BlenderSceneConverter::RegisterGameObject(KX_GameObject *gameobject, Object *for_blenderobject)
{
/* only maintained while converting, freed during game runtime */
- m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
+ m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject), gameobject);
}
/* only need to run this during conversion since
* m_map_blender_to_gameobject is freed after conversion */
-void KX_BlenderSceneConverter::UnregisterGameObject(
- KX_GameObject *gameobject)
+void KX_BlenderSceneConverter::UnregisterGameObject(KX_GameObject *gameobject)
{
- struct Object *bobp= gameobject->GetBlenderObject();
+ Object *bobp = gameobject->GetBlenderObject();
if (bobp) {
CHashedPtr bptr(bobp);
- KX_GameObject **gobp= m_map_blender_to_gameobject[bptr];
- if (gobp && *gobp == gameobject)
- {
+ KX_GameObject **gobp = m_map_blender_to_gameobject[bptr];
+ if (gobp && *gobp == gameobject) {
// also maintain m_map_blender_to_gameobject if the gameobject
// being removed is matching the blender object
m_map_blender_to_gameobject.remove(bptr);
@@ -469,47 +438,41 @@ void KX_BlenderSceneConverter::UnregisterGameObject(
}
}
-KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
- struct Object *for_blenderobject)
+KX_GameObject *KX_BlenderSceneConverter::FindGameObject(Object *for_blenderobject)
{
- KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
-
- return obp?*obp:NULL;
+ KX_GameObject **obp = m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
+
+ return obp ? *obp : NULL;
}
-void KX_BlenderSceneConverter::RegisterGameMesh(
- RAS_MeshObject *gamemesh,
- struct Mesh *for_blendermesh)
+void KX_BlenderSceneConverter::RegisterGameMesh(RAS_MeshObject *gamemesh, Mesh *for_blendermesh)
{
if (for_blendermesh) { /* dynamically loaded meshes we don't want to keep lookups for */
m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
}
- m_meshobjects.push_back(pair<KX_Scene*,RAS_MeshObject*>(m_currentScene,gamemesh));
+ m_meshobjects.push_back(pair<KX_Scene *, RAS_MeshObject *> (m_currentScene,gamemesh));
}
-
-
-RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
- struct Mesh *for_blendermesh/*,
- unsigned int onlayer*/)
+RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(Mesh *for_blendermesh)
{
- RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
-
- if (meshp/* && onlayer==(*meshp)->GetLightLayer()*/) {
+ RAS_MeshObject **meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
+
+ if (meshp) {
return *meshp;
- } else {
+ }
+ else {
return NULL;
}
-}
+}
void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
{
// First make sure we don't register the material twice
- vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator it;
+ vector<pair<KX_Scene *, RAS_IPolyMaterial *> >::iterator it;
for (it = m_polymaterials.begin(); it != m_polymaterials.end(); ++it)
if (it->second == polymat)
return;
- m_polymaterials.push_back(pair<KX_Scene*,RAS_IPolyMaterial*>(m_currentScene,polymat));
+ m_polymaterials.push_back(pair<KX_Scene *, RAS_IPolyMaterial *> (m_currentScene, polymat));
}
void KX_BlenderSceneConverter::CachePolyMaterial(KX_Scene *scene, Material *mat, RAS_IPolyMaterial *polymat)
@@ -518,94 +481,82 @@ void KX_BlenderSceneConverter::CachePolyMaterial(KX_Scene *scene, Material *mat,
m_polymat_cache[scene][mat] = polymat;
}
-RAS_IPolyMaterial *KX_BlenderSceneConverter::FindCachedPolyMaterial(KX_Scene *scene, struct Material *mat)
+RAS_IPolyMaterial *KX_BlenderSceneConverter::FindCachedPolyMaterial(KX_Scene *scene, Material *mat)
{
return (m_use_mat_cache) ? m_polymat_cache[scene][mat] : NULL;
}
-void KX_BlenderSceneConverter::CacheBlenderMaterial(KX_Scene *scene, struct Material *mat, BL_Material *blmat)
+void KX_BlenderSceneConverter::CacheBlenderMaterial(KX_Scene *scene, Material *mat, BL_Material *blmat)
{
if (m_use_mat_cache && mat)
m_mat_cache[scene][mat] = blmat;
}
-
-BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(KX_Scene *scene, struct Material *mat)
+BL_Material *KX_BlenderSceneConverter::FindCachedBlenderMaterial(KX_Scene *scene, 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, 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(bAction *for_act)
{
BL_InterpolatorList **listp = m_map_blender_to_gameAdtList[CHashedPtr(for_act)];
- return listp?*listp:NULL;
+ return listp ? *listp : NULL;
}
-
-void KX_BlenderSceneConverter::RegisterGameActuator(SCA_IActuator *act, struct bActuator *for_actuator)
+void KX_BlenderSceneConverter::RegisterGameActuator(SCA_IActuator *act, 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(bActuator *for_actuator)
{
SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
- return actp?*actp:NULL;
+ return actp ? *actp : NULL;
}
-
-void KX_BlenderSceneConverter::RegisterGameController(SCA_IController *cont, struct bController *for_controller)
+void KX_BlenderSceneConverter::RegisterGameController(SCA_IController *cont, 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(bController *for_controller)
{
SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
- return contp?*contp:NULL;
+ return contp ? *contp : NULL;
}
-
-
void KX_BlenderSceneConverter::RegisterWorldInfo(KX_WorldInfo *worldinfo)
{
- m_worldinfos.push_back(pair<KX_Scene*,KX_WorldInfo*>(m_currentScene,worldinfo));
+ m_worldinfos.push_back(pair<KX_Scene *, KX_WorldInfo *> (m_currentScene, worldinfo));
}
-void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
+void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
{
//TODO this entire function is deprecated, written for 2.4x
//the functionality should be rewritten, currently it does nothing
- KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
+ KX_SceneList *scenes = m_ketsjiEngine->CurrentScenes();
int numScenes = scenes->size();
int i;
- for (i=0;i<numScenes;i++)
- {
- KX_Scene* scene = scenes->at(i);
- //PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
- CListValue* parentList = scene->GetRootParentList();
+ for (i = 0; i < numScenes; i++) {
+ KX_Scene *scene = scenes->at(i);
+ CListValue *parentList = scene->GetRootParentList();
int numObjects = parentList->GetCount();
int g;
- for (g=0;g<numObjects;g++)
- {
- KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
+ for (g = 0; g < numObjects; g++) {
+ KX_GameObject *gameObj = (KX_GameObject *)parentList->GetValue(g);
if (gameObj->IsRecordAnimation()) {
-
- Object* blenderObject = gameObj->GetBlenderObject();
- if (blenderObject)
- {
+ Object *blenderObject = gameObj->GetBlenderObject();
+ if (blenderObject) {
#if 0
//erase existing ipo's
Ipo* ipo = blenderObject->ipo;//findIpoForName(blenderObject->id.name+2);
- if (ipo)
- { //clear the curve data
+ if (ipo) { //clear the curve data
if (clearIpo) {//rcruiz
IpoCurve *icu1;
@@ -630,64 +581,52 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
localDel_ipoCurve( tmpicu );
}
}
- } else
- { ipo = NULL; // XXX add_ipo(blenderObject->id.name+2, ID_OB);
+ }
+ else {
+ ipo = NULL; // XXX add_ipo(blenderObject->id.name+2, ID_OB);
blenderObject->ipo = ipo;
-
}
#endif
}
}
-
}
-
-
}
-
-
-
}
-void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo()
+void KX_BlenderSceneConverter::resetNoneDynamicObjectToIpo()
{
//TODO the functionality should be rewritten
}
-
- ///this generates ipo curves for position, rotation, allowing to use game physics in animation
-void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
+// this generates ipo curves for position, rotation, allowing to use game physics in animation
+void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
{
-
- KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
+ KX_SceneList *scenes = m_ketsjiEngine->CurrentScenes();
int numScenes = scenes->size();
int i;
- for (i=0;i<numScenes;i++)
- {
- KX_Scene* scene = scenes->at(i);
+ for (i = 0; i < numScenes; i++) {
+ KX_Scene *scene = scenes->at(i);
//PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
- CListValue* parentList = scene->GetObjectList();
+ CListValue *parentList = scene->GetObjectList();
int numObjects = parentList->GetCount();
int g;
- for (g=0;g<numObjects;g++)
- {
- KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
- Object* blenderObject = gameObj->GetBlenderObject();
- if (blenderObject && blenderObject->parent==NULL && gameObj->IsRecordAnimation()) {
-
- if (blenderObject->adt==NULL)
- BKE_id_add_animdata(&blenderObject->id);
-
- if (blenderObject->adt)
- {
- const MT_Point3& position = gameObj->NodeGetWorldPosition();
+ for (g = 0; g < numObjects; g++) {
+ KX_GameObject *gameObj = (KX_GameObject *)parentList->GetValue(g);
+ Object *blenderObject = gameObj->GetBlenderObject();
+ if (blenderObject && blenderObject->parent == NULL && gameObj->IsRecordAnimation()) {
+ if (blenderObject->adt == NULL)
+ BKE_animdata_add_id(&blenderObject->id);
+
+ if (blenderObject->adt) {
+ const MT_Point3 &position = gameObj->NodeGetWorldPosition();
//const MT_Vector3& scale = gameObj->NodeGetWorldScaling();
- const MT_Matrix3x3& orn = gameObj->NodeGetWorldOrientation();
+ const MT_Matrix3x3 &orn = gameObj->NodeGetWorldOrientation();
position.getValue(blenderObject->loc);
float tmat[3][3];
- for (int r=0;r<3;r++)
- for (int c=0;c<3;c++)
+ for (int r = 0; r < 3; r++)
+ for (int c = 0; c < 3; c++)
tmat[r][c] = (float)orn[c][r];
mat3_to_compatible_eul(blenderObject->rot, blenderObject->rot, tmat);
@@ -772,27 +711,22 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
}
}
-
-void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
+void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
{
-
- KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
+ KX_SceneList *scenes = m_ketsjiEngine->CurrentScenes();
int numScenes = scenes->size();
int i;
- for (i=0;i<numScenes;i++)
- {
- KX_Scene* scene = scenes->at(i);
+ for (i = 0; i < numScenes; i++) {
+ KX_Scene *scene = scenes->at(i);
//PHY_IPhysicsEnvironment* physEnv = scene->GetPhysicsEnvironment();
- CListValue* parentList = scene->GetRootParentList();
+ CListValue *parentList = scene->GetRootParentList();
int numObjects = parentList->GetCount();
int g;
- for (g=0;g<numObjects;g++)
- {
- KX_GameObject* gameObj = (KX_GameObject*)parentList->GetValue(g);
+ for (g = 0; g < numObjects; g++) {
+ KX_GameObject *gameObj = (KX_GameObject *)parentList->GetValue(g);
if (gameObj->IsRecordAnimation()) {
- Object* blenderObject = gameObj->GetBlenderObject();
- if (blenderObject && blenderObject->adt)
- {
+ Object *blenderObject = gameObj->GetBlenderObject();
+ if (blenderObject && blenderObject->adt) {
bAction *act = verify_adt_action(&blenderObject->id, false);
FCurve *fcu;
@@ -832,14 +766,14 @@ PyObject *KX_BlenderSceneConverter::GetPyNamespace()
}
#endif
-vector<Main*> &KX_BlenderSceneConverter::GetMainDynamic()
+vector<Main *> &KX_BlenderSceneConverter::GetMainDynamic()
{
return m_DynamicMaggie;
}
-Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path)
+Main *KX_BlenderSceneConverter::GetMainDynamicPath(const char *path)
{
- for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++)
+ for (vector<Main *>::iterator it = m_DynamicMaggie.begin(); !(it == m_DynamicMaggie.end()); it++)
if (BLI_path_cmp((*it)->name, path) == 0)
return *it;
@@ -848,22 +782,21 @@ Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path)
void KX_BlenderSceneConverter::MergeAsyncLoads()
{
- vector<KX_Scene*> *merge_scenes;
+ vector<KX_Scene *> *merge_scenes;
- vector<KX_LibLoadStatus*>::iterator mit;
- vector<KX_Scene*>::iterator sit;
+ vector<KX_LibLoadStatus *>::iterator mit;
+ vector<KX_Scene *>::iterator sit;
pthread_mutex_lock(&m_threadinfo->merge_lock);
- for (mit=m_mergequeue.begin(); mit!=m_mergequeue.end(); ++mit) {
- merge_scenes = (vector<KX_Scene*>*)(*mit)->GetData();
+ for (mit = m_mergequeue.begin(); mit != m_mergequeue.end(); ++mit) {
+ merge_scenes = (vector<KX_Scene *> *)(*mit)->GetData();
for (sit=merge_scenes->begin(); sit!=merge_scenes->end(); ++sit) {
(*mit)->GetMergeScene()->MergeScene(*sit);
delete (*sit);
}
-
delete merge_scenes;
(*mit)->SetData(NULL);
@@ -885,17 +818,17 @@ void KX_BlenderSceneConverter::AddScenesToMergeQueue(KX_LibLoadStatus *status)
static void *async_convert(void *ptr)
{
KX_Scene *new_scene = NULL;
- KX_LibLoadStatus *status = (KX_LibLoadStatus*)ptr;
- vector<Scene*> *scenes = (vector<Scene*>*)status->GetData();
- vector<KX_Scene*> *merge_scenes = new vector<KX_Scene*>(); // Deleted in MergeAsyncLoads
+ KX_LibLoadStatus *status = (KX_LibLoadStatus *)ptr;
+ vector<Scene *> *scenes = (vector<Scene *> *)status->GetData();
+ vector<KX_Scene *> *merge_scenes = new vector<KX_Scene *>(); // Deleted in MergeAsyncLoads
- for (unsigned int i=0; i<scenes->size(); ++i) {
+ for (unsigned int i = 0; i < scenes->size(); ++i) {
new_scene = status->GetEngine()->CreateScene((*scenes)[i], true);
if (new_scene)
merge_scenes->push_back(new_scene);
- status->AddProgress((1.f/scenes->size())*0.9f); // We'll call conversion 90% and merging 10% for now
+ status->AddProgress((1.0f / scenes->size()) * 0.9f); // We'll call conversion 90% and merging 10% for now
}
delete scenes;
@@ -922,28 +855,21 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFilePath(const char *filepa
return LinkBlendFile(bpy_openlib, filepath, group, scene_merge, err_str, options);
}
-static void load_datablocks(Main *main_newlib, BlendHandle *bpy_openlib, const char *path, int idcode)
+static void load_datablocks(Main *main_tmp, BlendHandle *bpy_openlib, const char *path, int idcode)
{
- Main *main_tmp= NULL; /* created only for linking, then freed */
LinkNode *names = NULL;
- short flag= 0; /* don't need any special options */
-
- /* here appending/linking starts */
- main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path);
int totnames_dummy;
- names = BLO_blendhandle_get_datablock_names( bpy_openlib, idcode, &totnames_dummy);
+ names = BLO_blendhandle_get_datablock_names(bpy_openlib, idcode, &totnames_dummy);
- int i=0;
- LinkNode *n= names;
+ int i = 0;
+ LinkNode *n = names;
while (n) {
BLO_library_append_named_part(main_tmp, &bpy_openlib, (char *)n->link, idcode);
- n= (LinkNode *)n->next;
+ n = (LinkNode *)n->next;
i++;
}
BLI_linklist_free(names, free); /* free linklist *and* each node's data */
-
- BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag);
}
KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openlib, const char *path, char *group, KX_Scene *scene_merge, char **err_str, short options)
@@ -956,42 +882,48 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
// TIMEIT_START(bge_link_blend_file);
KX_LibLoadStatus *status;
-
+
/* only scene and mesh supported right now */
- if (idcode!=ID_SCE && idcode!=ID_ME &&idcode!=ID_AC) {
+ if (idcode != ID_SCE && idcode != ID_ME && idcode != ID_AC) {
snprintf(err_local, sizeof(err_local), "invalid ID type given \"%s\"\n", group);
- *err_str= err_local;
+ *err_str = err_local;
BLO_blendhandle_close(bpy_openlib);
return NULL;
}
if (GetMainDynamicPath(path)) {
snprintf(err_local, sizeof(err_local), "blend file already open \"%s\"\n", path);
- *err_str= err_local;
+ *err_str = err_local;
BLO_blendhandle_close(bpy_openlib);
return NULL;
}
- if (bpy_openlib==NULL) {
+ if (bpy_openlib == NULL) {
snprintf(err_local, sizeof(err_local), "could not open blendfile \"%s\"\n", path);
- *err_str= err_local;
+ *err_str = err_local;
return NULL;
}
-
+
main_newlib = BKE_main_new();
BKE_reports_init(&reports, RPT_STORE);
- load_datablocks(main_newlib, bpy_openlib, path, idcode);
+ short flag = 0; /* don't need any special options */
+ /* created only for linking, then freed */
+ Main *main_tmp = BLO_library_append_begin(main_newlib, &bpy_openlib, (char *)path);
+
+ load_datablocks(main_tmp, bpy_openlib, path, idcode);
- if (idcode==ID_SCE && options & LIB_LOAD_LOAD_SCRIPTS) {
- load_datablocks(main_newlib, bpy_openlib, path, ID_TXT);
+ if (idcode == ID_SCE && options & LIB_LOAD_LOAD_SCRIPTS) {
+ load_datablocks(main_tmp, bpy_openlib, path, ID_TXT);
}
/* now do another round of linking for Scenes so all actions are properly loaded */
- if (idcode==ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) {
- load_datablocks(main_newlib, bpy_openlib, path, ID_AC);
+ if (idcode == ID_SCE && options & LIB_LOAD_LOAD_ACTIONS) {
+ load_datablocks(main_tmp, bpy_openlib, path, ID_AC);
}
-
+
+ BLO_library_append_end(NULL, main_tmp, &bpy_openlib, idcode, flag);
+
BLO_blendhandle_close(bpy_openlib);
BKE_reports_clear(&reports);
@@ -1004,42 +936,43 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
status = new KX_LibLoadStatus(this, m_ketsjiEngine, scene_merge, path);
- if (idcode==ID_ME) {
+ if (idcode == ID_ME) {
/* Convert all new meshes into BGE meshes */
- ID* mesh;
+ ID *mesh;
- for (mesh= (ID *)main_newlib->mesh.first; mesh; mesh= (ID *)mesh->next ) {
+ for (mesh = (ID *)main_newlib->mesh.first; mesh; mesh = (ID *)mesh->next ) {
if (options & LIB_LOAD_VERBOSE)
- printf("MeshName: %s\n", mesh->name+2);
+ printf("MeshName: %s\n", mesh->name + 2);
RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)mesh, NULL, scene_merge, this, false); // For now only use the libloading option for scenes, which need to handle materials/shaders
- scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
+ scene_merge->GetLogicManager()->RegisterMeshName(meshobj->GetName(), meshobj);
}
}
- else if (idcode==ID_AC) {
+ else if (idcode == ID_AC) {
/* Convert all actions */
ID *action;
- for (action= (ID *)main_newlib->action.first; action; action= (ID *)action->next) {
+ for (action= (ID *)main_newlib->action.first; action; action = (ID *)action->next) {
if (options & LIB_LOAD_VERBOSE)
- printf("ActionName: %s\n", action->name+2);
- scene_merge->GetLogicManager()->RegisterActionName(action->name+2, action);
+ printf("ActionName: %s\n", action->name + 2);
+ scene_merge->GetLogicManager()->RegisterActionName(action->name + 2, action);
}
}
- else if (idcode==ID_SCE) {
+ else if (idcode == ID_SCE) {
/* Merge all new linked in scene into the existing one */
ID *scene;
// scenes gets deleted by the thread when it's done using it (look in async_convert())
- vector<Scene*> *scenes = (options & LIB_LOAD_ASYNC) ? new vector<Scene*>() : NULL;
+ vector<Scene *> *scenes = (options & LIB_LOAD_ASYNC) ? new vector<Scene *>() : NULL;
- for (scene= (ID *)main_newlib->scene.first; scene; scene= (ID *)scene->next ) {
+ for (scene = (ID *)main_newlib->scene.first; scene; scene = (ID *)scene->next ) {
if (options & LIB_LOAD_VERBOSE)
- printf("SceneName: %s\n", scene->name+2);
+ printf("SceneName: %s\n", scene->name + 2);
if (options & LIB_LOAD_ASYNC) {
- scenes->push_back((Scene*)scene);
- } else {
+ scenes->push_back((Scene *)scene);
+ }
+ else {
/* merge into the base scene */
- KX_Scene* other= m_ketsjiEngine->CreateScene((Scene *)scene, true);
+ KX_Scene* other = m_ketsjiEngine->CreateScene((Scene *)scene, true);
scene_merge->MergeScene(other);
// RemoveScene(other); // Don't run this, it frees the entire scene converter data, just delete the scene
@@ -1050,7 +983,7 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
if (options & LIB_LOAD_ASYNC) {
pthread_t id;
status->SetData(scenes);
- pthread_create(&id, NULL, &async_convert, (void*)status);
+ pthread_create(&id, NULL, &async_convert, (void *)status);
m_threadinfo->threads.push_back(id);
}
@@ -1064,17 +997,16 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
if (options & LIB_LOAD_LOAD_ACTIONS) {
ID *action;
- for (action= (ID *)main_newlib->action.first; action; action= (ID *)action->next) {
+ for (action = (ID *)main_newlib->action.first; action; action = (ID *)action->next) {
if (options & LIB_LOAD_VERBOSE)
- printf("ActionName: %s\n", action->name+2);
- scene_merge->GetLogicManager()->RegisterActionName(action->name+2, action);
+ printf("ActionName: %s\n", action->name + 2);
+ scene_merge->GetLogicManager()->RegisterActionName(action->name + 2, action);
}
}
}
if (!(options & LIB_LOAD_ASYNC))
status->Finish();
-
// TIMEIT_END(bge_link_blend_file);
@@ -1084,22 +1016,22 @@ KX_LibLoadStatus *KX_BlenderSceneConverter::LinkBlendFile(BlendHandle *bpy_openl
/* Note m_map_*** are all ok and don't need to be freed
* most are temp and NewRemoveObject frees m_map_gameobject_to_blender */
-bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
+bool KX_BlenderSceneConverter::FreeBlendFile(Main *maggie)
{
- int maggie_index= -1;
- int i=0;
+ int maggie_index = -1;
+ int i = 0;
- if (maggie==NULL)
+ if (maggie == NULL)
return false;
/* tag all false except the one we remove */
- for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
- Main *main= *it;
+ for (vector<Main *>::iterator it = m_DynamicMaggie.begin(); !(it == m_DynamicMaggie.end()); it++) {
+ Main *main = *it;
if (main != maggie) {
BKE_main_id_tag_all(main, false);
}
else {
- maggie_index= i;
+ maggie_index = i;
}
i++;
}
@@ -1111,15 +1043,12 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index);
BKE_main_id_tag_all(maggie, true);
-
/* free all tagged objects */
- KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes();
+ KX_SceneList *scenes = m_ketsjiEngine->CurrentScenes();
int numScenes = scenes->size();
-
- for (int scene_idx=0;scene_idx<numScenes;scene_idx++)
- {
- KX_Scene* scene = scenes->at(scene_idx);
+ for (int scene_idx = 0; scene_idx < numScenes; scene_idx++) {
+ KX_Scene *scene = scenes->at(scene_idx);
if (IS_TAGGED(scene->GetBlenderScene())) {
m_ketsjiEngine->RemoveScene(scene->GetName());
m_mat_cache.erase(scene);
@@ -1128,16 +1057,13 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
numScenes--;
}
else {
-
/* in case the mesh might be refered to later */
{
- CTR_Map<STR_HashedString,void*> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap();
+ CTR_Map<STR_HashedString, void *> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap();
- for (int i=0; i<mapStringToMeshes.size(); i++)
- {
- RAS_MeshObject *meshobj= (RAS_MeshObject *) *mapStringToMeshes.at(i);
- if (meshobj && IS_TAGGED(meshobj->GetMesh()))
- {
+ for (int i = 0; i < mapStringToMeshes.size(); i++) {
+ RAS_MeshObject *meshobj = (RAS_MeshObject *) *mapStringToMeshes.at(i);
+ if (meshobj && IS_TAGGED(meshobj->GetMesh())) {
STR_HashedString mn = meshobj->GetName();
mapStringToMeshes.remove(mn);
m_map_mesh_to_gamemesh.remove(CHashedPtr(meshobj->GetMesh()));
@@ -1148,15 +1074,13 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
/* Now unregister actions */
{
- CTR_Map<STR_HashedString,void*> &mapStringToActions = scene->GetLogicManager()->GetActionMap();
+ CTR_Map<STR_HashedString, void *> &mapStringToActions = scene->GetLogicManager()->GetActionMap();
- for (int i=0; i<mapStringToActions.size(); i++)
- {
- ID *action= (ID*) *mapStringToActions.at(i);
+ for (int i = 0; i < mapStringToActions.size(); i++) {
+ ID *action = (ID*) *mapStringToActions.at(i);
- if (IS_TAGGED(action))
- {
- STR_HashedString an = action->name+2;
+ if (IS_TAGGED(action)) {
+ STR_HashedString an = action->name + 2;
mapStringToActions.remove(an);
i--;
}
@@ -1166,16 +1090,13 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
//scene->FreeTagged(); /* removed tagged objects and meshes*/
CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL};
- for (int ob_ls_idx=0; obj_lists[ob_ls_idx]; ob_ls_idx++)
- {
- CListValue *obs= obj_lists[ob_ls_idx];
- RAS_MeshObject* mesh;
+ for (int ob_ls_idx = 0; obj_lists[ob_ls_idx]; ob_ls_idx++) {
+ CListValue *obs = obj_lists[ob_ls_idx];
+ RAS_MeshObject *mesh;
- for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++)
- {
- KX_GameObject* gameobj = (KX_GameObject*)obs->GetValue(ob_idx);
+ for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++) {
+ KX_GameObject *gameobj = (KX_GameObject*)obs->GetValue(ob_idx);
if (IS_TAGGED(gameobj->GetBlenderObject())) {
-
int size_before = obs->GetCount();
/* Eventually calls RemoveNodeDestructObject
@@ -1190,9 +1111,9 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
}
else {
/* free the mesh, we could be referecing a linked one! */
- int mesh_index= gameobj->GetMeshCount();
+ int mesh_index = gameobj->GetMeshCount();
while (mesh_index--) {
- mesh= gameobj->GetMesh(mesh_index);
+ mesh = gameobj->GetMesh(mesh_index);
if (IS_TAGGED(mesh->GetMesh())) {
gameobj->RemoveMeshes(); /* XXX - slack, should only remove meshes that are library items but mostly objects only have 1 mesh */
break;
@@ -1210,11 +1131,9 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
}
/* make sure action actuators are not referencing tagged actions */
- for (unsigned int act_idx=0; act_idx<gameobj->GetActuators().size(); act_idx++)
- {
- if (gameobj->GetActuators()[act_idx]->IsType(SCA_IActuator::KX_ACT_ACTION))
- {
- BL_ActionActuator *act = (BL_ActionActuator*)gameobj->GetActuators()[act_idx];
+ for (unsigned int act_idx = 0; act_idx < gameobj->GetActuators().size(); act_idx++) {
+ if (gameobj->GetActuators()[act_idx]->IsType(SCA_IActuator::KX_ACT_ACTION)) {
+ BL_ActionActuator *act = (BL_ActionActuator *)gameobj->GetActuators()[act_idx];
if (IS_TAGGED(act->GetAction()))
act->SetAction(NULL);
}
@@ -1225,7 +1144,6 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
}
}
-
int size;
// delete the entities of this scene
@@ -1248,24 +1166,24 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
/* Worlds don't reference original blender data so we need to make a set from them */
- typedef std::set<KX_WorldInfo*> KX_WorldInfoSet;
+ typedef std::set<KX_WorldInfo *> KX_WorldInfoSet;
KX_WorldInfoSet worldset;
- for (int scene_idx=0;scene_idx<numScenes;scene_idx++)
- {
- KX_Scene* scene = scenes->at(scene_idx);
+ for (int scene_idx = 0; scene_idx < numScenes; scene_idx++) {
+ KX_Scene *scene = scenes->at(scene_idx);
if (scene->GetWorldInfo())
- worldset.insert( scene->GetWorldInfo() );
+ worldset.insert(scene->GetWorldInfo());
}
- vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
+ vector<pair<KX_Scene *, KX_WorldInfo *> >::iterator worldit;
size = m_worldinfos.size();
- for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
+ for (i = 0, worldit = m_worldinfos.begin(); i < size;) {
if ((*worldit).second && (worldset.count((*worldit).second)) == 0) {
delete (*worldit).second;
*worldit = m_worldinfos.back();
m_worldinfos.pop_back();
size--;
- } else {
+ }
+ else {
i++;
worldit++;
}
@@ -1273,20 +1191,15 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
worldset.clear();
/* done freeing the worlds */
-
-
-
- vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit;
+ vector<pair<KX_Scene *, RAS_IPolyMaterial *> >::iterator polymit;
size = m_polymaterials.size();
+ for (i = 0, polymit = m_polymaterials.begin(); i < size; ) {
+ RAS_IPolyMaterial *mat = (*polymit).second;
+ Material *bmat = NULL;
-
- for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
- RAS_IPolyMaterial *mat= (*polymit).second;
- Material *bmat= NULL;
-
- KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat);
- bmat= bl_mat->GetBlenderMaterial();
+ KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial *>(mat);
+ bmat = bl_mat->GetBlenderMaterial();
if (IS_TAGGED(bmat)) {
/* only remove from bucket */
@@ -1297,63 +1210,57 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
polymit++;
}
-
-
- for (i=0, polymit=m_polymaterials.begin(); i<size; ) {
- RAS_IPolyMaterial *mat= (*polymit).second;
- Material *bmat= NULL;
+ for (i = 0, polymit = m_polymaterials.begin(); i < size; ) {
+ RAS_IPolyMaterial *mat = (*polymit).second;
+ Material *bmat = NULL;
KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat);
- bmat= bl_mat->GetBlenderMaterial();
-
- if (bmat) {
- //printf("FOUND MAT '%s' !!! ", ((ID*)bmat)->name+2);
- }
- else {
- //printf("LOST MAT !!!");
- }
+ bmat = bl_mat->GetBlenderMaterial();
if (IS_TAGGED(bmat)) {
+ // Remove the poly material coresponding to this Blender Material.
+ m_polymat_cache[polymit->first].erase(bmat);
delete (*polymit).second;
*polymit = m_polymaterials.back();
m_polymaterials.pop_back();
size--;
- //printf("tagged !\n");
} else {
i++;
polymit++;
- //printf("(un)tagged !\n");
}
}
- vector<pair<KX_Scene*,BL_Material*> >::iterator matit;
+ vector<pair<KX_Scene *, BL_Material *> >::iterator matit;
size = m_materials.size();
- for (i=0, matit=m_materials.begin(); i<size; ) {
- BL_Material *mat= (*matit).second;
+ for (i = 0, matit = m_materials.begin(); i < size; ) {
+ BL_Material *mat = (*matit).second;
if (IS_TAGGED(mat->material)) {
+ // Remove the bl material coresponding to this Blender Material.
+ m_mat_cache[matit->first].erase(mat->material);
delete (*matit).second;
*matit = m_materials.back();
m_materials.pop_back();
size--;
- } else {
+ }
+ else {
i++;
matit++;
}
}
- vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit;
+ vector<pair<KX_Scene *, RAS_MeshObject *> >::iterator meshit;
RAS_BucketManager::BucketList::iterator bit;
list<RAS_MeshSlot>::iterator msit;
RAS_BucketManager::BucketList buckets;
size = m_meshobjects.size();
- for (i=0, meshit=m_meshobjects.begin(); i<size; ) {
- RAS_MeshObject *me= (*meshit).second;
+ for (i = 0, meshit = m_meshobjects.begin(); i < size;) {
+ RAS_MeshObject *me = (*meshit).second;
if (IS_TAGGED(me->GetMesh())) {
// Before deleting the mesh object, make sure the rasterizer is
// no longer referencing it.
buckets = meshit->first->GetBucketManager()->GetSolidBuckets();
- for (bit=buckets.begin(); bit!=buckets.end(); bit++) {
+ for (bit = buckets.begin(); bit != buckets.end(); bit++) {
msit = (*bit)->msBegin();
while (msit != (*bit)->msEnd()) {
@@ -1366,7 +1273,7 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
// And now the alpha buckets
buckets = meshit->first->GetBucketManager()->GetAlphaBuckets();
- for (bit=buckets.begin(); bit!=buckets.end(); bit++) {
+ for (bit = buckets.begin(); bit != buckets.end(); bit++) {
msit = (*bit)->msBegin();
while (msit != (*bit)->msEnd()) {
@@ -1382,7 +1289,8 @@ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie)
*meshit = m_meshobjects.back();
m_meshobjects.pop_back();
size--;
- } else {
+ }
+ else {
i++;
meshit++;
}
@@ -1409,24 +1317,23 @@ bool KX_BlenderSceneConverter::FreeBlendFile(const char *path)
bool KX_BlenderSceneConverter::MergeScene(KX_Scene *to, KX_Scene *from)
{
-
{
- vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator itp = m_worldinfos.begin();
+ vector<pair<KX_Scene *, KX_WorldInfo *> >::iterator itp = m_worldinfos.begin();
while (itp != m_worldinfos.end()) {
- if ((*itp).first==from)
- (*itp).first= to;
+ if ((*itp).first == from)
+ (*itp).first = to;
itp++;
}
}
{
- vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator itp = m_polymaterials.begin();
+ vector<pair<KX_Scene *, RAS_IPolyMaterial *> >::iterator itp = m_polymaterials.begin();
while (itp != m_polymaterials.end()) {
- if ((*itp).first==from) {
- (*itp).first= to;
+ if ((*itp).first == from) {
+ (*itp).first = to;
/* also switch internal data */
- RAS_IPolyMaterial*mat= (*itp).second;
+ RAS_IPolyMaterial *mat = (*itp).second;
mat->Replace_IScene(to);
}
itp++;
@@ -1434,29 +1341,39 @@ bool KX_BlenderSceneConverter::MergeScene(KX_Scene *to, KX_Scene *from)
}
{
- vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator itp = m_meshobjects.begin();
+ vector<pair<KX_Scene *, RAS_MeshObject *> >::iterator itp = m_meshobjects.begin();
while (itp != m_meshobjects.end()) {
- if ((*itp).first==from)
- (*itp).first= to;
+ if ((*itp).first == from)
+ (*itp).first = to;
itp++;
}
}
{
- vector<pair<KX_Scene*,BL_Material*> >::iterator itp = m_materials.begin();
+ vector<pair<KX_Scene *, BL_Material *> >::iterator itp = m_materials.begin();
while (itp != m_materials.end()) {
- if ((*itp).first==from)
- (*itp).first= to;
+ if ((*itp).first == from)
+ (*itp).first = to;
itp++;
}
}
-
+
+ MaterialCache::iterator matcacheit = m_mat_cache.find(from);
+ // Merge cached BL_Material map.
+ m_mat_cache[to].insert(matcacheit->second.begin(), matcacheit->second.end());
+ m_mat_cache.erase(matcacheit);
+
+ PolyMaterialCache::iterator polymatcacheit = m_polymat_cache.find(from);
+ // Merge cached RAS_IPolyMaterial map.
+ m_polymat_cache[to].insert(polymatcacheit->second.begin(), polymatcacheit->second.end());
+ m_polymat_cache.erase(polymatcacheit);
+
return true;
}
/* This function merges a mesh from the current scene into another main
* it does not convert */
-RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name)
+RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene *kx_scene, Main *maggie, const char *name)
{
/* Find a mesh in the current main */
ID *me= static_cast<ID *>(BLI_findstring(&m_maggie->mesh, name, offsetof(ID, name) + 2));
@@ -1464,7 +1381,7 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
if (me == NULL) {
// The mesh wasn't in the current main, try any dynamic (i.e., LibLoaded) ones
- vector<Main*>::iterator it;
+ vector<Main *>::iterator it;
for (it = GetMainDynamic().begin(); it != GetMainDynamic().end(); it++) {
me = static_cast<ID *>(BLI_findstring(&(*it)->mesh, name, offsetof(ID, name) + 2));
@@ -1474,12 +1391,12 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
break;
}
}
-
- if (me==NULL) {
+
+ if (me == NULL) {
printf("Could not be found \"%s\"\n", name);
return NULL;
}
-
+
/* Watch this!, if its used in the original scene can cause big troubles */
if (me->us > 0) {
#ifdef DEBUG
@@ -1491,34 +1408,32 @@ RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene,
BLI_remlink(&from_maggie->mesh, me); /* even if we made the copy it needs to be removed */
BLI_addtail(&maggie->mesh, me);
-
/* Must copy the materials this uses else we cant free them */
{
- Mesh *mesh= (Mesh *)me;
-
+ Mesh *mesh = (Mesh *)me;
+
/* ensure all materials are tagged */
- for (int i=0; i<mesh->totcol; i++)
+ for (int i = 0; i < mesh->totcol; i++) {
if (mesh->mat[i])
mesh->mat[i]->id.flag &= ~LIB_DOIT;
-
- for (int i=0; i<mesh->totcol; i++)
- {
- Material *mat_old= mesh->mat[i];
-
+ }
+
+ for (int i = 0; i < mesh->totcol; i++) {
+ Material *mat_old = mesh->mat[i];
+
/* if its tagged its a replaced material */
- if (mat_old && (mat_old->id.flag & LIB_DOIT)==0)
- {
- Material *mat_old= mesh->mat[i];
- Material *mat_new= BKE_material_copy( mat_old );
-
+ if (mat_old && (mat_old->id.flag & LIB_DOIT) == 0) {
+ Material *mat_old = mesh->mat[i];
+ Material *mat_new = BKE_material_copy(mat_old);
+
mat_new->id.flag |= LIB_DOIT;
mat_old->id.us--;
-
+
BLI_remlink(&G.main->mat, mat_new); // BKE_material_copy uses G.main, and there is no BKE_material_copy_ex
BLI_addtail(&maggie->mat, mat_new);
-
+
mesh->mat[i] = mat_new;
-
+
/* the same material may be used twice */
for (int j = i + 1; j < mesh->totcol; j++) {
if (mesh->mat[j] == mat_old) {
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index 0d706fcd924..854ae5b28dc 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -105,7 +105,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
bSensor* sens = (bSensor*)blenderobject->sensors.first;
bool pos_pulsemode = false;
bool neg_pulsemode = false;
- int frequency = 0;
+ int skipped_ticks = 0;
bool invert = false;
bool level = false;
bool tap = false;
@@ -119,542 +119,542 @@ void BL_ConvertSensors(struct Object* blenderobject,
sens = (bSensor*)blenderobject->sensors.first;
while (sens) {
- SCA_ISensor* gamesensor=NULL;
- /* All sensors have a pulse toggle, frequency, and invert field. */
- /* These are extracted here, and set when the sensor is added to the */
- /* list. */
- pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0;
- neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0;
-
- frequency = sens->freq;
- invert = !(sens->invert == 0);
- level = !(sens->level == 0);
- tap = !(sens->tap == 0);
-
- switch (sens->type)
- {
- case SENS_ALWAYS:
- {
-
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
- if (eventmgr)
- {
- gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
- }
-
- break;
- }
-
- case SENS_DELAY:
+ if (!(sens->flag & SENS_DEACTIVATE)) {
+ SCA_ISensor* gamesensor=NULL;
+ /* All sensors have a pulse toggle, skipped ticks parameter, and invert field. */
+ /* These are extracted here, and set when the sensor is added to the */
+ /* list. */
+ pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0;
+ neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0;
+
+ skipped_ticks = sens->freq;
+ invert = !(sens->invert == 0);
+ level = !(sens->level == 0);
+ tap = !(sens->tap == 0);
+
+ switch (sens->type)
{
- // we can reuse the Always event manager for the delay sensor
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
- if (eventmgr)
+ case SENS_ALWAYS:
{
- bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
- gamesensor = new SCA_DelaySensor(eventmgr,
- gameobj,
- delaysensor->delay,
- delaysensor->duration,
- (delaysensor->flag & SENS_DELAY_REPEAT) != 0);
+
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
+ if (eventmgr)
+ {
+ gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
+ }
+
+ break;
}
- break;
- }
- case SENS_COLLISION:
- {
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
- if (eventmgr)
+ case SENS_DELAY:
{
- // collision sensor can sense both materials and properties.
-
- bool bFindMaterial = false, bTouchPulse = false;
-
- bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
-
- bFindMaterial = (blendertouchsensor->mode & SENS_COLLISION_MATERIAL);
- bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE);
-
-
- const STR_String touchPropOrMatName = bFindMaterial ?
- blendertouchsensor->materialName : blendertouchsensor->name;
-
-
- if (gameobj->GetPhysicsController())
+ // we can reuse the Always event manager for the delay sensor
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
+ if (eventmgr)
{
- gamesensor = new KX_TouchSensor(eventmgr,
+ bDelaySensor* delaysensor = (bDelaySensor*)sens->data;
+ gamesensor = new SCA_DelaySensor(eventmgr,
gameobj,
- bFindMaterial,
- bTouchPulse,
- touchPropOrMatName);
+ delaysensor->delay,
+ delaysensor->duration,
+ (delaysensor->flag & SENS_DELAY_REPEAT) != 0);
}
-
- }
-
- break;
- }
- case SENS_MESSAGE:
- {
- KX_NetworkEventManager* eventmgr = (KX_NetworkEventManager*)
- logicmgr->FindEventManager(SCA_EventManager::NETWORK_EVENTMGR);
- if (eventmgr) {
- bMessageSensor* msgSens = (bMessageSensor*) sens->data;
-
- /* Get our NetworkScene */
- NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
- /* filter on the incoming subjects, might be empty */
- const STR_String subject = msgSens->subject;
-
- gamesensor = new KX_NetworkMessageSensor(
- eventmgr, // our eventmanager
- NetworkScene, // our NetworkScene
- gameobj, // the sensor controlling object
- subject); // subject to filter on
+ break;
}
- break;
- }
- case SENS_NEAR:
- {
-
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
- if (eventmgr)
+
+ case SENS_COLLISION:
{
- bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
- const STR_String nearpropertyname = (char *)blendernearsensor->name;
-
- //DT_ShapeHandle shape = DT_Sphere(0.0);
-
- // this sumoObject is not deleted by a gameobj, so delete it ourself
- // later (memleaks)!
- float radius = blendernearsensor->dist;
- const MT_Vector3& wpos = gameobj->NodeGetWorldPosition();
- bool bFindMaterial = false;
- PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,wpos);
-
- //will be done in KX_TouchEventManager::RegisterSensor()
- //if (isInActiveLayer)
- // kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
-
-
-
- gamesensor = new KX_NearSensor(eventmgr,gameobj,
- blendernearsensor->dist,
- blendernearsensor->resetdist,
- bFindMaterial,
- nearpropertyname,
- physCtrl);
-
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ // collision sensor can sense both materials and properties.
+
+ bool bFindMaterial = false, bTouchPulse = false;
+
+ bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
+
+ bFindMaterial = (blendertouchsensor->mode & SENS_COLLISION_MATERIAL);
+ bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE);
+
+
+ const STR_String touchPropOrMatName = bFindMaterial ?
+ blendertouchsensor->materialName : blendertouchsensor->name;
+
+
+ if (gameobj->GetPhysicsController())
+ {
+ gamesensor = new KX_TouchSensor(eventmgr,
+ gameobj,
+ bFindMaterial,
+ bTouchPulse,
+ touchPropOrMatName);
+ }
+
+ }
+
+ break;
}
- break;
- }
-
-
- case SENS_KEYBOARD:
- {
- /* temporary input device, for converting the code for the keyboard sensor */
-
- bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data;
- SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR);
- if (eventmgr)
+ case SENS_MESSAGE:
{
- gamesensor = new SCA_KeyboardSensor(eventmgr,
- ConvertKeyCode(blenderkeybdsensor->key),
- ConvertKeyCode(blenderkeybdsensor->qual),
- ConvertKeyCode(blenderkeybdsensor->qual2),
- (blenderkeybdsensor->type == SENS_ALL_KEYS),
- blenderkeybdsensor->targetName,
- blenderkeybdsensor->toggleName,
- gameobj,
- KX_KetsjiEngine::GetExitKey()); // blenderkeybdsensor->pad);
-
- }
-
- break;
- }
- case SENS_MOUSE:
- {
- int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;
- int trackfocus = 0;
- bMouseSensor *bmouse = (bMouseSensor *)sens->data;
-
- /* There are two main types of mouse sensors. If there is
- * no focus-related behavior requested, we can make do
- * with a basic sensor. This cuts down memory usage and
- * gives a slight performance gain. */
-
- SCA_MouseManager *eventmgr
- = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
- if (eventmgr) {
-
- /* Determine key mode. There is at most one active mode. */
- switch (bmouse->type) {
- case BL_SENS_MOUSE_LEFT_BUTTON:
- keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
- break;
- case BL_SENS_MOUSE_MIDDLE_BUTTON:
- keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
- break;
- case BL_SENS_MOUSE_RIGHT_BUTTON:
- keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
- break;
- case BL_SENS_MOUSE_WHEEL_UP:
- keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELUP;
- break;
- case BL_SENS_MOUSE_WHEEL_DOWN:
- keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELDOWN;
- break;
- case BL_SENS_MOUSE_MOVEMENT:
- keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
- break;
- case BL_SENS_MOUSE_MOUSEOVER:
- trackfocus = 1;
- break;
- case BL_SENS_MOUSE_MOUSEOVER_ANY:
- trackfocus = 2;
- break;
-
- default:
- ; /* error */
+ KX_NetworkEventManager* eventmgr = (KX_NetworkEventManager*)
+ logicmgr->FindEventManager(SCA_EventManager::NETWORK_EVENTMGR);
+ if (eventmgr) {
+ bMessageSensor* msgSens = (bMessageSensor*) sens->data;
+
+ /* Get our NetworkScene */
+ NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
+ /* filter on the incoming subjects, might be empty */
+ const STR_String subject = msgSens->subject;
+
+ gamesensor = new KX_NetworkMessageSensor(
+ eventmgr, // our eventmanager
+ NetworkScene, // our NetworkScene
+ gameobj, // the sensor controlling object
+ subject); // subject to filter on
}
-
- /* initial mouse position */
- int startx = canvas->GetWidth()/2;
- int starty = canvas->GetHeight()/2;
-
- if (!trackfocus) {
- /* plain, simple mouse sensor */
- gamesensor = new SCA_MouseSensor(eventmgr,
- startx,starty,
- keytype,
- gameobj);
- } else {
- /* give us a focus-aware sensor */
- bool bFindMaterial = (bmouse->mode & SENS_COLLISION_MATERIAL);
- bool bXRay = (bmouse->flag & SENS_RAY_XRAY);
- STR_String checkname = (bFindMaterial? bmouse->matname : bmouse->propname);
-
- gamesensor = new KX_MouseFocusSensor(eventmgr,
- startx,
- starty,
- keytype,
- trackfocus,
- (bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false,
- checkname,
+ break;
+ }
+ case SENS_NEAR:
+ {
+
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
+ const STR_String nearpropertyname = (char *)blendernearsensor->name;
+
+ //DT_ShapeHandle shape = DT_Sphere(0.0);
+
+ // this sumoObject is not deleted by a gameobj, so delete it ourself
+ // later (memleaks)!
+ float radius = blendernearsensor->dist;
+ const MT_Vector3& wpos = gameobj->NodeGetWorldPosition();
+ bool bFindMaterial = false;
+ PHY_IPhysicsController* physCtrl = kxscene->GetPhysicsEnvironment()->CreateSphereController(radius,wpos);
+
+ //will be done in KX_TouchEventManager::RegisterSensor()
+ //if (isInActiveLayer)
+ // kxscene->GetPhysicsEnvironment()->addSensor(physCtrl);
+
+
+
+ gamesensor = new KX_NearSensor(eventmgr,gameobj,
+ blendernearsensor->dist,
+ blendernearsensor->resetdist,
bFindMaterial,
- bXRay,
- kxscene,
- kxengine,
- gameobj);
+ nearpropertyname,
+ physCtrl);
+
}
- } else {
- // cout << "\n Could't find mouse event manager..."; - should throw an error here...
+ break;
}
- break;
- }
- case SENS_PROPERTY:
- {
- bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
- SCA_EventManager* eventmgr
- = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
- if (eventmgr)
+
+
+ case SENS_KEYBOARD:
{
- STR_String propname=blenderpropsensor->name;
- STR_String propval=blenderpropsensor->value;
- STR_String propmaxval=blenderpropsensor->maxvalue;
-
- SCA_PropertySensor::KX_PROPSENSOR_TYPE
- propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
-
- /* Better do an explicit conversion here! (was implicit */
- /* before...) */
- switch (blenderpropsensor->type) {
- case SENS_PROP_EQUAL:
- propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
- break;
- case SENS_PROP_NEQUAL:
- propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
- break;
- case SENS_PROP_INTERVAL:
- propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
- break;
- case SENS_PROP_CHANGED:
- propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
- break;
- case SENS_PROP_EXPRESSION:
- propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
- /* error */
- break;
- case SENS_PROP_LESSTHAN:
- propchecktype = SCA_PropertySensor::KX_PROPSENSOR_LESSTHAN;
- break;
- case SENS_PROP_GREATERTHAN:
- propchecktype = SCA_PropertySensor::KX_PROPSENSOR_GREATERTHAN;
- break;
- default:
- ; /* error */
+ /* temporary input device, for converting the code for the keyboard sensor */
+
+ bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data;
+ SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR);
+ if (eventmgr)
+ {
+ gamesensor = new SCA_KeyboardSensor(eventmgr,
+ ConvertKeyCode(blenderkeybdsensor->key),
+ ConvertKeyCode(blenderkeybdsensor->qual),
+ ConvertKeyCode(blenderkeybdsensor->qual2),
+ (blenderkeybdsensor->type == SENS_ALL_KEYS),
+ blenderkeybdsensor->targetName,
+ blenderkeybdsensor->toggleName,
+ gameobj,
+ KX_KetsjiEngine::GetExitKey()); // blenderkeybdsensor->pad);
+
}
- gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
+
+ break;
}
-
- break;
- }
- case SENS_ACTUATOR:
- {
- bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data;
- // we will reuse the property event manager, there is nothing special with this sensor
- SCA_EventManager* eventmgr
- = logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR);
- if (eventmgr)
+ case SENS_MOUSE:
+ {
+ int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;
+ int trackfocus = 0;
+ bMouseSensor *bmouse = (bMouseSensor *)sens->data;
+
+ /* There are two main types of mouse sensors. If there is
+ * no focus-related behavior requested, we can make do
+ * with a basic sensor. This cuts down memory usage and
+ * gives a slight performance gain. */
+
+ SCA_MouseManager *eventmgr
+ = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
+ if (eventmgr) {
+
+ /* Determine key mode. There is at most one active mode. */
+ switch (bmouse->type) {
+ case BL_SENS_MOUSE_LEFT_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
+ break;
+ case BL_SENS_MOUSE_MIDDLE_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
+ break;
+ case BL_SENS_MOUSE_RIGHT_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
+ break;
+ case BL_SENS_MOUSE_WHEEL_UP:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELUP;
+ break;
+ case BL_SENS_MOUSE_WHEEL_DOWN:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_WHEELDOWN;
+ break;
+ case BL_SENS_MOUSE_MOVEMENT:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
+ break;
+ case BL_SENS_MOUSE_MOUSEOVER:
+ trackfocus = 1;
+ break;
+ case BL_SENS_MOUSE_MOUSEOVER_ANY:
+ trackfocus = 2;
+ break;
+
+ default:
+ ; /* error */
+ }
+
+ /* initial mouse position */
+ int startx = canvas->GetWidth()/2;
+ int starty = canvas->GetHeight()/2;
+
+ if (!trackfocus) {
+ /* plain, simple mouse sensor */
+ gamesensor = new SCA_MouseSensor(eventmgr,
+ startx,starty,
+ keytype,
+ gameobj);
+ } else {
+ /* give us a focus-aware sensor */
+ bool bFindMaterial = (bmouse->mode & SENS_COLLISION_MATERIAL);
+ bool bXRay = (bmouse->flag & SENS_RAY_XRAY);
+ STR_String checkname = (bFindMaterial? bmouse->matname : bmouse->propname);
+
+ gamesensor = new KX_MouseFocusSensor(eventmgr,
+ startx,
+ starty,
+ keytype,
+ trackfocus,
+ (bmouse->flag & SENS_MOUSE_FOCUS_PULSE) ? true:false,
+ checkname,
+ bFindMaterial,
+ bXRay,
+ kxscene,
+ kxengine,
+ gameobj);
+ }
+ } else {
+ // cout << "\n Could't find mouse event manager..."; - should throw an error here...
+ }
+ break;
+ }
+ case SENS_PROPERTY:
{
- STR_String propname=blenderactsensor->name;
- gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname);
+ bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
+ SCA_EventManager* eventmgr
+ = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String propname=blenderpropsensor->name;
+ STR_String propval=blenderpropsensor->value;
+ STR_String propmaxval=blenderpropsensor->maxvalue;
+
+ SCA_PropertySensor::KX_PROPSENSOR_TYPE
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
+
+ /* Better do an explicit conversion here! (was implicit */
+ /* before...) */
+ switch (blenderpropsensor->type) {
+ case SENS_PROP_EQUAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
+ break;
+ case SENS_PROP_NEQUAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
+ break;
+ case SENS_PROP_INTERVAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
+ break;
+ case SENS_PROP_CHANGED:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
+ break;
+ case SENS_PROP_EXPRESSION:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
+ /* error */
+ break;
+ case SENS_PROP_LESSTHAN:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_LESSTHAN;
+ break;
+ case SENS_PROP_GREATERTHAN:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_GREATERTHAN;
+ break;
+ default:
+ ; /* error */
+ }
+ gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
+ }
+
+ break;
}
- break;
- }
-
- case SENS_ARMATURE:
- {
- bArmatureSensor* blenderarmsensor = (bArmatureSensor*) sens->data;
- // we will reuse the property event manager, there is nothing special with this sensor
- SCA_EventManager* eventmgr
- = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
- if (eventmgr)
+ case SENS_ACTUATOR:
{
- STR_String bonename=blenderarmsensor->posechannel;
- STR_String constraintname=blenderarmsensor->constraint;
- gamesensor = new KX_ArmatureSensor(eventmgr,gameobj,bonename,constraintname, blenderarmsensor->type, blenderarmsensor->value);
+ bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data;
+ // we will reuse the property event manager, there is nothing special with this sensor
+ SCA_EventManager* eventmgr
+ = logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String propname=blenderactsensor->name;
+ gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname);
+ }
+ break;
}
- break;
- }
- case SENS_RADAR:
- {
-
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
- if (eventmgr)
+ case SENS_ARMATURE:
{
- bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
- const STR_String radarpropertyname = blenderradarsensor->name;
-
- int radaraxis = blenderradarsensor->axis;
-
- MT_Scalar coneheight = blenderradarsensor->range;
-
- // janco: the angle was doubled, so should I divide the factor in 2
- // or the blenderradarsensor->angle?
- // nzc: the angle is the opening angle. We need to init with
- // the axis-hull angle,so /2.0.
- MT_Scalar factor = tan(blenderradarsensor->angle * 0.5f);
- //MT_Scalar coneradius = coneheight * (factor / 2);
- MT_Scalar coneradius = coneheight * factor;
-
-
- // this sumoObject is not deleted by a gameobj, so delete it ourself
- // later (memleaks)!
- MT_Scalar smallmargin = 0.0;
- MT_Scalar largemargin = 0.0;
-
- bool bFindMaterial = false;
- PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController((float)coneradius, (float)coneheight);
-
- gamesensor = new KX_RadarSensor(
- eventmgr,
- gameobj,
- ctrl,
- coneradius,
- coneheight,
- radaraxis,
- smallmargin,
- largemargin,
- bFindMaterial,
- radarpropertyname);
-
+ bArmatureSensor* blenderarmsensor = (bArmatureSensor*) sens->data;
+ // we will reuse the property event manager, there is nothing special with this sensor
+ SCA_EventManager* eventmgr
+ = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String bonename=blenderarmsensor->posechannel;
+ STR_String constraintname=blenderarmsensor->constraint;
+ gamesensor = new KX_ArmatureSensor(eventmgr,gameobj,bonename,constraintname, blenderarmsensor->type, blenderarmsensor->value);
+ }
+ break;
}
-
- break;
- }
- case SENS_RAY:
- {
- bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
-
- //blenderradarsensor->angle;
- SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
- if (eventmgr)
+
+ case SENS_RADAR:
{
- bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
- bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY);
-
- STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
-
- // don't want to get rays of length 0.0 or so
- double distance = (blenderraysensor->range < 0.01f ? 0.01f : blenderraysensor->range);
- int axis = blenderraysensor->axisflag;
-
-
- gamesensor = new KX_RaySensor(eventmgr,
- gameobj,
- checkname,
- bFindMaterial,
- bXRay,
- distance,
- axis,
- kxscene);
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
+ const STR_String radarpropertyname = blenderradarsensor->name;
+
+ int radaraxis = blenderradarsensor->axis;
+
+ MT_Scalar coneheight = blenderradarsensor->range;
+
+ // janco: the angle was doubled, so should I divide the factor in 2
+ // or the blenderradarsensor->angle?
+ // nzc: the angle is the opening angle. We need to init with
+ // the axis-hull angle,so /2.0.
+ MT_Scalar factor = tan(blenderradarsensor->angle * 0.5f);
+ //MT_Scalar coneradius = coneheight * (factor / 2);
+ MT_Scalar coneradius = coneheight * factor;
+
+
+ // this sumoObject is not deleted by a gameobj, so delete it ourself
+ // later (memleaks)!
+ MT_Scalar smallmargin = 0.0;
+ MT_Scalar largemargin = 0.0;
+
+ bool bFindMaterial = false;
+ PHY_IPhysicsController* ctrl = kxscene->GetPhysicsEnvironment()->CreateConeController((float)coneradius, (float)coneheight);
+
+ gamesensor = new KX_RadarSensor(
+ eventmgr,
+ gameobj,
+ ctrl,
+ coneradius,
+ coneheight,
+ radaraxis,
+ smallmargin,
+ largemargin,
+ bFindMaterial,
+ radarpropertyname);
+
+ }
+
+ break;
}
- break;
- }
-
- case SENS_RANDOM:
- {
- bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
- // some files didn't write randomsensor, avoid crash now for NULL ptr's
- if (blenderrndsensor)
+ case SENS_RAY:
{
+ bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
+
+ //blenderradarsensor->angle;
SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
if (eventmgr)
{
- int randomSeed = blenderrndsensor->seed;
- if (randomSeed == 0)
+ bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
+ bool bXRay = (blenderraysensor->mode & SENS_RAY_XRAY);
+
+ STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
+
+ // don't want to get rays of length 0.0 or so
+ double distance = (blenderraysensor->range < 0.01f ? 0.01f : blenderraysensor->range);
+ int axis = blenderraysensor->axisflag;
+
+
+ gamesensor = new KX_RaySensor(eventmgr,
+ gameobj,
+ checkname,
+ bFindMaterial,
+ bXRay,
+ distance,
+ axis,
+ kxscene);
+
+ }
+ break;
+ }
+
+ case SENS_RANDOM:
+ {
+ bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
+ // some files didn't write randomsensor, avoid crash now for NULL ptr's
+ if (blenderrndsensor)
+ {
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::BASIC_EVENTMGR);
+ if (eventmgr)
{
- randomSeed = (int)(kxengine->GetRealTime()*100000.0);
- randomSeed ^= (intptr_t)blenderrndsensor;
+ int randomSeed = blenderrndsensor->seed;
+ if (randomSeed == 0)
+ {
+ randomSeed = (int)(kxengine->GetRealTime()*100000.0);
+ randomSeed ^= (intptr_t)blenderrndsensor;
+ }
+ gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
}
- gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
}
+ break;
}
- break;
- }
- case SENS_JOYSTICK:
- {
- int joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_NODEF;
-
- bJoystickSensor* bjoy = (bJoystickSensor*) sens->data;
-
- SCA_JoystickManager *eventmgr
- = (SCA_JoystickManager*) logicmgr->FindEventManager(SCA_EventManager::JOY_EVENTMGR);
- if (eventmgr)
+ case SENS_JOYSTICK:
{
- int axis =0;
- int axisf =0;
- int button =0;
- int hat =0;
- int hatf =0;
- int prec =0;
-
- switch (bjoy->type) {
- case SENS_JOY_AXIS:
- axis = bjoy->axis;
- axisf = bjoy->axisf;
- prec = bjoy->precision;
- joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS;
- break;
- case SENS_JOY_BUTTON:
- button = bjoy->button;
- joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON;
- break;
- case SENS_JOY_HAT:
- hat = bjoy->hat;
- hatf = bjoy->hatf;
- joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_HAT;
- break;
- case SENS_JOY_AXIS_SINGLE:
- axis = bjoy->axis_single;
- prec = bjoy->precision;
- joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS_SINGLE;
- break;
- default:
- printf("Error: bad case statement\n");
- break;
+ int joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_NODEF;
+
+ bJoystickSensor* bjoy = (bJoystickSensor*) sens->data;
+
+ SCA_JoystickManager *eventmgr
+ = (SCA_JoystickManager*) logicmgr->FindEventManager(SCA_EventManager::JOY_EVENTMGR);
+ if (eventmgr)
+ {
+ int axis =0;
+ int axisf =0;
+ int button =0;
+ int hat =0;
+ int hatf =0;
+ int prec =0;
+
+ switch (bjoy->type) {
+ case SENS_JOY_AXIS:
+ axis = bjoy->axis;
+ axisf = bjoy->axisf;
+ prec = bjoy->precision;
+ joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS;
+ break;
+ case SENS_JOY_BUTTON:
+ button = bjoy->button;
+ joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_BUTTON;
+ break;
+ case SENS_JOY_HAT:
+ hat = bjoy->hat;
+ hatf = bjoy->hatf;
+ joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_HAT;
+ break;
+ case SENS_JOY_AXIS_SINGLE:
+ axis = bjoy->axis_single;
+ prec = bjoy->precision;
+ joysticktype = SCA_JoystickSensor::KX_JOYSENSORMODE_AXIS_SINGLE;
+ break;
+ default:
+ printf("Error: bad case statement\n");
+ break;
+ }
+ gamesensor = new SCA_JoystickSensor(
+ eventmgr,
+ gameobj,
+ bjoy->joyindex,
+ joysticktype,
+ axis,axisf,
+ prec,
+ button,
+ hat,hatf,
+ (bjoy->flag & SENS_JOY_ANY_EVENT));
}
- gamesensor = new SCA_JoystickSensor(
- eventmgr,
- gameobj,
- bjoy->joyindex,
- joysticktype,
- axis,axisf,
- prec,
- button,
- hat,hatf,
- (bjoy->flag & SENS_JOY_ANY_EVENT));
- }
- else
+ else
+ {
+ printf("Error there was a problem finding the event manager\n");
+ }
+
+ break;
+ }
+ default:
{
- printf("Error there was a problem finding the event manager\n");
}
-
- break;
}
- default:
- {
- }
- }
- if (gamesensor && !(sens->flag & SENS_DEACTIVATE))
- {
- gamesensor->SetExecutePriority(executePriority++);
- STR_String uniquename = sens->name;
- uniquename += "#SENS#";
- uniqueint++;
- CIntValue* uniqueval = new CIntValue(uniqueint);
- uniquename += uniqueval->GetText();
- uniqueval->Release();
-
- /* Conversion succeeded, so we can set the generic props here. */
- gamesensor->SetPulseMode(pos_pulsemode,
- neg_pulsemode,
- frequency);
- gamesensor->SetInvert(invert);
- gamesensor->SetLevel(level);
- gamesensor->SetTap(tap);
- gamesensor->SetName(sens->name);
-
- gameobj->AddSensor(gamesensor);
-
- // only register to manager if it's in an active layer
- // Make registration dynamic: only when sensor is activated
- //if (isInActiveLayer)
- // gamesensor->RegisterToManager();
-
- gamesensor->ReserveController(sens->totlinks);
- for (int i=0;i<sens->totlinks;i++)
+ if (gamesensor)
{
- bController* linkedcont = (bController*) sens->links[i];
- if (linkedcont) {
- // If the controller is deactived doesn't register it
- if (!(linkedcont->flag & CONT_DEACTIVATE)) {
- SCA_IController* gamecont = converter->FindGameController(linkedcont);
-
- if (gamecont) {
- logicmgr->RegisterToSensor(gamecont,gamesensor);
- }
- else {
- printf("Warning, sensor \"%s\" could not find its controller "
- "(link %d of %d) from object \"%s\"\n"
- "\tthere has been an error converting the blender controller for the game engine,"
- "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
+ gamesensor->SetExecutePriority(executePriority++);
+ STR_String uniquename = sens->name;
+ uniquename += "#SENS#";
+ uniqueint++;
+ CIntValue* uniqueval = new CIntValue(uniqueint);
+ uniquename += uniqueval->GetText();
+ uniqueval->Release();
+
+ /* Conversion succeeded, so we can set the generic props here. */
+ gamesensor->SetPulseMode(pos_pulsemode,
+ neg_pulsemode,
+ skipped_ticks);
+ gamesensor->SetInvert(invert);
+ gamesensor->SetLevel(level);
+ gamesensor->SetTap(tap);
+ gamesensor->SetName(sens->name);
+
+ gameobj->AddSensor(gamesensor);
+
+ // only register to manager if it's in an active layer
+ // Make registration dynamic: only when sensor is activated
+ //if (isInActiveLayer)
+ // gamesensor->RegisterToManager();
+
+ gamesensor->ReserveController(sens->totlinks);
+ for (int i=0;i<sens->totlinks;i++)
+ {
+ bController* linkedcont = (bController*) sens->links[i];
+ if (linkedcont) {
+ // If the controller is deactived doesn't register it
+ if (!(linkedcont->flag & CONT_DEACTIVATE)) {
+ SCA_IController* gamecont = converter->FindGameController(linkedcont);
+
+ if (gamecont) {
+ logicmgr->RegisterToSensor(gamecont,gamesensor);
+ }
+ else {
+ printf("Warning, sensor \"%s\" could not find its controller "
+ "(link %d of %d) from object \"%s\"\n"
+ "\tthere has been an error converting the blender controller for the game engine,"
+ "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
+ }
}
}
+ else {
+ printf("Warning, sensor \"%s\" has lost a link to a controller "
+ "(link %d of %d) from object \"%s\"\n"
+ "\tpossible causes are partially appended objects or an error reading the file,"
+ "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
+ }
}
- else {
- printf("Warning, sensor \"%s\" has lost a link to a controller "
- "(link %d of %d) from object \"%s\"\n"
- "\tpossible causes are partially appended objects or an error reading the file,"
- "logic may be incorrect\n", sens->name, i+1, sens->totlinks, blenderobject->id.name+2);
+ // special case: Keyboard sensor with no link
+ // this combination is usually used for key logging.
+ if (sens->type == SENS_KEYBOARD && sens->totlinks == 0) {
+ // Force the registration so that the sensor runs
+ gamesensor->IncLink();
}
+
+ // done with gamesensor
+ gamesensor->Release();
+
}
- // special case: Keyboard sensor with no link
- // this combination is usually used for key logging.
- if (sens->type == SENS_KEYBOARD && sens->totlinks == 0) {
- // Force the registration so that the sensor runs
- gamesensor->IncLink();
- }
-
- // done with gamesensor
- gamesensor->Release();
-
}
- else if (gamesensor)
- gamesensor->Release();
sens=sens->next;
}
diff --git a/source/gameengine/Expressions/CMakeLists.txt b/source/gameengine/Expressions/CMakeLists.txt
index 6907f314503..48c10d75a17 100644
--- a/source/gameengine/Expressions/CMakeLists.txt
+++ b/source/gameengine/Expressions/CMakeLists.txt
@@ -55,6 +55,7 @@ set(SRC
StringValue.cpp
Value.cpp
VectorValue.cpp
+ KX_PythonCallBack.cpp
BoolValue.h
ConstExpr.h
@@ -77,6 +78,7 @@ set(SRC
Value.h
VectorValue.h
VoidValue.h
+ KX_PythonCallBack.h
)
blender_add_lib(ge_logic_expressions "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/gameengine/Expressions/KX_PythonCallBack.cpp b/source/gameengine/Expressions/KX_PythonCallBack.cpp
new file mode 100644
index 00000000000..fbc250a1b3d
--- /dev/null
+++ b/source/gameengine/Expressions/KX_PythonCallBack.cpp
@@ -0,0 +1,119 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Porteries Tristan.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file gameengine/Expressions/KX_PythonCallBack.cpp
+ * \ingroup expressions
+ */
+
+#include "KX_PythonCallBack.h"
+#include <iostream>
+#include <stdarg.h>
+
+#include "BLI_alloca.h"
+
+/** Check if a python value is a function and have the correct number of arguments.
+ * \param value The python value to check.
+ * \param minargcount The minimum of arguments possible.
+ * \param maxargcount The maximum of arguments possible.
+ * \param r_argcount The number of argument of this function, this variable will be
+ * changed in the function.
+ */
+static PyObject *CheckPythonFunction(PyObject *value, unsigned int minargcount, unsigned int maxargcount, unsigned int &r_argcount)
+{
+ if (PyMethod_Check(value)) {
+ PyCodeObject *code = ((PyCodeObject *)PyFunction_GET_CODE(PyMethod_GET_FUNCTION(value)));
+ // *args support
+ r_argcount = (code->co_flags & CO_VARARGS) ? maxargcount : (code->co_argcount - 1);
+ }
+ else if (PyFunction_Check(value)) {
+ PyCodeObject *code = ((PyCodeObject *)PyFunction_GET_CODE(value));
+ // *args support
+ r_argcount = (code->co_flags & CO_VARARGS) ? maxargcount : code->co_argcount;
+ }
+ else { // is not a methode or a function
+ PyErr_Format(PyExc_TypeError, "items must be functions or methodes, not %s",
+ Py_TYPE(value)->tp_name);
+ return NULL;
+ }
+
+ if (r_argcount < minargcount || r_argcount > maxargcount) {
+ // wrong number of arguments
+ PyErr_Format(PyExc_TypeError, "methode or function (%s) has invalid number of arguments (%i) must be between %i and %i",
+ Py_TYPE(value)->tp_name, r_argcount, minargcount, maxargcount);
+ return NULL;
+ }
+
+ return value;
+}
+
+/** Create a python tuple to call a python function
+ * \param argcount The lenght of the tuple.
+ * \param arglist The fully list of python arguments [size >= argcount].
+ */
+static PyObject *CreatePythonTuple(unsigned int argcount, PyObject **arglist)
+{
+ PyObject *tuple = PyTuple_New(argcount);
+
+ for (unsigned int i = 0; i < argcount; ++i) {
+ PyObject *item = arglist[i];
+ // increment reference and copy it in a new tuple
+ Py_INCREF(item);
+ PyTuple_SET_ITEM(tuple, i, item);
+ }
+
+ return tuple;
+}
+
+void RunPythonCallBackList(PyObject *functionlist, PyObject **arglist, unsigned int minargcount, unsigned int maxargcount)
+{
+ unsigned int size = PyList_Size(functionlist);
+ PyObject **argTuples = (PyObject **)BLI_array_alloca(argTuples, maxargcount - minargcount + 1);
+ memset(argTuples, 0, sizeof(PyObject *) * (maxargcount - minargcount + 1));
+
+ for (unsigned int i = 0; i < size; ++i) {
+ unsigned int funcargcount = 0;
+
+ PyObject *item = PyList_GET_ITEM(functionlist, i);
+ PyObject *func = CheckPythonFunction(item, minargcount, maxargcount, funcargcount);
+ if (!func) { // this item fails the check
+ PyErr_Print();
+ PyErr_Clear();
+ continue;
+ }
+
+ // get correct argument tuple.
+ PyObject *tuple = argTuples[funcargcount - minargcount];
+ if (!tuple)
+ argTuples[funcargcount - minargcount] = tuple = CreatePythonTuple(funcargcount, arglist);
+
+ PyObject *ret = PyObject_Call(func, tuple, NULL);
+ if (!ret) { // if ret is NULL this seems that the function doesn't work !
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ else
+ Py_DECREF(ret);
+ }
+
+ for (unsigned int i = 0; i <= (maxargcount - minargcount); ++i)
+ Py_XDECREF(argTuples[i]);
+}
diff --git a/source/gameengine/Expressions/KX_PythonCallBack.h b/source/gameengine/Expressions/KX_PythonCallBack.h
new file mode 100644
index 00000000000..2ff6e305d67
--- /dev/null
+++ b/source/gameengine/Expressions/KX_PythonCallBack.h
@@ -0,0 +1,40 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Porteries Tristan.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file KX_PythonCallBack.h
+ * \ingroup expressions
+ */
+
+#ifndef __KX_PYTHON_CALLBACK_H__
+#define __KX_PYTHON_CALLBACK_H__
+
+#include "KX_Python.h"
+
+/** Execute each functions with at least one argument
+ * \param functionlist The python list which contains callbacks.
+ * \param arglist The first item in the tuple to execute callbacks (can be NULL for no arguments).
+ * \param minargcount The minimum of quantity of arguments possible.
+ * \param maxargcount The maximum of quantity of arguments possible.
+ */
+void RunPythonCallBackList(PyObject *functionlist, PyObject **arglist, unsigned int minargcount, unsigned int maxargcount);
+
+#endif // __KX_PYTHON_CALLBACK_H__
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index a65d61bc98b..31a17bd0cbf 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -148,12 +148,18 @@ PyObject *PyObjectPlus::py_base_repr(PyObject *self) // This should be the ent
PyObject *PyObjectPlus::py_base_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyTypeObject *base_type;
- PyObjectPlus_Proxy *base = NULL;
- if (!PyArg_ParseTuple(args, "O:Base PyObjectPlus", &base))
+ /* one or more args is needed */
+ if (!PyTuple_GET_SIZE(args)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Expected at least one argument");
return NULL;
+ }
+
+ PyObjectPlus_Proxy *base = (PyObjectPlus_Proxy *)PyTuple_GET_ITEM(args, 0);
- /* the 'base' PyObject may be subclassed (multiple times even)
+ /**
+ * the 'base' PyObject may be subclassed (multiple times even)
* we need to find the first C++ defined class to check 'type'
* is a subclass of the base arguments type.
*
@@ -162,12 +168,13 @@ PyObject *PyObjectPlus::py_base_new(PyTypeObject *type, PyObject *args, PyObject
* eg.
*
* # CustomOb is called 'type' in this C code
+ * \code{.py}
* class CustomOb(GameTypes.KX_GameObject):
* pass
*
* # this calls py_base_new(...), the type of 'CustomOb' is checked to be a subclass of the 'cont.owner' type
* ob = CustomOb(cont.owner)
- *
+ * \endcode
* */
base_type= Py_TYPE(base);
while (base_type && !BGE_PROXY_CHECK_TYPE(base_type))
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index 34b814d7416..c3ce98ed27a 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -111,6 +111,8 @@ typedef struct PyObjectPlus_Proxy {
/* Opposite of BGE_PROXY_REF */
#define BGE_PROXY_FROM_REF(_self) (((PyObjectPlus *)_self)->GetProxy())
+/* Same as 'BGE_PROXY_REF' but doesn't incref. */
+#define BGE_PROXY_FROM_REF_BORROW(_self) _bge_proxy_from_ref_borrow((void *)_self)
// This must be the first line of each
@@ -631,6 +633,17 @@ public:
#ifdef WITH_PYTHON
PyObject *PyUnicode_From_STR_String(const STR_String& str);
+
+inline PyObject *_bge_proxy_from_ref_borrow(void *self_v)
+{
+ PyObject *self_proxy = BGE_PROXY_FROM_REF(self_v);
+ /* this is typically _very_ bad practice,
+ * however we know the proxy is owned by 'self_v' */
+ self_proxy->ob_refcnt--;
+ return self_proxy;
+}
+
#endif
+
#endif /* __PYOBJECTPLUS_H__ */
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index 3ffe128c3b3..21e2c1cbcfc 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -221,6 +221,7 @@ public:
OBJ_ARMATURE=0,
OBJ_CAMERA=1,
OBJ_LIGHT=2,
+ OBJ_TEXT=3
} ObjectTypes;
};
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 1cb17af8325..66dd69f93c4 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -67,7 +67,7 @@ SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
m_neg_ticks = 0;
m_pos_pulsemode = false;
m_neg_pulsemode = false;
- m_pulse_frequency = 0;
+ m_skipped_ticks = 0;
m_state = false;
m_prev_state = false;
@@ -102,11 +102,11 @@ bool SCA_ISensor::IsPositiveTrigger()
void SCA_ISensor::SetPulseMode(bool posmode,
bool negmode,
- int freq)
+ int skippedticks)
{
m_pos_pulsemode = posmode;
m_neg_pulsemode = negmode;
- m_pulse_frequency = freq;
+ m_skipped_ticks = skippedticks;
}
void SCA_ISensor::SetInvert(bool inv)
@@ -263,7 +263,7 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr)
* not set :( */
if (m_pos_pulsemode) {
m_pos_ticks++;
- if (m_pos_ticks > m_pulse_frequency) {
+ if (m_pos_ticks > m_skipped_ticks) {
if ( m_state )
{
ActivateControllers(logicmgr);
@@ -276,7 +276,7 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr)
if (m_neg_pulsemode && !m_tap)
{
m_neg_ticks++;
- if (m_neg_ticks > m_pulse_frequency) {
+ if (m_neg_ticks > m_skipped_ticks) {
if (!m_state )
{
ActivateControllers(logicmgr);
@@ -367,7 +367,7 @@ PyMethodDef SCA_ISensor::Methods[] = {
PyAttributeDef SCA_ISensor::Attributes[] = {
KX_PYATTRIBUTE_BOOL_RW("usePosPulseMode",SCA_ISensor,m_pos_pulsemode),
KX_PYATTRIBUTE_BOOL_RW("useNegPulseMode",SCA_ISensor,m_neg_pulsemode),
- KX_PYATTRIBUTE_INT_RW("frequency",0,100000,true,SCA_ISensor,m_pulse_frequency),
+ KX_PYATTRIBUTE_INT_RW("skippedTicks",0,100000,true,SCA_ISensor,m_skipped_ticks),
KX_PYATTRIBUTE_BOOL_RW("invert",SCA_ISensor,m_invert),
KX_PYATTRIBUTE_BOOL_RW_CHECK("level",SCA_ISensor,m_level,pyattr_check_level),
KX_PYATTRIBUTE_BOOL_RW_CHECK("tap",SCA_ISensor,m_tap,pyattr_check_tap),
@@ -376,6 +376,7 @@ PyAttributeDef SCA_ISensor::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("status", SCA_ISensor, pyattr_get_status),
KX_PYATTRIBUTE_RO_FUNCTION("pos_ticks", SCA_ISensor, pyattr_get_posTicks),
KX_PYATTRIBUTE_RO_FUNCTION("neg_ticks", SCA_ISensor, pyattr_get_negTicks),
+ KX_PYATTRIBUTE_RW_FUNCTION("frequency", SCA_ISensor, pyattr_get_frequency, pyattr_set_frequency),
{ NULL } //Sentinel
};
@@ -444,6 +445,27 @@ int SCA_ISensor::pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrde
self->m_level = false;
return 0;
}
+
+PyObject *SCA_ISensor::pyattr_get_frequency(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ SCA_ISensor *self = static_cast<SCA_ISensor*>(self_v);
+ ShowDeprecationWarning("SCA_ISensor.frequency", "SCA_ISensor.skippedTicks");
+ return PyLong_FromLong(self->m_skipped_ticks);
+}
+
+int SCA_ISensor::pyattr_set_frequency(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ SCA_ISensor *self = static_cast<SCA_ISensor*>(self_v);
+ ShowDeprecationWarning("SCA_ISensor.frequency", "SCA_ISensor.skippedTicks");
+ if (PyLong_Check(value)) {
+ self->m_skipped_ticks = PyLong_AsLong(value);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "sensor.frequency = int: Sensor, expected an integer");
+ return PY_SET_ATTR_FAIL;
+ }
+}
#endif // WITH_PYTHON
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index 7bbba7aaafe..1e82f3ab11f 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -57,8 +57,8 @@ protected:
/** Pulse negative pulses? */
bool m_neg_pulsemode;
- /** Repeat frequency in pulse mode. */
- int m_pulse_frequency;
+ /** Number of skipped ticks between two active pulses. */
+ int m_skipped_ticks;
/** Number of ticks since the last positive pulse. */
int m_pos_ticks;
@@ -125,7 +125,7 @@ public:
*/
void SetPulseMode(bool posmode,
bool negmode,
- int freq);
+ int skippedticks);
/** Set inversion of pulses on or off. */
void SetInvert(bool inv);
@@ -201,6 +201,8 @@ public:
static PyObject* pyattr_get_status(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_posTicks(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_negTicks(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_frequency(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_frequency(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static int pyattr_check_level(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_check_tap(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index 6f34f8710c1..6841d2a8ea1 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -265,13 +265,8 @@ bool SCA_PropertySensor::CheckPropertyCondition()
//the concept of Edge and Level triggering has unwanted effect for KX_PROPSENSOR_CHANGED
//see Game Engine bugtracker [ #3809 ]
- if (m_checktype != KX_PROPSENSOR_CHANGED)
- {
- m_recentresult=result;
- } else
- {
- m_recentresult=result;//true;
- }
+ m_recentresult = result;
+
return result;
}
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
index 4e93556453a..2fe4d18a7fc 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -107,7 +107,7 @@ bool SCA_RandomSensor::Evaluate()
bool evaluateResult = false;
- if (++m_interval > m_pulse_frequency) {
+ if (++m_interval > m_skipped_ticks) {
bool drawResult = false;
m_interval = 0;
if (m_iteration > 31) {
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h
index acbea477e38..34cc9759a08 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.h
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h
@@ -71,6 +71,8 @@ public:
virtual void ResizeWindow(int width, int height) {}
+ virtual void GetDisplayDimensions(int &width, int &height) {}
+
/**
* \section Methods inherited from abstract base class RAS_ICanvas.
*/
diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
index a1bc7e88840..dfa115e085c 100644
--- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt
+++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
@@ -46,6 +46,7 @@ set(INC
../../../blender/imbuf
../../../blender/makesdna
../../../blender/makesrna
+ ../../../blender/pointcache
../../../../intern/container
../../../../intern/ghost
../../../../intern/glew-mx
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 6b69a991968..b8ce67743de 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -636,7 +636,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
if (!m_networkdevice)
goto initFailed;
- sound_init(m_maggie);
+ BKE_sound_init(m_maggie);
// create a ketsjisystem (only needed for timing and stuff)
m_kxsystem = new GPG_System (m_system);
@@ -672,7 +672,7 @@ bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
return m_engineInitialized;
initFailed:
- sound_exit();
+ BKE_sound_exit();
delete m_kxsystem;
delete m_networkdevice;
delete m_mouse;
@@ -847,7 +847,7 @@ void GPG_Application::exitEngine()
if (!m_engineInitialized)
return;
- sound_exit();
+ BKE_sound_exit();
if (m_ketsjiengine)
{
stopEngine();
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
index 556f85804ea..09eb1691dae 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.cpp
@@ -121,6 +121,18 @@ bool GPG_Canvas::GetSwapInterval(int& intervalOut)
return false;
}
+void GPG_Canvas::GetDisplayDimensions(int &width, int &height)
+ {
+ unsigned int uiwidth;
+ unsigned int uiheight;
+
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ system->getMainDisplayDimensions(uiwidth, uiheight);
+
+ width = uiwidth;
+ height = uiheight;
+}
+
void GPG_Canvas::ResizeWindow(int width, int height)
{
if (m_window->getState() == GHOST_kWindowStateFullScreen)
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h
index 337c2cedf55..18afbf6cd9e 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Canvas.h
+++ b/source/gameengine/GamePlayer/ghost/GPG_Canvas.h
@@ -63,6 +63,8 @@ public:
virtual float GetMouseNormalizedX(int x);
virtual float GetMouseNormalizedY(int y);
+ virtual void GetDisplayDimensions(int &width, int &height);
+
virtual void ResizeWindow(int width, int height);
virtual void SetFullScreen(bool enable);
virtual bool GetFullScreen();
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index 915fe614957..6d97447dff0 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -74,11 +74,14 @@ extern "C"
#include "BKE_report.h"
#include "BKE_library.h"
#include "BKE_modifier.h"
+#include "BKE_material.h"
#include "BKE_text.h"
#include "BKE_sound.h"
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
+
+#include "PTC_api.h"
#ifdef __APPLE__
int GHOST_HACK_getFirstFile(char buf[]);
@@ -451,6 +454,7 @@ int main(int argc, char** argv)
RNA_init();
init_nodesystem();
+ PTC_alembic_init();
initglobals();
@@ -517,9 +521,12 @@ int main(int argc, char** argv)
// enable fast mipmap generation
U.use_gpu_mipmap = 1;
- sound_init_once();
+ BKE_sound_init_once();
+
+ // Initialize a default material for meshes without materials.
+ init_def_material();
- set_free_windowmanager_cb(wm_free);
+ BKE_library_callback_free_window_manager_set(wm_free);
/* if running blenderplayer the last argument can't be parsed since it has to be the filename. else it is bundled */
isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript
index 610abcd0357..27adc000413 100644
--- a/source/gameengine/GamePlayer/ghost/SConscript
+++ b/source/gameengine/GamePlayer/ghost/SConscript
@@ -57,6 +57,7 @@ incs = [
'#source/blender/include',
'#source/blender/makesdna',
'#source/blender/makesrna',
+ '#source/blender/pointcache',
'#source/gameengine/Rasterizer',
'#source/gameengine/GameLogic',
'#source/gameengine/Expressions',
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
index a50c07a486a..9bae119107e 100644
--- a/source/gameengine/Ketsji/BL_Action.cpp
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -49,6 +49,7 @@ extern "C" {
// Needed for material IPOs
#include "BKE_material.h"
#include "DNA_material_types.h"
+#include "DNA_scene_types.h"
}
#include "MEM_guardedalloc.h"
@@ -162,6 +163,14 @@ bool BL_Action::Play(const char* name,
m_obj->GetSGNode()->AddSGController(sg_contr);
sg_contr->SetObject(m_obj->GetSGNode());
+ // World
+ sg_contr = BL_CreateWorldIPO(m_action, kxscene->GetBlenderScene()->world, kxscene->GetSceneConverter());
+ if (sg_contr) {
+ m_sg_contr_list.push_back(sg_contr);
+ m_obj->GetSGNode()->AddSGController(sg_contr);
+ sg_contr->SetObject(m_obj->GetSGNode());
+ }
+
// Try obcolor
sg_contr = BL_CreateObColorIPO(m_action, m_obj, kxscene->GetSceneConverter());
if (sg_contr) {
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index 58739e7ef81..e1a28961a68 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -203,9 +203,21 @@ void BL_Texture::InitGLTex(unsigned int *pix,int x,int y,bool mipmap)
glBindTexture(GL_TEXTURE_2D, mTexture );
if ( mipmap ) {
+ int i;
+ ImBuf *ibuf;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, x, y, GL_RGBA, GL_UNSIGNED_BYTE, pix );
+
+ ibuf = IMB_allocFromBuffer(pix, NULL, x, y);
+
+ IMB_makemipmap(ibuf, true);
+
+ for (i = 0; i < ibuf->miptot; i++) {
+ ImBuf *mip = IMB_getmipmap(ibuf, i);
+
+ glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, mip->x, mip->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect);
+ }
+ IMB_freeImBuf(ibuf);
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -245,9 +257,17 @@ void BL_Texture::InitNonPow2Tex(unsigned int *pix,int x,int y,bool mipmap)
glBindTexture(GL_TEXTURE_2D, mTexture );
if ( mipmap ) {
+ int i;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, nx, ny, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect );
+
+ IMB_makemipmap(ibuf, true);
+
+ for (i = 0; i < ibuf->miptot; i++) {
+ ImBuf *mip = IMB_getmipmap(ibuf, i);
+
+ glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, mip->x, mip->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect);
+ }
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 9f0b582045f..7ec2673bf1f 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -94,6 +94,21 @@ void KX_BlenderMaterial::Initialize(
((data->ras_mode &TEX)),
game
);
+ Material *ma = data->material;
+
+ // Save material data to restore on exit
+ mSavedData.r = ma->r;
+ mSavedData.g = ma->g;
+ mSavedData.b = ma->b;
+ mSavedData.a = ma->alpha;
+ mSavedData.specr = ma->specr;
+ mSavedData.specg = ma->specg;
+ mSavedData.specb = ma->specb;
+ mSavedData.spec = ma->spec;
+ mSavedData.ref = ma->ref;
+ mSavedData.hardness = ma->har;
+ mSavedData.emit = ma->emit;
+
mMaterial = data;
mShader = 0;
mBlenderShader = 0;
@@ -124,6 +139,20 @@ void KX_BlenderMaterial::Initialize(
KX_BlenderMaterial::~KX_BlenderMaterial()
{
+ Material *ma = mMaterial->material;
+ // Restore Blender material data
+ ma->r = mSavedData.r;
+ ma->g = mSavedData.g;
+ ma->b = mSavedData.b;
+ ma->alpha = mSavedData.a;
+ ma->specr = mSavedData.specr;
+ ma->specg = mSavedData.specg;
+ ma->specb = mSavedData.specb;
+ ma->spec = mSavedData.spec;
+ ma->ref = mSavedData.ref;
+ ma->har = mSavedData.hardness;
+ ma->emit = mSavedData.emit;
+
// cleanup work
if (mConstructed)
// clean only if material was actually used
@@ -793,17 +822,19 @@ void KX_BlenderMaterial::UpdateIPO(
)
{
// only works one deep now
- mMaterial->speccolor[0] = (float)(specrgb)[0];
- mMaterial->speccolor[1] = (float)(specrgb)[1];
- mMaterial->speccolor[2] = (float)(specrgb)[2];
- mMaterial->matcolor[0] = (float)(rgba[0]);
- mMaterial->matcolor[1] = (float)(rgba[1]);
- mMaterial->matcolor[2] = (float)(rgba[2]);
- mMaterial->alpha = (float)(alpha);
- mMaterial->hard = (float)(hard);
- mMaterial->emit = (float)(emit);
- mMaterial->spec_f = (float)(spec);
- mMaterial->ref = (float)(ref);
+
+ // GLSL Multitexture Input
+ mMaterial->material->specr = mMaterial->speccolor[0] = (float)(specrgb)[0];
+ mMaterial->material->specg = mMaterial->speccolor[1] = (float)(specrgb)[1];
+ mMaterial->material->specb = mMaterial->speccolor[2] = (float)(specrgb)[2];
+ mMaterial->material->r = mMaterial->matcolor[0] = (float)(rgba[0]);
+ mMaterial->material->g = mMaterial->matcolor[1] = (float)(rgba[1]);
+ mMaterial->material->b = mMaterial->matcolor[2] = (float)(rgba[2]);
+ mMaterial->material->alpha = mMaterial->alpha = (float)(rgba[3]);
+ mMaterial->material->har = mMaterial->hard = (float)(hard);
+ mMaterial->material->emit = mMaterial->emit = (float)(emit);
+ mMaterial->material->spec = mMaterial->spec_f = (float)(spec);
+ mMaterial->material->ref = mMaterial->ref = (float)(ref);
}
void KX_BlenderMaterial::Replace_IScene(SCA_IScene *val)
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index b7c64215eaf..23921588d6a 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -134,6 +134,15 @@ private:
bool mConstructed; // if false, don't clean on exit
int mLightLayer;
+ struct {
+ float r, g, b, a;
+ float specr, specg, specb;
+ float spec;
+ float ref;
+ float hardness;
+ float emit;
+ } mSavedData;
+
void InitTextures();
void SetBlenderGLSLShader();
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index ce2fe5f5ad8..4456345e1d9 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -463,6 +463,7 @@ bool KX_Camera::GetFrustumCulling() const
void KX_Camera::EnableViewport(bool viewport)
{
+ InvalidateProjectionMatrix(false); // We need to reset projection matrix
m_camdata.m_viewport = viewport;
}
@@ -885,7 +886,7 @@ int KX_Camera::pyattr_set_projection_matrix(void *self_v, const KX_PYATTRIBUTE_D
PyObject *KX_Camera::pyattr_get_modelview_matrix(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_Camera* self = static_cast<KX_Camera*>(self_v);
- return PyObjectFrom(self->GetModelviewMatrix());
+ return PyObjectFrom(self->GetWorldToCamera());
}
PyObject *KX_Camera::pyattr_get_camera_to_world(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
@@ -994,7 +995,7 @@ KX_PYMETHODDEF_DOC_O(KX_Camera, getScreenPosition,
GLdouble modelmatrix[16];
GLdouble projmatrix[16];
- MT_Matrix4x4 m_modelmatrix = this->GetModelviewMatrix();
+ MT_Matrix4x4 m_modelmatrix = this->GetWorldToCamera();
MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix();
m_modelmatrix.getValue(modelmatrix);
@@ -1037,7 +1038,7 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, getScreenVect,
GLdouble modelmatrix[16];
GLdouble projmatrix[16];
- MT_Matrix4x4 m_modelmatrix = this->GetModelviewMatrix();
+ MT_Matrix4x4 m_modelmatrix = this->GetWorldToCamera();
MT_Matrix4x4 m_projmatrix = this->GetProjectionMatrix();
m_modelmatrix.getValue(modelmatrix);
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index 454c4a54ec1..eeb836c44b8 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -192,7 +192,7 @@ public:
void InvalidateProjectionMatrix(bool valid = false);
/** Gets the modelview matrix that is used by the rasterizer.
- * \warning If the Camera is a dynamic object then this method may return garbage. Use GetCameraToWorld() instead.
+ * \warning If the Camera is a dynamic object then this method may return garbage. Use GetWorldToCamera() instead.
*/
const MT_Matrix4x4& GetModelviewMatrix() const;
diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp
index 9789a8294ee..f3b098f407a 100644
--- a/source/gameengine/Ketsji/KX_FontObject.cpp
+++ b/source/gameengine/Ketsji/KX_FontObject.cpp
@@ -118,7 +118,6 @@ CValue* KX_FontObject::GetReplica()
void KX_FontObject::ProcessReplica()
{
KX_GameObject::ProcessReplica();
- KX_GetActiveScene()->AddFont(this);
}
int GetFontId(VFont *vfont)
diff --git a/source/gameengine/Ketsji/KX_FontObject.h b/source/gameengine/Ketsji/KX_FontObject.h
index 209ab6ca69f..bf70eedfde6 100644
--- a/source/gameengine/Ketsji/KX_FontObject.h
+++ b/source/gameengine/Ketsji/KX_FontObject.h
@@ -54,6 +54,7 @@ public:
*/
virtual CValue* GetReplica();
virtual void ProcessReplica();
+ virtual int GetGameObjectType() { return OBJ_TEXT; }
protected:
std::vector<STR_String> m_text;
diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp
index c6087ac676d..a23af680104 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.cpp
+++ b/source/gameengine/Ketsji/KX_GameActuator.cpp
@@ -178,6 +178,11 @@ bool KX_GameActuator::Update()
// obtain file size:
fseek (fp , 0 , SEEK_END);
marshal_length = ftell(fp);
+ if (marshal_length == -1) {
+ printf("warning: could not read position of '%s'\n", mashal_path);
+ fclose(fp);
+ break;
+ }
rewind(fp);
marshal_buffer = (char*) malloc (sizeof(char)*marshal_length);
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 8d22c9132fd..e77960b99b1 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -47,6 +47,7 @@
#include "KX_MeshProxy.h"
#include "KX_PolyProxy.h"
#include <stdio.h> // printf
+#include <climits> // USHRT_MAX
#include "SG_Controller.h"
#include "PHY_IGraphicController.h"
#include "SG_Node.h"
@@ -68,6 +69,7 @@
#include "BL_ActionManager.h"
#include "BL_Action.h"
+#include "KX_PythonCallBack.h"
#include "PyObjectPlus.h" /* python stuff */
#include "BLI_utildefines.h"
#include "python_utildefines.h"
@@ -91,9 +93,10 @@ KX_GameObject::KX_GameObject(
: SCA_IObject(),
m_bDyna(false),
m_layer(0),
+ m_currentLodLevel(0),
+ m_previousLodLevel(0),
m_pBlenderObject(NULL),
m_pBlenderGroupObject(NULL),
- m_bSuspendDynamics(false),
m_bUseObjectColor(false),
m_bIsNegativeScaling(false),
m_objectColor(1.0, 1.0, 1.0, 1.0),
@@ -291,6 +294,21 @@ void KX_GameObject::SetDupliGroupObject(KX_GameObject* obj)
m_pDupliGroupObject = obj;
}
+void KX_GameObject::AddConstraint(bRigidBodyJointConstraint *cons)
+{
+ m_constraints.push_back(cons);
+}
+
+std::vector<bRigidBodyJointConstraint*> KX_GameObject::GetConstraints()
+{
+ return m_constraints;
+}
+
+void KX_GameObject::ClearConstraints()
+{
+ m_constraints.clear();
+}
+
KX_GameObject* KX_GameObject::GetParent()
{
KX_GameObject* result = NULL;
@@ -545,13 +563,26 @@ void KX_GameObject::ActivateGraphicController(bool recurse)
}
}
-void KX_GameObject::SetUserCollisionGroup(short group)
+void KX_GameObject::SetUserCollisionGroup(unsigned short group)
{
m_userCollisionGroup = group;
+ if (m_pPhysicsController)
+ m_pPhysicsController->RefreshCollisions();
}
-void KX_GameObject::SetUserCollisionMask(short mask)
+void KX_GameObject::SetUserCollisionMask(unsigned short mask)
{
m_userCollisionMask = mask;
+ if (m_pPhysicsController)
+ m_pPhysicsController->RefreshCollisions();
+}
+
+unsigned short KX_GameObject::GetUserCollisionGroup()
+{
+ return m_userCollisionGroup;
+}
+unsigned short KX_GameObject::GetUserCollisionMask()
+{
+ return m_userCollisionMask;
}
bool KX_GameObject::CheckCollision(KX_GameObject* other)
@@ -569,6 +600,13 @@ CValue* KX_GameObject::GetReplica()
return replica;
}
+bool KX_GameObject::IsDynamicsSuspended() const
+{
+ if (m_pPhysicsController)
+ return m_pPhysicsController->IsSuspended();
+ return false;
+}
+
float KX_GameObject::getLinearDamping() const
{
if (m_pPhysicsController)
@@ -768,35 +806,74 @@ void KX_GameObject::AddLodMesh(RAS_MeshObject* mesh)
m_lodmeshes.push_back(mesh);
}
+
+static float calcHysteresis(KX_Scene *kxscene, LodLevel *lod)
+{
+ float hystvariance = 0.0f;
+
+ if (!kxscene->IsActivedLodHysteresis())
+ return hystvariance;
+
+ short hysteresis = 0;
+ // if exists, LoD level hysteresis will override scene hysteresis
+ if (lod->next->flags & OB_LOD_USE_HYST)
+ hysteresis = lod->next->obhysteresis;
+ else
+ hysteresis = kxscene->GetLodHysteresisValue();
+
+ return hystvariance = MT_abs(lod->next->distance - lod->distance) * hysteresis / 100;
+}
+
void KX_GameObject::UpdateLod(MT_Vector3 &cam_pos)
{
// Handle dupligroups
- if (this->m_pInstanceObjects) {
- KX_GameObject * instob;
- int count = this->m_pInstanceObjects->GetCount();
+ if (m_pInstanceObjects) {
+ KX_GameObject *instob;
+ int count = m_pInstanceObjects->GetCount();
for (int i = 0; i < count; i++) {
- instob = (KX_GameObject*)this->m_pInstanceObjects->GetValue(i);
+ instob = (KX_GameObject*)m_pInstanceObjects->GetValue(i);
instob->UpdateLod(cam_pos);
}
}
- if (this->m_lodmeshes.empty()) return;
+ if (m_lodmeshes.empty())
+ return;
- MT_Vector3 delta = this->NodeGetWorldPosition() - cam_pos;
+ MT_Vector3 delta = NodeGetWorldPosition() - cam_pos;
float distance2 = delta.length2();
int level = 0;
- Object *bob = this->GetBlenderObject();
- LodLevel *lod = (LodLevel*) bob->lodlevels.first;
+ float hystvariance = 0.0f;
+ Object *bob = GetBlenderObject();
+ LodLevel *lod = (LodLevel *)bob->lodlevels.first;
+ KX_Scene *kxscene = GetScene();
+
for (; lod; lod = lod->next, level++) {
- if (!lod->source || lod->source->type != OB_MESH) level--;
- if (!lod->next || lod->next->distance * lod->next->distance > distance2) break;
- }
+ if (!lod->source || lod->source->type != OB_MESH)
+ level--;
- RAS_MeshObject *mesh = this->m_lodmeshes[level];
+ if (!lod->next)
+ break;
- if (mesh != this->m_meshes[0]) {
- this->GetScene()->ReplaceMesh(this, mesh, true, false);
+ if (level == m_previousLodLevel || level == (m_previousLodLevel + 1)) {
+ hystvariance = calcHysteresis(kxscene, lod);
+ float newdistance = lod->next->distance + hystvariance;
+ if (newdistance * newdistance > distance2)
+ break;
+ }
+ else if (level == (m_previousLodLevel - 1)) {
+ hystvariance = calcHysteresis(kxscene, lod);
+ float newdistance = lod->next->distance - hystvariance;
+ if (newdistance * newdistance > distance2)
+ break;
+ }
+ }
+
+ RAS_MeshObject *mesh = m_lodmeshes[level];
+ m_currentLodLevel = level;
+ if (mesh != m_meshes[0]) {
+ m_previousLodLevel = level;
+ GetScene()->ReplaceMesh(this, mesh, true, false);
}
}
@@ -1494,70 +1571,17 @@ void KX_GameObject::RegisterCollisionCallbacks()
}
void KX_GameObject::RunCollisionCallbacks(KX_GameObject *collider, const MT_Vector3 &point, const MT_Vector3 &normal)
{
- #ifdef WITH_PYTHON
- Py_ssize_t len;
- PyObject* collision_callbacks = m_collisionCallbacks;
-
- if (collision_callbacks && (len=PyList_GET_SIZE(collision_callbacks)))
- {
- // Argument tuples are created lazily, only when they are needed.
- PyObject *args_3 = NULL;
- PyObject *args_1 = NULL; // Only for compatibility with pre-2.74 callbacks that take 1 argument.
-
- PyObject *func;
- PyObject *ret;
- int co_argcount;
-
- // Iterate the list and run the callbacks
- for (Py_ssize_t pos=0; pos < len; pos++)
- {
- func = PyList_GET_ITEM(collision_callbacks, pos);
-
- // Get the number of arguments, supporting functions, methods and generic callables.
- if (PyMethod_Check(func)) {
- // Take away the 'self' argument for methods.
- co_argcount = ((PyCodeObject *)PyFunction_GET_CODE(PyMethod_GET_FUNCTION(func)))->co_argcount - 1;
- } else if (PyFunction_Check(func)) {
- co_argcount = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_argcount;
- } else {
- // We'll just assume the callable takes the correct number of arguments.
- co_argcount = 3;
- }
+#ifdef WITH_PYTHON
+ if (!m_collisionCallbacks || PyList_GET_SIZE(m_collisionCallbacks) == 0)
+ return;
- // Check whether the function expects the colliding object only,
- // or also the point and normal.
- if (co_argcount <= 1) {
- // One argument, or *args (which gives co_argcount == 0)
- if (args_1 == NULL) {
- args_1 = PyTuple_New(1);
- PyTuple_SET_ITEMS(args_1, collider->GetProxy());
- }
- ret = PyObject_Call(func, args_1, NULL);
- } else {
- // More than one argument, assume we can give point & normal.
- if (args_3 == NULL) {
- args_3 = PyTuple_New(3);
- PyTuple_SET_ITEMS(args_3,
- collider->GetProxy(),
- PyObjectFrom(point),
- PyObjectFrom(normal));
- }
- ret = PyObject_Call(func, args_3, NULL);
- }
+ PyObject *args[] = {collider->GetProxy(), PyObjectFrom(point), PyObjectFrom(normal)};
+ RunPythonCallBackList(m_collisionCallbacks, args, 1, ARRAY_SIZE(args));
- if (ret == NULL) {
- PyErr_Print();
- PyErr_Clear();
- }
- else {
- Py_DECREF(ret);
- }
- }
-
- if (args_3) Py_DECREF(args_3);
- if (args_1) Py_DECREF(args_1);
+ for (unsigned int i = 0; i < ARRAY_SIZE(args); ++i) {
+ Py_DECREF(args[i]);
}
- #endif
+#endif
}
/* Suspend/ resume: for the dynamic behavior, there is a simple
@@ -1889,7 +1913,7 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_NOARGS},
{"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
{"getAxisVect",(PyCFunction) KX_GameObject::sPyGetAxisVect, METH_O},
- {"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics,METH_NOARGS},
+ {"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics, METH_VARARGS},
{"restoreDynamics", (PyCFunction)KX_GameObject::sPyRestoreDynamics,METH_NOARGS},
{"enableRigidBody", (PyCFunction)KX_GameObject::sPyEnableRigidBody,METH_NOARGS},
{"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_NOARGS},
@@ -1927,6 +1951,7 @@ PyMethodDef KX_GameObject::Methods[] = {
};
PyAttributeDef KX_GameObject::Attributes[] = {
+ KX_PYATTRIBUTE_INT_RO("currentLodLevel", KX_GameObject, m_currentLodLevel),
KX_PYATTRIBUTE_RO_FUNCTION("name", KX_GameObject, pyattr_get_name),
KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
KX_PYATTRIBUTE_RO_FUNCTION("groupMembers", KX_GameObject, pyattr_get_group_members),
@@ -1934,6 +1959,7 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("scene", KX_GameObject, pyattr_get_scene),
KX_PYATTRIBUTE_RO_FUNCTION("life", KX_GameObject, pyattr_get_life),
KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass),
+ KX_PYATTRIBUTE_RO_FUNCTION("isSuspendDynamics", KX_GameObject, pyattr_get_is_suspend_dynamics),
KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMin", KX_GameObject, pyattr_get_lin_vel_min, pyattr_set_lin_vel_min),
KX_PYATTRIBUTE_RW_FUNCTION("linVelocityMax", KX_GameObject, pyattr_get_lin_vel_max, pyattr_set_lin_vel_max),
KX_PYATTRIBUTE_RW_FUNCTION("visible", KX_GameObject, pyattr_get_visible, pyattr_set_visible),
@@ -1945,6 +1971,8 @@ PyAttributeDef KX_GameObject::Attributes[] = {
KX_PYATTRIBUTE_RW_FUNCTION("scaling", KX_GameObject, pyattr_get_worldScaling, pyattr_set_localScaling),
KX_PYATTRIBUTE_RW_FUNCTION("timeOffset",KX_GameObject, pyattr_get_timeOffset,pyattr_set_timeOffset),
KX_PYATTRIBUTE_RW_FUNCTION("collisionCallbacks", KX_GameObject, pyattr_get_collisionCallbacks, pyattr_set_collisionCallbacks),
+ KX_PYATTRIBUTE_RW_FUNCTION("collisionGroup", KX_GameObject, pyattr_get_collisionGroup, pyattr_set_collisionGroup),
+ KX_PYATTRIBUTE_RW_FUNCTION("collisionMask", KX_GameObject, pyattr_get_collisionMask, pyattr_set_collisionMask),
KX_PYATTRIBUTE_RW_FUNCTION("state", KX_GameObject, pyattr_get_state, pyattr_set_state),
KX_PYATTRIBUTE_RO_FUNCTION("meshes", KX_GameObject, pyattr_get_meshes),
KX_PYATTRIBUTE_RW_FUNCTION("localOrientation",KX_GameObject,pyattr_get_localOrientation,pyattr_set_localOrientation),
@@ -2291,6 +2319,56 @@ int KX_GameObject::pyattr_set_collisionCallbacks(void *self_v, const KX_PYATTRIB
return PY_SET_ATTR_SUCCESS;
}
+PyObject *KX_GameObject::pyattr_get_collisionGroup(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+ return PyLong_FromLong(self->GetUserCollisionGroup());
+}
+
+int KX_GameObject::pyattr_set_collisionGroup(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+ int val = PyLong_AsLong(value);
+
+ if (val == -1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "gameOb.collisionGroup = int: KX_GameObject, expected an int bit field");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ if (val < 0 || val > USHRT_MAX) {
+ PyErr_Format(PyExc_AttributeError, "gameOb.collisionGroup = int: KX_GameObject, expected a int bit field between 0 and %i", USHRT_MAX);
+ return PY_SET_ATTR_FAIL;
+ }
+
+ self->SetUserCollisionGroup(val);
+ return PY_SET_ATTR_SUCCESS;
+}
+
+PyObject *KX_GameObject::pyattr_get_collisionMask(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+ return PyLong_FromLong(self->GetUserCollisionMask());
+}
+
+int KX_GameObject::pyattr_set_collisionMask(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+ int val = PyLong_AsLong(value);
+
+ if (val == -1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "gameOb.collisionMask = int: KX_GameObject, expected an int bit field");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ if (val < 0 || val > USHRT_MAX) {
+ PyErr_Format(PyExc_AttributeError, "gameOb.collisionMask = int: KX_GameObject, expected a int bit field between 0 and %i", USHRT_MAX);
+ return PY_SET_ATTR_FAIL;
+ }
+
+ self->SetUserCollisionMask(val);
+ return PY_SET_ATTR_SUCCESS;
+}
+
PyObject* KX_GameObject::pyattr_get_scene(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject *self = static_cast<KX_GameObject*>(self_v);
@@ -2347,6 +2425,19 @@ int KX_GameObject::pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrd
return PY_SET_ATTR_SUCCESS;
}
+PyObject *KX_GameObject::pyattr_get_is_suspend_dynamics(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
+
+ // Only objects with a physics controller can be suspended
+ if (!self->GetPhysicsController()) {
+ PyErr_SetString(PyExc_AttributeError, "This object has not Physics Controller");
+ return NULL;
+ }
+
+ return PyBool_FromLong(self->IsDynamicsSuspended());
+}
+
PyObject *KX_GameObject::pyattr_get_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
@@ -2439,7 +2530,9 @@ int KX_GameObject::pyattr_set_record_animation(void *self_v, const KX_PYATTRIBUT
PyObject *KX_GameObject::pyattr_get_worldPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_GLOBAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_GLOBAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetWorldPosition());
@@ -2461,7 +2554,9 @@ int KX_GameObject::pyattr_set_worldPosition(void *self_v, const KX_PYATTRIBUTE_D
PyObject *KX_GameObject::pyattr_get_localPosition(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_LOCAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_POS_LOCAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetLocalPosition());
@@ -2483,7 +2578,9 @@ int KX_GameObject::pyattr_set_localPosition(void *self_v, const KX_PYATTRIBUTE_D
PyObject *KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_INERTIA_LOCAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_INERTIA_LOCAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
if (self->GetPhysicsController1())
@@ -2495,7 +2592,9 @@ PyObject *KX_GameObject::pyattr_get_localInertia(void *self_v, const KX_PYATTRIB
PyObject *KX_GameObject::pyattr_get_worldOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Matrix_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_GLOBAL);
+ return Matrix_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3, 3,
+ mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_GLOBAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetWorldOrientation());
@@ -2520,7 +2619,9 @@ int KX_GameObject::pyattr_set_worldOrientation(void *self_v, const KX_PYATTRIBUT
PyObject *KX_GameObject::pyattr_get_localOrientation(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Matrix_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, 3, mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_LOCAL);
+ return Matrix_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3, 3,
+ mathutils_kxgameob_matrix_cb_index, MATHUTILS_MAT_CB_ORI_LOCAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetLocalOrientation());
@@ -2544,7 +2645,9 @@ int KX_GameObject::pyattr_set_localOrientation(void *self_v, const KX_PYATTRIBUT
PyObject *KX_GameObject::pyattr_get_worldScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_GLOBAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_GLOBAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetWorldScaling());
@@ -2566,7 +2669,9 @@ int KX_GameObject::pyattr_set_worldScaling(void *self_v, const KX_PYATTRIBUTE_DE
PyObject *KX_GameObject::pyattr_get_localScaling(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_LOCAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_SCALE_LOCAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->NodeGetLocalScaling());
@@ -2668,7 +2773,9 @@ int KX_GameObject::pyattr_set_worldTransform(void *self_v, const KX_PYATTRIBUTE_
PyObject *KX_GameObject::pyattr_get_worldLinearVelocity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_LINVEL_GLOBAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_LINVEL_GLOBAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(GetLinearVelocity(false));
@@ -2690,7 +2797,9 @@ int KX_GameObject::pyattr_set_worldLinearVelocity(void *self_v, const KX_PYATTRI
PyObject *KX_GameObject::pyattr_get_localLinearVelocity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_LINVEL_LOCAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_LINVEL_LOCAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(GetLinearVelocity(true));
@@ -2712,7 +2821,9 @@ int KX_GameObject::pyattr_set_localLinearVelocity(void *self_v, const KX_PYATTRI
PyObject *KX_GameObject::pyattr_get_worldAngularVelocity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_ANGVEL_GLOBAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_ANGVEL_GLOBAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(GetAngularVelocity(false));
@@ -2734,7 +2845,9 @@ int KX_GameObject::pyattr_set_worldAngularVelocity(void *self_v, const KX_PYATTR
PyObject *KX_GameObject::pyattr_get_localAngularVelocity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_ANGVEL_LOCAL);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_ANGVEL_LOCAL);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(GetAngularVelocity(true));
@@ -2855,7 +2968,9 @@ PyObject *KX_GameObject::pyattr_get_meshes(void *self_v, const KX_PYATTRIBUTE_DE
PyObject *KX_GameObject::pyattr_get_obcolor(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
#ifdef USE_MATHUTILS
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 4, mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_OBJECT_COLOR);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 4,
+ mathutils_kxgameob_vector_cb_index, MATHUTILS_VEC_CB_OBJECT_COLOR);
#else
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyObjectFrom(self->GetObjectColor());
@@ -3233,10 +3348,16 @@ PyObject *KX_GameObject::PyApplyImpulse(PyObject *args)
-PyObject *KX_GameObject::PySuspendDynamics()
+PyObject *KX_GameObject::PySuspendDynamics(PyObject *args)
{
+ bool ghost = false;
+
+ if (!PyArg_ParseTuple(args, "|b", &ghost))
+ return NULL;
+
if (GetPhysicsController())
- GetPhysicsController()->SuspendDynamics();
+ GetPhysicsController()->SuspendDynamics(ghost);
+
Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 5800cbc6834..9c081b449ec 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -49,6 +49,7 @@
#include "CTR_HashedPtr.h"
#include "KX_Scene.h"
#include "KX_KetsjiEngine.h" /* for m_anim_framerate */
+#include "DNA_constraint_types.h" /* for constraint replication */
#include "DNA_object_types.h"
#include "SCA_LogicManager.h" /* for ConvertPythonToGameObject to search object names */
@@ -88,18 +89,19 @@ protected:
int m_layer;
std::vector<RAS_MeshObject*> m_meshes;
std::vector<RAS_MeshObject*> m_lodmeshes;
+ int m_currentLodLevel;
+ short m_previousLodLevel;
SG_QList m_meshSlots; // head of mesh slots of this
struct Object* m_pBlenderObject;
struct Object* m_pBlenderGroupObject;
- bool m_bSuspendDynamics;
bool m_bUseObjectColor;
bool m_bIsNegativeScaling;
MT_Vector4 m_objectColor;
// Bit fields for user control over physics collisions
- short m_userCollisionGroup;
- short m_userCollisionMask;
+ unsigned short m_userCollisionGroup;
+ unsigned short m_userCollisionMask;
// visible = user setting
// culled = while rendering, depending on camera
@@ -116,6 +118,7 @@ protected:
SG_Node* m_pSGNode;
MT_CmMatrix4x4 m_OpenGL_4x4Matrix;
+ std::vector<bRigidBodyJointConstraint*> m_constraints;
KX_ObstacleSimulation* m_pObstacleSimulation;
@@ -192,6 +195,14 @@ public:
void
UpdateBlenderObjectMatrix(Object* blendobj=NULL);
+ /**
+ * Used for constraint replication for group instances.
+ * The list of constraints is filled during data conversion.
+ */
+ void AddConstraint(bRigidBodyJointConstraint *cons);
+ std::vector<bRigidBodyJointConstraint*> GetConstraints();
+ void ClearConstraints();
+
/**
* Get a pointer to the game object that is the parent of
* this object. Or NULL if there is no parent. The returned
@@ -506,8 +517,17 @@ public:
*/
void ActivateGraphicController(bool recurse);
- void SetUserCollisionGroup(short filter);
- void SetUserCollisionMask(short mask);
+ /** Set the object's collison group
+ * \param filter The group bitfield
+ */
+ void SetUserCollisionGroup(unsigned short filter);
+
+ /** Set the object's collison mask
+ * \param filter The mask bitfield
+ */
+ void SetUserCollisionMask(unsigned short mask);
+ unsigned short GetUserCollisionGroup();
+ unsigned short GetUserCollisionMask();
/**
* Extra broadphase check for user controllable collisions
*/
@@ -607,6 +627,8 @@ public:
return m_bDyna;
}
+ bool IsDynamicsSuspended() const;
+
/**
* Should we record animation for this object?
*/
@@ -892,7 +914,7 @@ public:
* Change the layer of the object (when it is added in another layer
* than the original layer)
*/
- void
+ virtual void
SetLayer(
int l
);
@@ -983,7 +1005,7 @@ public:
KX_PYMETHOD_O(KX_GameObject,SetState);
KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
KX_PYMETHOD_O(KX_GameObject,GetAxisVect);
- KX_PYMETHOD_NOARGS(KX_GameObject,SuspendDynamics);
+ KX_PYMETHOD_VARARGS(KX_GameObject,SuspendDynamics);
KX_PYMETHOD_NOARGS(KX_GameObject,RestoreDynamics);
KX_PYMETHOD_NOARGS(KX_GameObject,EnableRigidBody);
KX_PYMETHOD_NOARGS(KX_GameObject,DisableRigidBody);
@@ -1027,6 +1049,7 @@ public:
static PyObject* pyattr_get_life(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_mass(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_is_suspend_dynamics(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_lin_vel_min(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_lin_vel_max(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
@@ -1073,6 +1096,10 @@ public:
static int pyattr_set_obcolor(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_collisionCallbacks(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_collisionCallbacks(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_collisionGroup(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_collisionGroup(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_collisionMask(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_collisionMask(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_debug(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_debug(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_debugRecursive(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
diff --git a/source/gameengine/Ketsji/KX_IpoConvert.cpp b/source/gameengine/Ketsji/KX_IpoConvert.cpp
index 57130bf57b2..7b00760ee7b 100644
--- a/source/gameengine/Ketsji/KX_IpoConvert.cpp
+++ b/source/gameengine/Ketsji/KX_IpoConvert.cpp
@@ -269,52 +269,80 @@ SG_Controller *BL_CreateCameraIPO(struct bAction *action, KX_GameObject* camera
return ipocontr;
}
-void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *converter)
-{
-
- if (blenderworld->adt) {
- KX_WorldIpoController* ipocontr = new KX_WorldIpoController();
-
-// Erwin, hook up the world ipo controller here
-// Gino: hook it up to what ?
-// is there a userinterface element for that ?
-// for now, we have some new python hooks to access the data, for a work-around
-
- ipocontr->m_mist_start = blenderworld->miststa;
- ipocontr->m_mist_dist = blenderworld->mistdist;
- ipocontr->m_mist_rgb[0] = blenderworld->horr;
- ipocontr->m_mist_rgb[1] = blenderworld->horg;
- ipocontr->m_mist_rgb[2] = blenderworld->horb;
+SG_Controller * BL_CreateWorldIPO( bAction *action, struct World *blenderworld, KX_BlenderSceneConverter *converter )
+{
+ KX_WorldIpoController *ipocontr = NULL;
- BL_InterpolatorList *adtList= GetAdtList(blenderworld->adt->action, converter);
+ if (blenderworld) {
+ BL_InterpolatorList *adtList = GetAdtList(action, converter);
- // For each active channel in the adtList add an
- // interpolator to the game object.
-
+ // For each active channel in the adtList add an interpolator to the game object.
KX_IInterpolator *interpolator;
KX_IScalarInterpolator *interp;
-
+
+ for (int i=0; i<3; i++) {
+ if ((interp = adtList->GetScalarInterpolator("ambient_color", i))) {
+ if (!ipocontr) {
+ ipocontr = new KX_WorldIpoController();
+ }
+ interpolator = new KX_ScalarInterpolator(&ipocontr->m_ambi_rgb[i], interp);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyAmbientColor(true);
+ }
+ }
+
for (int i=0; i<3; i++) {
if ((interp = adtList->GetScalarInterpolator("horizon_color", i))) {
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[i], interp);
+ if (!ipocontr) {
+ ipocontr = new KX_WorldIpoController();
+ }
+ interpolator = new KX_ScalarInterpolator(&ipocontr->m_hori_rgb[i], interp);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyMistColor(true);
+ ipocontr->SetModifyHorizonColor(true);
}
}
- if ((interp = adtList->GetScalarInterpolator("mist.depth", 0))) {
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_dist, interp);
+ if ((interp = adtList->GetScalarInterpolator("mist_settings.start", 0))) {
+ if (!ipocontr) {
+ ipocontr = new KX_WorldIpoController();
+ }
+ interpolator = new KX_ScalarInterpolator(&ipocontr->m_mist_start, interp);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistStart(true);
+ }
+
+ if ((interp = adtList->GetScalarInterpolator("mist_settings.depth", 0))) {
+ if (!ipocontr) {
+ ipocontr = new KX_WorldIpoController();
+ }
+ interpolator = new KX_ScalarInterpolator(&ipocontr->m_mist_dist, interp);
ipocontr->AddInterpolator(interpolator);
ipocontr->SetModifyMistDist(true);
}
- if ((interp = adtList->GetScalarInterpolator("mist.start", 0))) {
- interpolator= new KX_ScalarInterpolator(&ipocontr->m_mist_start, interp);
+ if ((interp = adtList->GetScalarInterpolator("mist_settings.intensity", 0))) {
+ if (!ipocontr) {
+ ipocontr = new KX_WorldIpoController();
+ }
+ interpolator = new KX_ScalarInterpolator(&ipocontr->m_mist_intensity, interp);
ipocontr->AddInterpolator(interpolator);
- ipocontr->SetModifyMistStart(true);
+ ipocontr->SetModifyMistIntensity(true);
+ }
+
+ if (ipocontr) {
+ ipocontr->m_mist_start = blenderworld->miststa;
+ ipocontr->m_mist_dist = blenderworld->mistdist;
+ ipocontr->m_mist_intensity = blenderworld->misi;
+ ipocontr->m_hori_rgb[0] = blenderworld->horr;
+ ipocontr->m_hori_rgb[1] = blenderworld->horg;
+ ipocontr->m_hori_rgb[2] = blenderworld->horb;
+ ipocontr->m_ambi_rgb[0] = blenderworld->ambr;
+ ipocontr->m_ambi_rgb[1] = blenderworld->ambg;
+ ipocontr->m_ambi_rgb[2] = blenderworld->ambb;
}
}
+ return ipocontr;
}
SG_Controller *BL_CreateMaterialIpo(
@@ -368,7 +396,7 @@ SG_Controller *BL_CreateMaterialIpo(
ipocontr->AddInterpolator(interpolator);
}
- if ((sinterp = adtList->GetScalarInterpolator("specularity", 0))) {
+ if ((sinterp = adtList->GetScalarInterpolator("specular_intensity", 0))) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController(matname_hash);
}
@@ -376,7 +404,7 @@ SG_Controller *BL_CreateMaterialIpo(
ipocontr->AddInterpolator(interpolator);
}
- if ((sinterp = adtList->GetScalarInterpolator("diffuse_reflection", 0))) {
+ if ((sinterp = adtList->GetScalarInterpolator("diffuse_intensity", 0))) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController(matname_hash);
}
diff --git a/source/gameengine/Ketsji/KX_IpoConvert.h b/source/gameengine/Ketsji/KX_IpoConvert.h
index a653e4e110b..6db43552811 100644
--- a/source/gameengine/Ketsji/KX_IpoConvert.h
+++ b/source/gameengine/Ketsji/KX_IpoConvert.h
@@ -50,7 +50,8 @@ SG_Controller *BL_CreateLampIPO(bAction *action,
KX_GameObject* lightobj,
KX_BlenderSceneConverter *converter);
-void BL_ConvertWorldIpos(struct World* blenderworld,
+SG_Controller *BL_CreateWorldIPO(bAction *action,
+ struct World *blenderworld,
KX_BlenderSceneConverter *converter);
SG_Controller *BL_CreateCameraIPO(bAction *action,
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index e453b757b7e..40af9b4ca39 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -312,10 +312,11 @@ void KX_KetsjiEngine::RenderDome()
// for each scene, call the proceed functions
{
scene = *sceneit;
+ KX_SetActiveScene(scene);
KX_Camera* cam = scene->GetActiveCamera();
// pass the scene's worldsettings to the rasterizer
- SetWorldSettings(scene->GetWorldInfo());
+ scene->GetWorldInfo()->UpdateWorldSettings();
// shadow buffers
if (i == 0) {
@@ -389,8 +390,10 @@ void KX_KetsjiEngine::RenderDome()
);
}
m_dome->Draw();
+
// Draw Callback for the last scene
#ifdef WITH_PYTHON
+ PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
scene->RunDrawingCallbacks(scene->GetPostDrawCB());
#endif
EndFrame();
@@ -475,7 +478,7 @@ void KX_KetsjiEngine::ClearFrame()
if (doclear) {
KX_Scene* firstscene = *m_scenes.begin();
- SetBackGround(firstscene->GetWorldInfo());
+ firstscene->GetWorldInfo()->UpdateBackGround();
m_canvas->SetViewPort(clearvp.GetLeft(), clearvp.GetBottom(),
clearvp.GetRight(), clearvp.GetTop());
@@ -825,7 +828,7 @@ void KX_KetsjiEngine::Render()
KX_Scene* scene = *sceneit;
KX_Camera* cam = scene->GetActiveCamera();
// pass the scene's worldsettings to the rasterizer
- SetWorldSettings(scene->GetWorldInfo());
+ scene->GetWorldInfo()->UpdateWorldSettings();
// this is now done incrementatlly in KX_Scene::CalculateVisibleMeshes
//scene->UpdateMeshTransformations();
@@ -882,7 +885,7 @@ void KX_KetsjiEngine::Render()
KX_Camera* cam = scene->GetActiveCamera();
// pass the scene's worldsettings to the rasterizer
- SetWorldSettings(scene->GetWorldInfo());
+ scene->GetWorldInfo()->UpdateWorldSettings();
if (scene->IsClearingZBuffer())
m_rasterizer->ClearDepthBuffer();
@@ -962,54 +965,6 @@ const STR_String& KX_KetsjiEngine::GetExitString()
return m_exitstring;
}
-
-void KX_KetsjiEngine::SetBackGround(KX_WorldInfo* wi)
-{
- if (wi->hasWorld())
- {
- if (m_rasterizer->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED)
- {
- m_rasterizer->SetBackColor(
- wi->getBackColorRed(),
- wi->getBackColorGreen(),
- wi->getBackColorBlue(),
- 0.0
- );
- }
- }
-}
-
-
-
-void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi)
-{
- if (wi->hasWorld())
- {
- // ...
- m_rasterizer->SetAmbientColor(
- wi->getAmbientColorRed(),
- wi->getAmbientColorGreen(),
- wi->getAmbientColorBlue()
- );
-
- if (m_rasterizer->GetDrawingMode() >= RAS_IRasterizer::KX_SOLID)
- {
- if (wi->hasMist())
- {
- m_rasterizer->SetFog(
- wi->getMistStart(),
- wi->getMistDistance(),
- wi->getMistColorRed(),
- wi->getMistColorGreen(),
- wi->getMistColorBlue()
- );
- }
- }
- }
-}
-
-
-
void KX_KetsjiEngine::EnableCameraOverride(const STR_String& forscene)
{
m_overrideCam = true;
@@ -1150,6 +1105,13 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
if (!cam)
return;
+
+ KX_SetActiveScene(scene);
+
+#ifdef WITH_PYTHON
+ scene->RunDrawingCallbacks(scene->GetPreDrawSetupCB());
+#endif
+
GetSceneViewport(scene, cam, area, viewport);
// store the computed viewport in the scene
@@ -1262,6 +1224,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
SG_SetActiveStage(SG_STAGE_RENDER);
#ifdef WITH_PYTHON
+ PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
// Run any pre-drawing python callbacks
scene->RunDrawingCallbacks(scene->GetPreDrawCB());
#endif
@@ -1280,12 +1243,16 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
*/
void KX_KetsjiEngine::PostRenderScene(KX_Scene* scene)
{
+ KX_SetActiveScene(scene);
+
// We need to first make sure our viewport is correct (enabling multiple viewports can mess this up)
m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight());
m_rasterizer->FlushDebugShapes();
scene->Render2DFilters(m_canvas);
+
#ifdef WITH_PYTHON
+ PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
scene->RunDrawingCallbacks(scene->GetPostDrawCB());
#endif
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index e18b203b675..4392769ed02 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -205,14 +205,12 @@ private:
void PostRenderScene(KX_Scene* scene);
void RenderDebugProperties();
void RenderShadowBuffers(KX_Scene *scene);
- void SetBackGround(KX_WorldInfo* worldinfo);
public:
KX_KetsjiEngine(class KX_ISystem* system);
virtual ~KX_KetsjiEngine();
// set the devices and stuff. the client must take care of creating these
- void SetWorldSettings(KX_WorldInfo* worldinfo);
void SetKeyboardDevice(SCA_IInputDevice* keyboarddevice);
void SetMouseDevice(SCA_IInputDevice* mousedevice);
void SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 33cfec57fc0..0dec5715588 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -108,6 +108,7 @@ void KX_LightObject::UpdateScene(KX_Scene *kxscene)
void KX_LightObject::SetLayer(int layer)
{
+ KX_GameObject::SetLayer(layer);
m_lightobj->m_layer = layer;
}
@@ -166,27 +167,31 @@ PyAttributeDef KX_LightObject::Attributes[] = {
PyObject *KX_LightObject::pyattr_get_layer(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
return PyLong_FromLong(self->m_lightobj->m_layer);
}
int KX_LightObject::pyattr_set_layer(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
- KX_LightObject* self = static_cast<KX_LightObject*>(self_v);
+ KX_LightObject *self = static_cast<KX_LightObject *>(self_v);
+ int layer = PyLong_AsLong(value);
- if (PyLong_Check(value)) {
- int val = PyLong_AsLong(value);
- if (val < 1)
- val = 1;
- else if (val > 20)
- val = 20;
+ if (layer == -1 && PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError, "expected an integer for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
+ }
- self->m_lightobj->m_layer = val;
- return PY_SET_ATTR_SUCCESS;
+ if (layer < 1) {
+ PyErr_Format(PyExc_TypeError, "expected an integer greater than 1 for attribute \"%s\"", attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
+ }
+ else if(layer > MAX_LIGHT_LAYERS) {
+ PyErr_Format(PyExc_TypeError, "expected an integer less than %i for attribute \"%s\"", MAX_LIGHT_LAYERS, attrdef->m_name);
+ return PY_SET_ATTR_FAIL;
}
- PyErr_Format(PyExc_TypeError, "expected an integer for attribute \"%s\"", attrdef->m_name);
- return PY_SET_ATTR_FAIL;
+ self->SetLayer(layer);
+ return PY_SET_ATTR_SUCCESS;
}
PyObject *KX_LightObject::pyattr_get_energy(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index 503ed7411e9..3a58584223d 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -34,6 +34,8 @@
#include "KX_GameObject.h"
+#define MAX_LIGHT_LAYERS ((1 << 20) - 1)
+
struct GPULamp;
struct Scene;
struct Base;
@@ -58,7 +60,7 @@ public:
RAS_ILightObject* GetLightData() { return m_lightobj;}
void UpdateScene(class KX_Scene *kxscene);
- void SetLayer(int layer);
+ virtual void SetLayer(int layer);
virtual int GetGameObjectType() { return OBJ_LIGHT; }
diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.cpp b/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
index a9617aa47b8..1faf8f17d54 100644
--- a/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
+++ b/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
@@ -32,21 +32,6 @@ bool KX_MaterialIpoController::Update(double currentTime)
{
if (m_modified)
{
- m_rgba[0]=0;
- m_rgba[1]=0;
- m_rgba[2]=0;
- m_rgba[3]=0;
-
- m_specrgb[0] =0;
- m_specrgb[1] =0;
- m_specrgb[2] =0;
- m_hard =0;
- m_spec=0;
- m_ref=0;
- m_emit=0;
- m_alpha = 0;
-
-
T_InterpolatorList::iterator i;
for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
(*i)->Execute(m_ipotime);
diff --git a/source/gameengine/Ketsji/KX_MouseActuator.cpp b/source/gameengine/Ketsji/KX_MouseActuator.cpp
index 62417b4df81..c372e6e9ce2 100644
--- a/source/gameengine/Ketsji/KX_MouseActuator.cpp
+++ b/source/gameengine/Ketsji/KX_MouseActuator.cpp
@@ -278,7 +278,10 @@ bool KX_MouseActuator::Update()
setposition[1] = center_y;
}
- setMousePosition(setposition[0], setposition[1]);
+ // only trigger mouse event when it is necessary
+ if (m_oldposition[0] != position[0] || m_oldposition[1] != position[1]) {
+ setMousePosition(setposition[0], setposition[1]);
+ }
m_oldposition[0] = position[0];
m_oldposition[1] = position[1];
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
index 0eec86987be..12abcb250a7 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -75,7 +75,8 @@ KX_ObjectActuator(
m_reference(refobj),
m_active_combined_velocity (false),
m_linear_damping_active(false),
- m_angular_damping_active(false)
+ m_angular_damping_active(false),
+ m_jumping(false)
{
if (m_bitLocalFlag.ServoControl)
{
@@ -140,6 +141,7 @@ bool KX_ObjectActuator::Update()
m_angular_damping_active = false;
m_error_accumulator.setValue(0.0,0.0,0.0);
m_previous_error.setValue(0.0,0.0,0.0);
+ m_jumping = false;
return false;
} else if (parent)
@@ -223,6 +225,11 @@ bool KX_ObjectActuator::Update()
else if (m_bitLocalFlag.CharacterMotion) {
MT_Vector3 dir = m_dloc;
+ if (m_bitLocalFlag.DLoc) {
+ MT_Matrix3x3 basis = parent->GetPhysicsController()->GetOrientation();
+ dir = basis * dir;
+ }
+
if (m_bitLocalFlag.AddOrSetCharLoc) {
MT_Vector3 old_dir = character->GetWalkDirection();
@@ -236,21 +243,20 @@ bool KX_ObjectActuator::Update()
}
// We always want to set the walk direction since a walk direction of (0, 0, 0) should stop the character
- if (m_bitLocalFlag.DLoc)
- {
- MT_Matrix3x3 basis = parent->GetPhysicsController()->GetOrientation();
- dir = basis*dir;
- }
character->SetWalkDirection(dir/parent->GetScene()->GetPhysicsEnvironment()->GetNumTimeSubSteps());
if (!m_bitLocalFlag.ZeroDRot)
{
parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
}
- if (m_bitLocalFlag.CharacterJump)
- {
- character->Jump();
+ if (m_bitLocalFlag.CharacterJump) {
+ if (!m_jumping) {
+ character->Jump();
+ m_jumping = true;
+ }
+ else if (character->OnGround())
+ m_jumping = false;
}
}
else {
@@ -516,7 +522,9 @@ static Mathutils_Callback mathutils_obactu_vector_cb = {
PyObject *KX_ObjectActuator::pyattr_get_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_LINV);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_LINV);
}
int KX_ObjectActuator::pyattr_set_linV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
@@ -532,7 +540,9 @@ int KX_ObjectActuator::pyattr_set_linV(void *self_v, const KX_PYATTRIBUTE_DEF *a
PyObject *KX_ObjectActuator::pyattr_get_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
- return Vector_CreatePyObject_cb(BGE_PROXY_FROM_REF(self_v), 3, mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_ANGV);
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_kxobactu_vector_cb_index, MATHUTILS_VEC_CB_ANGV);
}
int KX_ObjectActuator::pyattr_set_angV(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
index 1f2453e3700..b5622d97611 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -116,7 +116,8 @@ class KX_ObjectActuator : public SCA_IActuator
bool m_active_combined_velocity;
bool m_linear_damping_active;
bool m_angular_damping_active;
-
+ bool m_jumping;
+
public:
enum KX_OBJECT_ACT_VEC_TYPE {
KX_OBJECT_ACT_NODEF = 0,
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index 94f5064261f..065251f5676 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -496,78 +496,46 @@ static PyObject *gPyCreateConstraint(PyObject *self,
{
/* FIXME - physicsid is a long being cast to a pointer, should at least use PyCapsule */
unsigned long long physicsid = 0, physicsid2 = 0;
- int constrainttype=0, extrainfo=0;
- int len = PyTuple_Size(args);
- int success = 1;
+ int constrainttype = 0;
int flag = 0;
+ float pivotX = 0.0f, pivotY = 0.0f, pivotZ = 0.0f, axisX = 0.0f, axisY = 0.0f, axisZ = 0.0f;
- float pivotX=1,pivotY=1,pivotZ=1,axisX=0,axisY=0,axisZ=1;
- if (len == 3)
- {
- success = PyArg_ParseTuple(args, "KKi", &physicsid, &physicsid2, &constrainttype);
- }
- else if (len == 6)
- {
- success = PyArg_ParseTuple(args, "KKifff", &physicsid, &physicsid2, &constrainttype,
- &pivotX, &pivotY, &pivotZ);
- }
- else if (len == 9)
- {
- success = PyArg_ParseTuple(args, "KKiffffff", &physicsid, &physicsid2, &constrainttype,
- &pivotX, &pivotY, &pivotZ, &axisX, &axisY, &axisZ);
- }
- else if (len == 10)
- {
- success = PyArg_ParseTuple(args, "KKiffffffi", &physicsid, &physicsid2, &constrainttype,
- &pivotX, &pivotY, &pivotZ, &axisX, &axisY, &axisZ, &flag);
- }
+ static const char *kwlist[] = {"physicsid_1", "physicsid_2", "constraint_type", "pivot_x", "pivot_y", "pivot_z",
+ "axis_X", "axis_y", "axis_z", "flag", NULL};
- /* XXX extrainfo seems to be nothing implemented. right now it works as a pivot with [X,0,0] */
- else if (len == 4)
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "KKi|ffffffi:createConstraint", (char **)kwlist,
+ &physicsid, &physicsid2, &constrainttype,
+ &pivotX, &pivotY, &pivotZ, &axisX, &axisY, &axisZ, &flag))
{
- success = PyArg_ParseTuple(args,"KKii", &physicsid, &physicsid2, &constrainttype, &extrainfo);
- pivotX=extrainfo;
+ return NULL;
}
- if (success)
- {
- if (PHY_GetActiveEnvironment())
- {
-
- PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) physicsid;
- PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2;
- if (physctrl) //TODO:check for existence of this pointer!
- {
- int constraintid =0;
-
- //convert from euler angle into axis
- float radsPerDeg = 6.283185307179586232f / 360.f;
+ if (PHY_GetActiveEnvironment()) {
+ PHY_IPhysicsController *physctrl = (PHY_IPhysicsController*)physicsid;
+ PHY_IPhysicsController *physctrl2 = (PHY_IPhysicsController*)physicsid2;
+ if (physctrl) { //TODO:check for existence of this pointer!
+ //convert from euler angle into axis
+ const float deg2rad = 0.017453292f;
- //we need to pass a full constraint frame, not just axis
- //localConstraintFrameBasis
- MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*axisX,radsPerDeg*axisY,radsPerDeg*axisZ));
- MT_Vector3 axis0 = localCFrame.getColumn(0);
- MT_Vector3 axis1 = localCFrame.getColumn(1);
- MT_Vector3 axis2 = localCFrame.getColumn(2);
+ //we need to pass a full constraint frame, not just axis
+ //localConstraintFrameBasis
+ MT_Matrix3x3 localCFrame(MT_Vector3(deg2rad*axisX, deg2rad*axisY, deg2rad*axisZ));
+ MT_Vector3 axis0 = localCFrame.getColumn(0);
+ MT_Vector3 axis1 = localCFrame.getColumn(1);
+ MT_Vector3 axis2 = localCFrame.getColumn(2);
- constraintid = PHY_GetActiveEnvironment()->CreateConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,
- pivotX,pivotY,pivotZ,
- (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(),flag);
+ int constraintid = PHY_GetActiveEnvironment()->CreateConstraint(
+ physctrl, physctrl2, (enum PHY_ConstraintType)constrainttype, pivotX, pivotY, pivotZ,
+ (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(), flag);
- KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment());
+ KX_ConstraintWrapper *wrap = new KX_ConstraintWrapper(
+ (enum PHY_ConstraintType)constrainttype, constraintid, PHY_GetActiveEnvironment());
- return wrap->NewProxy(true);
- }
-
-
+ return wrap->NewProxy(true);
}
}
- else {
- return NULL;
- }
-
Py_RETURN_NONE;
}
@@ -680,7 +648,7 @@ static struct PyMethodDef physicsconstraints_methods[] = {
{"createConstraint",(PyCFunction) gPyCreateConstraint,
- METH_VARARGS, (const char *)gPyCreateConstraint__doc__},
+ METH_VARARGS|METH_KEYWORDS, (const char *)gPyCreateConstraint__doc__},
{"getVehicleConstraint",(PyCFunction) gPyGetVehicleConstraint,
METH_VARARGS, (const char *)gPyGetVehicleConstraint__doc__},
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index d7dd3fe5253..6fdc53f9c64 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -51,6 +51,8 @@
# include <Python.h>
extern "C" {
+ # include "BLI_utildefines.h"
+ # include "python_utildefines.h"
# include "bpy_internal_import.h" /* from the blender python api, but we want to import text too! */
# include "py_capi_utils.h"
# include "mathutils.h" // 'mathutils' module copied here so the blenderlayer can use.
@@ -354,7 +356,7 @@ static PyObject *gPyLoadGlobalDict(PyObject *)
{
char marshal_path[512];
char *marshal_buffer = NULL;
- size_t marshal_length;
+ int marshal_length;
FILE *fp = NULL;
int result;
@@ -365,7 +367,12 @@ static PyObject *gPyLoadGlobalDict(PyObject *)
if (fp) {
// obtain file size:
fseek (fp, 0, SEEK_END);
- marshal_length = (size_t)ftell(fp);
+ marshal_length = ftell(fp);
+ if (marshal_length == -1) {
+ printf("Warning: could not read position of '%s'\n", marshal_path);
+ fclose(fp);
+ Py_RETURN_NONE;
+ }
rewind(fp);
marshal_buffer = (char*)malloc (sizeof(char)*marshal_length);
@@ -1029,109 +1036,22 @@ static PyObject *gPyGetStereoEye(PyObject *, PyObject *, PyObject *)
static PyObject *gPySetBackgroundColor(PyObject *, PyObject *value)
{
-
MT_Vector4 vec;
if (!PyVecTo(value, vec))
return NULL;
-
- if (gp_Canvas)
- {
- gp_Rasterizer->SetBackColor((float)vec[0], (float)vec[1], (float)vec[2], (float)vec[3]);
- }
KX_WorldInfo *wi = gp_KetsjiScene->GetWorldInfo();
- if (wi->hasWorld())
- wi->setBackColor((float)vec[0], (float)vec[1], (float)vec[2]);
-
- Py_RETURN_NONE;
-}
-
-
-
-static PyObject *gPySetMistColor(PyObject *, PyObject *value)
-{
-
- MT_Vector3 vec;
- if (!PyVecTo(value, vec))
- return NULL;
-
- if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistColor(color), Rasterizer not available");
+ if (!wi->hasWorld()) {
+ PyErr_SetString(PyExc_RuntimeError, "bge.render.SetBackgroundColor(color), World not available");
return NULL;
}
- gp_Rasterizer->SetFogColor((float)vec[0], (float)vec[1], (float)vec[2]);
-
- Py_RETURN_NONE;
-}
-
-static PyObject *gPyDisableMist(PyObject *)
-{
-
- if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistColor(color), Rasterizer not available");
- return NULL;
- }
- gp_Rasterizer->DisableFog();
-
- Py_RETURN_NONE;
-}
-static PyObject *gPySetMistStart(PyObject *, PyObject *args)
-{
+ ShowDeprecationWarning("setBackgroundColor()", "KX_WorldInfo.background_color");
+ wi->setBackColor((float)vec[0], (float)vec[1], (float)vec[2]);
- float miststart;
- if (!PyArg_ParseTuple(args,"f:setMistStart",&miststart))
- return NULL;
-
- if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistStart(float), Rasterizer not available");
- return NULL;
- }
-
- gp_Rasterizer->SetFogStart(miststart);
-
Py_RETURN_NONE;
}
-
-
-static PyObject *gPySetMistEnd(PyObject *, PyObject *args)
-{
-
- float mistend;
- if (!PyArg_ParseTuple(args,"f:setMistEnd",&mistend))
- return NULL;
-
- if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistEnd(float), Rasterizer not available");
- return NULL;
- }
-
- gp_Rasterizer->SetFogEnd(mistend);
-
- Py_RETURN_NONE;
-}
-
-
-static PyObject *gPySetAmbientColor(PyObject *, PyObject *value)
-{
-
- MT_Vector3 vec;
- if (!PyVecTo(value, vec))
- return NULL;
-
- if (!gp_Rasterizer) {
- PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setAmbientColor(color), Rasterizer not available");
- return NULL;
- }
- gp_Rasterizer->SetAmbientColor((float)vec[0], (float)vec[1], (float)vec[2]);
-
- Py_RETURN_NONE;
-}
-
-
-
-
static PyObject *gPyMakeScreenshot(PyObject *, PyObject *args)
{
char* filename;
@@ -1490,6 +1410,21 @@ static PyObject *gPyClearDebugList(PyObject *)
Py_RETURN_NONE;
}
+static PyObject *gPyGetDisplayDimensions(PyObject *)
+{
+ PyObject *result;
+ int width, height;
+
+ gp_Canvas->GetDisplayDimensions(width, height);
+
+ result = PyTuple_New(2);
+ PyTuple_SET_ITEMS(result,
+ PyLong_FromLong(width),
+ PyLong_FromLong(height));
+
+ return result;
+}
+
PyDoc_STRVAR(Rasterizer_module_documentation,
"This is the Python API for the game engine of Rasterizer"
);
@@ -1508,11 +1443,6 @@ static struct PyMethodDef rasterizer_methods[] = {
{"setMousePosition",(PyCFunction) gPySetMousePosition,
METH_VARARGS, "setMousePosition(int x,int y)"},
{"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_O,"set Background Color (rgb)"},
- {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_O,"set Ambient Color (rgb)"},
- {"disableMist",(PyCFunction)gPyDisableMist,METH_NOARGS,"turn off mist"},
- {"setMistColor",(PyCFunction)gPySetMistColor,METH_O,"set Mist Color (rgb)"},
- {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
- {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
{"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"},
{"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_NOARGS,"disable motion blur"},
@@ -1538,6 +1468,8 @@ static struct PyMethodDef rasterizer_methods[] = {
{"setWindowSize", (PyCFunction) gPySetWindowSize, METH_VARARGS, ""},
{"setFullScreen", (PyCFunction) gPySetFullScreen, METH_O, ""},
{"getFullScreen", (PyCFunction) gPyGetFullScreen, METH_NOARGS, ""},
+ {"getDisplayDimensions", (PyCFunction) gPyGetDisplayDimensions, METH_NOARGS,
+ "Get the actual dimensions, in pixels, of the physical display (e.g., the monitor)."},
{"setMipmapping", (PyCFunction) gPySetMipmapping, METH_VARARGS, ""},
{"getMipmapping", (PyCFunction) gPyGetMipmapping, METH_NOARGS, ""},
{"setVsync", (PyCFunction) gPySetVsync, METH_VARARGS, ""},
@@ -2149,14 +2081,14 @@ PyObject *initGamePlayerPythonScripting(Main *maggie, int argc, char** argv)
Py_SetProgramName(program_path_wchar);
/* Update, Py3.3 resolves attempting to parse non-existing header */
- #if 0
+#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; /* inhibits the automatic importing of 'site' */
}
- #endif
+#endif
Py_FrozenFlag = 1;
diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
index 828fd62f205..b3511e4e61a 100644
--- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
@@ -40,6 +40,7 @@
#include "BL_ArmatureConstraint.h"
#include "BL_ArmatureObject.h"
#include "BL_ArmatureChannel.h"
+#include "KX_WorldInfo.h"
#include "KX_ArmatureSensor.h"
#include "KX_BlenderMaterial.h"
#include "KX_CameraActuator.h"
@@ -231,6 +232,7 @@ PyMODINIT_FUNC initGameTypesPythonBinding(void)
PyType_Ready_Attr(dict, KX_SCA_EndObjectActuator, init_getset);
PyType_Ready_Attr(dict, KX_SCA_ReplaceMeshActuator, init_getset);
PyType_Ready_Attr(dict, KX_Scene, init_getset);
+ PyType_Ready_Attr(dict, KX_WorldInfo, init_getset);
PyType_Ready_Attr(dict, KX_NavMeshObject, init_getset);
PyType_Ready_Attr(dict, KX_SceneActuator, init_getset);
PyType_Ready_Attr(dict, KX_SoundActuator, init_getset);
@@ -279,6 +281,7 @@ PyMODINIT_FUNC initGameTypesPythonBinding(void)
/* Init mathutils callbacks */
KX_GameObject_Mathutils_Callback_Init();
KX_ObjectActuator_Mathutils_Callback_Init();
+ KX_WorldInfo_Mathutils_Callback_Init();
#endif
return m;
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 97ebd6d40a9..25755f7127b 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -43,6 +43,7 @@
#include "KX_FontObject.h"
#include "RAS_IPolygonMaterial.h"
#include "ListValue.h"
+#include "KX_PythonCallBack.h"
#include "SCA_LogicManager.h"
#include "SCA_TimeEventManager.h"
//#include "SCA_AlwaysEventManager.h"
@@ -156,7 +157,9 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_networkDeviceInterface(ndi),
m_active_camera(NULL),
m_ueberExecutionPriority(0),
- m_blenderScene(scene)
+ m_blenderScene(scene),
+ m_isActivedHysteresis(false),
+ m_lodHysteresisValue(0)
{
m_suspendedtime = 0.0;
m_suspendeddelta = 0.0;
@@ -235,6 +238,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_attr_dict = NULL;
m_draw_call_pre = NULL;
m_draw_call_post = NULL;
+ m_draw_setup_call_pre = NULL;
#endif
}
@@ -532,6 +536,8 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
m_objectlist->Add(newobj->AddRef());
if (newobj->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
m_lightlist->Add(newobj->AddRef());
+ else if (newobj->GetGameObjectType()==SCA_IObject::OBJ_TEXT)
+ AddFont((KX_FontObject*)newobj);
newobj->AddMeshUser();
// logic cannot be replicated, until the whole hierarchy is replicated.
@@ -803,13 +809,6 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
// we can now add the graphic controller to the physic engine
replica->ActivateGraphicController(true);
- // set references for dupli-group
- // groupobj holds a list of all objects, that belongs to this group
- groupobj->AddInstanceObjects(replica);
-
- // every object gets the reference to its dupli-group object
- replica->SetDupliGroupObject(groupobj);
-
// done with replica
replica->Release();
}
@@ -817,38 +816,38 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
// the logic must be replicated first because we need
// the new logic bricks before relinking
vector<KX_GameObject*>::iterator git;
- for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
- {
- (*git)->ReParentLogic();
- }
-
- // relink any pointers as necessary, sort of a temporary solution
- for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
- {
+ for (git = m_logicHierarchicalGameObjects.begin(); git != m_logicHierarchicalGameObjects.end(); ++git) {
+ KX_GameObject *gameobj = *git;
+
+ if (gameobj->GetBlenderGroupObject() == blgroupobj) {
+ // set references for dupli-group
+ // groupobj holds a list of all objects, that belongs to this group
+ groupobj->AddInstanceObjects(gameobj);
+ // every object gets the reference to its dupli-group object
+ gameobj->SetDupliGroupObject(groupobj);
+ }
+
+ gameobj->ReParentLogic();
+
+ // relink any pointers as necessary, sort of a temporary solution
// this will also relink the actuator to objects within the hierarchy
- (*git)->Relink(&m_map_gameobject_to_replica);
+ gameobj->Relink(&m_map_gameobject_to_replica);
// add the object in the layer of the parent
- (*git)->SetLayer(groupobj->GetLayer());
- // If the object was a light, we need to update it's RAS_LightObject as well
- if ((*git)->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
- {
- KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
- lightobj->SetLayer(groupobj->GetLayer());
- }
- }
+ gameobj->SetLayer(groupobj->GetLayer());
- // replicate crosslinks etc. between logic bricks
- for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
- {
- ReplicateLogic((*git));
- }
+ // replicate crosslinks etc. between logic bricks
+ ReplicateLogic(gameobj);
- // now look if object in the hierarchy have dupli group and recurse
- for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
- {
- if ((*git) != groupobj && (*git)->IsDupliGroup())
+ // now look if object in the hierarchy have dupli group and recurse
+ /* Replicate all constraints. */
+ if (gameobj->GetPhysicsController()) {
+ gameobj->GetPhysicsController()->ReplicateConstraints(gameobj, m_logicHierarchicalGameObjects);
+ gameobj->ClearConstraints();
+ }
+
+ if (gameobj != groupobj && gameobj->IsDupliGroup())
// can't instantiate group immediately as it destroys m_logicHierarchicalGameObjects
- duplilist.push_back((*git));
+ duplilist.push_back(gameobj);
}
for (git = duplilist.begin(); !(git == duplilist.end()); ++git)
@@ -859,7 +858,7 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
- class CValue* parentobject,
+ class CValue* referenceobject,
int lifespan)
{
@@ -868,7 +867,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
m_groupGameObjects.clear();
KX_GameObject* originalobj = (KX_GameObject*) originalobject;
- KX_GameObject* parentobj = (KX_GameObject*) parentobject;
+ KX_GameObject* referenceobj = (KX_GameObject*) referenceobject;
m_ueberExecutionPriority++;
@@ -904,18 +903,20 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
replica->GetSGNode()->AddChild(childreplicanode);
}
- // At this stage all the objects in the hierarchy have been duplicated,
- // we can update the scenegraph, we need it for the duplication of logic
- MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition();
- replica->NodeSetLocalPosition(newpos);
+ if (referenceobj) {
+ // At this stage all the objects in the hierarchy have been duplicated,
+ // we can update the scenegraph, we need it for the duplication of logic
+ MT_Point3 newpos = referenceobj->NodeGetWorldPosition();
+ replica->NodeSetLocalPosition(newpos);
- MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation();
- replica->NodeSetLocalOrientation(newori);
-
- // 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);
+ MT_Matrix3x3 newori = referenceobj->NodeGetWorldOrientation();
+ replica->NodeSetLocalOrientation(newori);
+
+ // get the rootnode's scale
+ MT_Vector3 newscale = referenceobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
+ // set the replica's relative scale with the rootnode's scale
+ replica->NodeSetRelativeScale(newscale);
+ }
replica->GetSGNode()->UpdateWorldData(0);
replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
@@ -935,13 +936,13 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
{
// this will also relink the actuators in the hierarchy
(*git)->Relink(&m_map_gameobject_to_replica);
- // add the object in the layer of the parent
- (*git)->SetLayer(parentobj->GetLayer());
- // If the object was a light, we need to update it's RAS_LightObject as well
- if ((*git)->GetGameObjectType()==SCA_IObject::OBJ_LIGHT)
- {
- KX_LightObject* lightobj = static_cast<KX_LightObject*>(*git);
- lightobj->SetLayer(parentobj->GetLayer());
+ if (referenceobj) {
+ // add the object in the layer of the reference object
+ (*git)->SetLayer(referenceobj->GetLayer());
+ }
+ else {
+ // We don't know what layer set, so we set all visible layers in the blender scene.
+ (*git)->SetLayer(m_blenderScene->lay);
}
}
@@ -1755,6 +1756,26 @@ void KX_Scene::UpdateObjectLods(void)
}
}
+void KX_Scene::SetLodHysteresis(bool active)
+{
+ m_isActivedHysteresis = active;
+}
+
+bool KX_Scene::IsActivedLodHysteresis(void)
+{
+ return m_isActivedHysteresis;
+}
+
+void KX_Scene::SetLodHysteresisValue(int hysteresisvalue)
+{
+ m_lodHysteresisValue = hysteresisvalue;
+}
+
+int KX_Scene::GetLodHysteresisValue(void)
+{
+ return m_lodHysteresisValue;
+}
+
void KX_Scene::UpdateObjectActivity(void)
{
if (m_activity_culling) {
@@ -1871,15 +1892,6 @@ static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *from, KX_Sce
brick->Replace_IScene(to);
brick->Replace_NetworkScene(to->GetNetworkScene());
- /* near sensors have physics controllers */
- KX_TouchSensor *touch_sensor = dynamic_cast<class KX_TouchSensor *>(brick);
- if (touch_sensor) {
- KX_TouchEventManager *tmgr = (KX_TouchEventManager*)from->GetLogicManager()->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
- touch_sensor->UnregisterSumo(tmgr);
- touch_sensor->GetPhysicsController()->SetPhysicsEnvironment(to->GetPhysicsEnvironment());
- touch_sensor->RegisterSumo(tmgr);
- }
-
// If we end up replacing a KX_TouchEventManager, we need to make sure
// physics controllers are properly in place. In other words, do this
// after merging physics controllers!
@@ -1938,17 +1950,6 @@ static void MergeScene_GameObject(KX_GameObject* gameobj, KX_Scene *to, KX_Scene
{
SCA_IController *cont= *itc;
MergeScene_LogicBrick(cont, from, to);
-
- vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors();
- vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators();
-
- for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());++ita) {
- MergeScene_LogicBrick(*ita, from, to);
- }
-
- for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());++its) {
- MergeScene_LogicBrick(*its, from, to);
- }
}
}
@@ -2102,30 +2103,10 @@ void KX_Scene::Render2DFilters(RAS_ICanvas* canvas)
void KX_Scene::RunDrawingCallbacks(PyObject *cb_list)
{
- Py_ssize_t len;
-
- if (cb_list && (len=PyList_GET_SIZE(cb_list)))
- {
- PyObject *args = PyTuple_New(0); // save python creating each call
- PyObject *func;
- PyObject *ret;
-
- // Iterate the list and run the callbacks
- for (Py_ssize_t pos=0; pos < len; pos++)
- {
- func= PyList_GET_ITEM(cb_list, pos);
- ret= PyObject_Call(func, args, NULL);
- if (ret==NULL) {
- PyErr_Print();
- PyErr_Clear();
- }
- else {
- Py_DECREF(ret);
- }
- }
+ if (!cb_list || PyList_GET_SIZE(cb_list) == 0)
+ return;
- Py_DECREF(args);
- }
+ RunPythonCallBackList(cb_list, NULL, 0, 0);
}
//----------------------------------------------------------------------------
@@ -2311,6 +2292,19 @@ PyObject *KX_Scene::pyattr_get_lights(void *self_v, const KX_PYATTRIBUTE_DEF *at
return self->GetLightList()->GetProxy();
}
+PyObject *KX_Scene::pyattr_get_world(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self = static_cast<KX_Scene*>(self_v);
+ KX_WorldInfo *world = self->GetWorldInfo();
+
+ if (world->GetName() != "") {
+ return world->GetProxy();
+ }
+ else {
+ Py_RETURN_NONE;
+ }
+}
+
PyObject *KX_Scene::pyattr_get_cameras(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
/* With refcounts in this case...
@@ -2375,6 +2369,17 @@ PyObject *KX_Scene::pyattr_get_drawing_callback_post(void *self_v, const KX_PYAT
return self->m_draw_call_post;
}
+PyObject *KX_Scene::pyattr_get_drawing_setup_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self = static_cast<KX_Scene*>(self_v);
+
+ if (self->m_draw_setup_call_pre == NULL)
+ self->m_draw_setup_call_pre = PyList_New(0);
+
+ Py_INCREF(self->m_draw_setup_call_pre);
+ return self->m_draw_setup_call_pre;
+}
+
int KX_Scene::pyattr_set_drawing_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_Scene* self = static_cast<KX_Scene*>(self_v);
@@ -2409,6 +2414,22 @@ int KX_Scene::pyattr_set_drawing_callback_post(void *self_v, const KX_PYATTRIBUT
return PY_SET_ATTR_SUCCESS;
}
+int KX_Scene::pyattr_set_drawing_setup_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Scene* self = static_cast<KX_Scene*>(self_v);
+
+ if (!PyList_CheckExact(value)) {
+ PyErr_SetString(PyExc_ValueError, "Expected a list");
+ return PY_SET_ATTR_FAIL;
+ }
+
+ Py_XDECREF(self->m_draw_setup_call_pre);
+ Py_INCREF(value);
+
+ self->m_draw_setup_call_pre = value;
+ return PY_SET_ATTR_SUCCESS;
+}
+
PyObject *KX_Scene::pyattr_get_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_Scene* self = static_cast<KX_Scene*>(self_v);
@@ -2434,9 +2455,11 @@ PyAttributeDef KX_Scene::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("objectsInactive", KX_Scene, pyattr_get_objects_inactive),
KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights),
KX_PYATTRIBUTE_RO_FUNCTION("cameras", KX_Scene, pyattr_get_cameras),
+ KX_PYATTRIBUTE_RO_FUNCTION("world", KX_Scene, pyattr_get_world),
KX_PYATTRIBUTE_RW_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera, pyattr_set_active_camera),
KX_PYATTRIBUTE_RW_FUNCTION("pre_draw", KX_Scene, pyattr_get_drawing_callback_pre, pyattr_set_drawing_callback_pre),
KX_PYATTRIBUTE_RW_FUNCTION("post_draw", KX_Scene, pyattr_get_drawing_callback_post, pyattr_set_drawing_callback_post),
+ KX_PYATTRIBUTE_RW_FUNCTION("pre_draw_setup", KX_Scene, pyattr_get_drawing_setup_callback_pre, pyattr_set_drawing_setup_callback_pre),
KX_PYATTRIBUTE_RW_FUNCTION("gravity", KX_Scene, pyattr_get_gravity, pyattr_set_gravity),
KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend),
KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling),
@@ -2449,23 +2472,23 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject,
"addObject(object, other, time=0)\n"
"Returns the added object.\n")
{
- PyObject *pyob, *pyother;
- KX_GameObject *ob, *other;
+ PyObject *pyob, *pyreference = Py_None;
+ KX_GameObject *ob, *reference;
int time = 0;
- if (!PyArg_ParseTuple(args, "OO|i:addObject", &pyob, &pyother, &time))
+ if (!PyArg_ParseTuple(args, "O|Oi:addObject", &pyob, &pyreference, &time))
return NULL;
- if ( !ConvertPythonToGameObject(pyob, &ob, false, "scene.addObject(object, other, time): KX_Scene (first argument)") ||
- !ConvertPythonToGameObject(pyother, &other, false, "scene.addObject(object, other, time): KX_Scene (second argument)") )
+ if (!ConvertPythonToGameObject(pyob, &ob, false, "scene.addObject(object, reference, time): KX_Scene (first argument)") ||
+ !ConvertPythonToGameObject(pyreference, &reference, true, "scene.addObject(object, reference, time): KX_Scene (second argument)"))
return NULL;
if (!m_inactivelist->SearchValue(ob)) {
- PyErr_Format(PyExc_ValueError, "scene.addObject(object, other, time): KX_Scene (first argument): object must be in an inactive layer");
+ PyErr_Format(PyExc_ValueError, "scene.addObject(object, reference, time): KX_Scene (first argument): object must be in an inactive layer");
return NULL;
}
- SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time);
+ SCA_IObject *replica = AddReplicaObject((SCA_IObject*)ob, reference, time);
// release here because AddReplicaObject AddRef's
// the object is added to the scene so we don't want python to own a reference
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 2e1ee9f101d..a5645ea6448 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -107,6 +107,7 @@ class KX_Scene : public PyObjectPlus, public SCA_IScene
PyObject* m_attr_dict;
PyObject* m_draw_call_pre;
PyObject* m_draw_call_post;
+ PyObject* m_draw_setup_call_pre;
#endif
struct CullingInfo {
@@ -295,6 +296,12 @@ protected:
KX_ObstacleSimulation* m_obstacleSimulation;
+ /**
+ * LOD Hysteresis settings
+ */
+ bool m_isActivedHysteresis;
+ int m_lodHysteresisValue;
+
public:
KX_Scene(class SCA_IInputDevice* keyboarddevice,
class SCA_IInputDevice* mousedevice,
@@ -546,6 +553,12 @@ public:
// Update the mesh for objects based on level of detail settings
void UpdateObjectLods(void);
+
+ // LoD Hysteresis functions
+ void SetLodHysteresis(bool active);
+ bool IsActivedLodHysteresis();
+ void SetLodHysteresisValue(int hysteresisvalue);
+ int GetLodHysteresisValue();
// Update the activity box settings for objects in this scene, if needed.
void UpdateObjectActivity(void);
@@ -612,12 +625,15 @@ public:
static PyObject* pyattr_get_objects_inactive(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_lights(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_cameras(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject* pyattr_get_world(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static PyObject* pyattr_get_active_camera(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_drawing_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_drawing_callback_pre(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_drawing_callback_post(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_drawing_callback_post(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject* pyattr_get_drawing_setup_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_drawing_setup_callback_pre(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
static PyObject* pyattr_get_gravity(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
@@ -634,6 +650,7 @@ public:
PyObject *GetPreDrawCB() { return m_draw_call_pre; }
PyObject *GetPostDrawCB() { return m_draw_call_post; }
+ PyObject *GetPreDrawSetupCB() { return m_draw_setup_call_pre; }
#endif
/**
diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.cpp b/source/gameengine/Ketsji/KX_SteeringActuator.cpp
index 10d4273a2b4..83597f9125a 100644
--- a/source/gameengine/Ketsji/KX_SteeringActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SteeringActuator.cpp
@@ -263,12 +263,12 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
if (apply_steerforce)
{
- MT_Vector3 newvel;
bool isdyna = obj->IsDynamic();
if (isdyna)
m_steerVec.z() = 0;
if (!m_steerVec.fuzzyZero())
m_steerVec.normalize();
+ MT_Vector3 newvel = m_velocity * m_steerVec;
//adjust velocity to avoid obstacles
if (m_simulation && m_obstacle /*&& !newvel.fuzzyZero()*/)
@@ -284,13 +284,10 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
HandleActorFace(newvel);
if (isdyna)
{
- //TODO: Take into account angular velocity on turns
+ //temporary solution: set 2D steering velocity directly to obj
+ //correct way is to apply physical force
MT_Vector3 curvel = obj->GetLinearVelocity();
- newvel = (curvel.length() * m_steerVec) + (m_acceleration * delta) * m_steerVec;
- if (newvel.length2() >= (m_velocity * m_velocity))
- newvel = m_velocity * m_steerVec;
-
if (m_lockzvel)
newvel.z() = 0.0f;
else
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index d10e51a491a..b42200783e4 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -54,19 +54,20 @@ KX_VehicleWrapper::~KX_VehicleWrapper()
#ifdef WITH_PYTHON
-static bool raise_exc_wheel(PHY_IVehicle* vehicle, int i, const char *method)
+static bool raise_exc_wheel(PHY_IVehicle *vehicle, int i, const char *method)
{
- if ( i < 0 || i >= vehicle->GetNumWheels() ) {
+ if (i < 0 || i >= vehicle->GetNumWheels()) {
PyErr_Format(PyExc_ValueError,
- "%s(...): wheel index %d out of range (0 to %d).", method, i, vehicle->GetNumWheels()-1);
- return -1;
- } else {
- return 0;
+ "%s(...): wheel index %d out of range (0 to %d).", method, i, vehicle->GetNumWheels() - 1);
+ return true;
+ }
+ else {
+ return false;
}
}
#define WHEEL_INDEX_CHECK_OR_RETURN(i, method) \
- if (raise_exc_wheel(m_vehicle, i, method) == -1) { return NULL; } (void)0
+ if (raise_exc_wheel(m_vehicle, i, method)) {return NULL;} (void)0
PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args)
@@ -86,8 +87,6 @@ PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args)
if (gameOb->GetSGNode())
{
- PHY_IMotionState* motionState = new KX_MotionState(gameOb->GetSGNode());
-
MT_Vector3 attachPos,attachDir,attachAxle;
if(!PyVecTo(pylistPos,attachPos)) {
PyErr_SetString(PyExc_AttributeError,
@@ -114,6 +113,7 @@ PyObject *KX_VehicleWrapper::PyAddWheel(PyObject *args)
return NULL;
}
+ PHY_IMotionState *motionState = new KX_MotionState(gameOb->GetSGNode());
m_vehicle->AddWheel(motionState,attachPos,attachDir,attachAxle,suspensionRestLength,wheelRadius,hasSteering);
}
diff --git a/source/gameengine/Ketsji/KX_WorldInfo.cpp b/source/gameengine/Ketsji/KX_WorldInfo.cpp
index 444d6b0771b..8678b058761 100644
--- a/source/gameengine/Ketsji/KX_WorldInfo.cpp
+++ b/source/gameengine/Ketsji/KX_WorldInfo.cpp
@@ -31,8 +31,464 @@
#include "KX_WorldInfo.h"
+#include "KX_PythonInit.h"
+#include "KX_PyMath.h"
+#include "RAS_IRasterizer.h"
+#include "GPU_material.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+/* This list includes only data type definitions */
+#include "DNA_scene_types.h"
+#include "DNA_world_types.h"
+
+#include "BLI_math.h"
+
+#include "BKE_global.h"
+#include "BKE_scene.h"
+/* end of blender include block */
+
+
+KX_WorldInfo::KX_WorldInfo(Scene *blenderscene, World *blenderworld)
+{
+ if (blenderworld) {
+ m_name = blenderworld->id.name + 2;
+ m_do_color_management = BKE_scene_check_color_management_enabled(blenderscene);
+ m_hasworld = true;
+ m_hasmist = ((blenderworld->mode) & WO_MIST ? true : false);
+ m_misttype = blenderworld->mistype;
+ m_miststart = blenderworld->miststa;
+ m_mistdistance = blenderworld->mistdist;
+ m_mistintensity = blenderworld->misi;
+ setMistColor(blenderworld->horr, blenderworld->horg, blenderworld->horb);
+ setBackColor(blenderworld->horr, blenderworld->horg, blenderworld->horb);
+ setAmbientColor(blenderworld->ambr, blenderworld->ambg, blenderworld->ambb);
+ }
+ else {
+ m_hasworld = false;
+ }
+}
KX_WorldInfo::~KX_WorldInfo()
{
}
+const STR_String& KX_WorldInfo::GetName()
+{
+ return m_name;
+}
+
+bool KX_WorldInfo::hasWorld()
+{
+ return m_hasworld;
+}
+
+void KX_WorldInfo::setBackColor(float r, float g, float b)
+{
+ m_backgroundcolor[0] = r;
+ m_backgroundcolor[1] = g;
+ m_backgroundcolor[2] = b;
+
+ if (m_do_color_management) {
+ linearrgb_to_srgb_v3_v3(m_con_backgroundcolor, m_backgroundcolor);
+ }
+ else {
+ copy_v3_v3(m_con_backgroundcolor, m_backgroundcolor);
+ }
+}
+
+const float *KX_WorldInfo::getBackColor(void) const
+{
+ return m_backgroundcolor;
+}
+
+void KX_WorldInfo::setMistType(short type)
+{
+ m_misttype = type;
+}
+
+void KX_WorldInfo::setUseMist(bool enable)
+{
+ m_hasmist = enable;
+}
+
+void KX_WorldInfo::setMistStart(float d)
+{
+ m_miststart = d;
+}
+
+void KX_WorldInfo::setMistDistance(float d)
+{
+ m_mistdistance = d;
+}
+
+void KX_WorldInfo::setMistIntensity(float intensity)
+{
+ m_mistintensity = intensity;
+}
+void KX_WorldInfo::setMistColor(float r, float g, float b)
+{
+ m_mistcolor[0] = r;
+ m_mistcolor[1] = g;
+ m_mistcolor[2] = b;
+
+ if (m_do_color_management) {
+ linearrgb_to_srgb_v3_v3(m_con_mistcolor, m_mistcolor);
+ }
+ else {
+ copy_v3_v3(m_con_mistcolor, m_mistcolor);
+ }
+}
+
+void KX_WorldInfo::setAmbientColor(float r, float g, float b)
+{
+ m_ambientcolor[0] = r;
+ m_ambientcolor[1] = g;
+ m_ambientcolor[2] = b;
+
+ if (m_do_color_management) {
+ linearrgb_to_srgb_v3_v3(m_con_ambientcolor, m_ambientcolor);
+ }
+ else {
+ copy_v3_v3(m_con_ambientcolor, m_ambientcolor);
+ }
+}
+
+void KX_WorldInfo::UpdateBackGround()
+{
+ if (m_hasworld) {
+ RAS_IRasterizer *m_rasterizer = KX_GetActiveEngine()->GetRasterizer();
+
+ if (m_rasterizer->GetDrawingMode() >= RAS_IRasterizer::KX_SOLID) {
+ m_rasterizer->SetBackColor(m_con_backgroundcolor);
+ GPU_horizon_update_color(m_backgroundcolor);
+ }
+ }
+}
+
+void KX_WorldInfo::UpdateWorldSettings()
+{
+ if (m_hasworld) {
+ RAS_IRasterizer *m_rasterizer = KX_GetActiveEngine()->GetRasterizer();
+
+ if (m_rasterizer->GetDrawingMode() >= RAS_IRasterizer::KX_SOLID) {
+ m_rasterizer->SetAmbientColor(m_con_ambientcolor);
+ GPU_ambient_update_color(m_ambientcolor);
+
+ if (m_hasmist) {
+ m_rasterizer->SetFog(m_misttype, m_miststart, m_mistdistance, m_mistintensity, m_con_mistcolor);
+ GPU_mist_update_values(m_misttype, m_miststart, m_mistdistance, m_mistintensity, m_mistcolor);
+ m_rasterizer->EnableFog(true);
+ GPU_mist_update_enable(true);
+ }
+ else {
+ m_rasterizer->EnableFog(false);
+ GPU_mist_update_enable(false);
+ }
+ }
+ }
+}
+
+#ifdef WITH_PYTHON
+
+/* -------------------------------------------------------------------------
+ * Python functions
+ * ------------------------------------------------------------------------- */
+PyObject *KX_WorldInfo::py_repr(void)
+{
+ return PyUnicode_From_STR_String(GetName());
+}
+
+/* -------------------------------------------------------------------------
+ * Python Integration Hooks
+ * ------------------------------------------------------------------------- */
+PyTypeObject KX_WorldInfo::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "KX_WorldInfo",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,0,0,0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ 0,0,0,0,0,0,0,
+ Methods,
+ 0,
+ 0,
+ &PyObjectPlus::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyMethodDef KX_WorldInfo::Methods[] = {
+ {NULL,NULL} /* Sentinel */
+};
+
+PyAttributeDef KX_WorldInfo::Attributes[] = {
+ KX_PYATTRIBUTE_BOOL_RW("mistEnable", KX_WorldInfo, m_hasmist),
+ KX_PYATTRIBUTE_FLOAT_RW("mistStart", 0.0f, 10000.0f, KX_WorldInfo, m_miststart),
+ KX_PYATTRIBUTE_FLOAT_RW("mistDistance", 0.001f, 10000.0f, KX_WorldInfo, m_mistdistance),
+ KX_PYATTRIBUTE_FLOAT_RW("mistIntensity", 0.0f, 1.0f, KX_WorldInfo, m_mistintensity),
+ KX_PYATTRIBUTE_SHORT_RW("mistType", 0, 2, true, KX_WorldInfo, m_misttype),
+ KX_PYATTRIBUTE_RO_FUNCTION("KX_MIST_QUADRATIC", KX_WorldInfo, pyattr_get_mist_typeconst),
+ KX_PYATTRIBUTE_RO_FUNCTION("KX_MIST_LINEAR", KX_WorldInfo, pyattr_get_mist_typeconst),
+ KX_PYATTRIBUTE_RO_FUNCTION("KX_MIST_INV_QUADRATIC", KX_WorldInfo, pyattr_get_mist_typeconst),
+ KX_PYATTRIBUTE_RW_FUNCTION("mistColor", KX_WorldInfo, pyattr_get_mist_color, pyattr_set_mist_color),
+ KX_PYATTRIBUTE_RW_FUNCTION("backgroundColor", KX_WorldInfo, pyattr_get_back_color, pyattr_set_back_color),
+ KX_PYATTRIBUTE_RW_FUNCTION("ambientColor", KX_WorldInfo, pyattr_get_ambient_color, pyattr_set_ambient_color),
+ { NULL } /* Sentinel */
+};
+
+/* Attribute get/set functions */
+
+#ifdef USE_MATHUTILS
+
+/*----------------------mathutils callbacks ----------------------------*/
+
+/* subtype */
+#define MATHUTILS_VEC_CB_MIST_COLOR 1
+#define MATHUTILS_VEC_CB_BACK_COLOR 2
+#define MATHUTILS_VEC_CB_AMBIENT_COLOR 3
+
+static unsigned char mathutils_world_vector_cb_index = -1; /* index for our callbacks */
+
+static int mathutils_world_generic_check(BaseMathObject *bmo)
+{
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
+ if (self == NULL)
+ return -1;
+
+ return 0;
+}
+
+static int mathutils_world_vector_get(BaseMathObject *bmo, int subtype)
+{
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
+ if (self == NULL)
+ return -1;
+
+ switch (subtype) {
+ case MATHUTILS_VEC_CB_MIST_COLOR:
+ copy_v3_v3(bmo->data, self->m_mistcolor);
+ break;
+ case MATHUTILS_VEC_CB_BACK_COLOR:
+ copy_v3_v3(bmo->data, self->m_backgroundcolor);
+ break;
+ case MATHUTILS_VEC_CB_AMBIENT_COLOR:
+ copy_v3_v3(bmo->data, self->m_ambientcolor);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int mathutils_world_vector_set(BaseMathObject *bmo, int subtype)
+{
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
+
+ if (self == NULL)
+ return -1;
+
+ switch (subtype) {
+ case MATHUTILS_VEC_CB_MIST_COLOR:
+ self->setMistColor(bmo->data[0], bmo->data[1], bmo->data[2]);
+ break;
+ case MATHUTILS_VEC_CB_BACK_COLOR:
+ self->setBackColor(bmo->data[0], bmo->data[1], bmo->data[2]);
+ break;
+ case MATHUTILS_VEC_CB_AMBIENT_COLOR:
+ self->setAmbientColor(bmo->data[0], bmo->data[1], bmo->data[2]);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int mathutils_world_vector_get_index(BaseMathObject *bmo, int subtype, int index)
+{
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
+
+ if (self == NULL)
+ return -1;
+
+ switch (subtype) {
+ case MATHUTILS_VEC_CB_MIST_COLOR:
+ {
+ const float *color = self->m_mistcolor;
+ bmo->data[index] = color[index];
+ }
+ break;
+ case MATHUTILS_VEC_CB_BACK_COLOR:
+ {
+ const float *color = self->m_backgroundcolor;
+ bmo->data[index] = color[index];
+ }
+ break;
+ case MATHUTILS_VEC_CB_AMBIENT_COLOR:
+ {
+ const float *color = self->m_ambientcolor;
+ bmo->data[index] = color[index];
+ }
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int mathutils_world_vector_set_index(BaseMathObject *bmo, int subtype, int index)
+{
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>BGE_PROXY_REF(bmo->cb_user);
+
+ if (self == NULL)
+ return -1;
+
+ float color[4];
+ switch (subtype) {
+ case MATHUTILS_VEC_CB_MIST_COLOR:
+ copy_v3_v3(color, self->m_mistcolor);
+ color[index] = bmo->data[index];
+ self->setMistColor(color[0], color[1], color[2]);
+ break;
+ case MATHUTILS_VEC_CB_BACK_COLOR:
+ copy_v3_v3(color, self->m_backgroundcolor);
+ color[index] = bmo->data[index];
+ self->setBackColor(color[0], color[1], color[2]);
+ break;
+ case MATHUTILS_VEC_CB_AMBIENT_COLOR:
+ copy_v3_v3(color, self->m_ambientcolor);
+ color[index] = bmo->data[index];
+ self->setAmbientColor(color[0], color[1], color[2]);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static Mathutils_Callback mathutils_world_vector_cb = {
+ mathutils_world_generic_check,
+ mathutils_world_vector_get,
+ mathutils_world_vector_set,
+ mathutils_world_vector_get_index,
+ mathutils_world_vector_set_index
+};
+
+void KX_WorldInfo_Mathutils_Callback_Init()
+{
+ // register mathutils callbacks, ok to run more than once.
+ mathutils_world_vector_cb_index = Mathutils_RegisterCallback(&mathutils_world_vector_cb);
+}
+#endif // USE_MATHUTILS
+
+
+PyObject *KX_WorldInfo::pyattr_get_mist_typeconst(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ PyObject *retvalue;
+
+ const char* type = attrdef->m_name;
+
+ if (!strcmp(type, "KX_MIST_QUADRATIC")) {
+ retvalue = PyLong_FromLong(KX_MIST_QUADRATIC);
+ }
+ else if (!strcmp(type, "KX_MIST_LINEAR")) {
+ retvalue = PyLong_FromLong(KX_MIST_LINEAR);
+ }
+ else if (!strcmp(type, "KX_MIST_INV_QUADRATIC")) {
+ retvalue = PyLong_FromLong(KX_MIST_INV_QUADRATIC);
+ }
+ else {
+ /* should never happen */
+ PyErr_SetString(PyExc_TypeError, "invalid mist type");
+ retvalue = NULL;
+ }
+
+ return retvalue;
+}
+
+PyObject *KX_WorldInfo::pyattr_get_mist_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+#ifdef USE_MATHUTILS
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_MIST_COLOR);
+#else
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
+ return PyObjectFrom(MT_Vector3(self->m_mistcolor));
+#endif
+}
+
+int KX_WorldInfo::pyattr_set_mist_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
+
+ MT_Vector3 color;
+ if (PyVecTo(value, color))
+ {
+ self->setMistColor(color[0], color[1], color[2]);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject *KX_WorldInfo::pyattr_get_back_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+
+#ifdef USE_MATHUTILS
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_BACK_COLOR);
+#else
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
+ return PyObjectFrom(MT_Vector3(self->m_backgroundcolor));
+#endif
+}
+
+int KX_WorldInfo::pyattr_set_back_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
+
+ MT_Vector3 color;
+ if (PyVecTo(value, color))
+ {
+ self->setBackColor(color[0], color[1], color[2]);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ return PY_SET_ATTR_FAIL;
+}
+
+PyObject *KX_WorldInfo::pyattr_get_ambient_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+#ifdef USE_MATHUTILS
+ return Vector_CreatePyObject_cb(
+ BGE_PROXY_FROM_REF_BORROW(self_v), 3,
+ mathutils_world_vector_cb_index, MATHUTILS_VEC_CB_AMBIENT_COLOR);
+#else
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
+ return PyObjectFrom(MT_Vector3(self->m_ambientcolor));
+#endif
+}
+
+int KX_WorldInfo::pyattr_set_ambient_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_WorldInfo *self = static_cast<KX_WorldInfo*>(self_v);
+
+ MT_Vector3 color;
+ if (PyVecTo(value, color))
+ {
+ self->setAmbientColor(color[0], color[1], color[2]);
+ return PY_SET_ATTR_SUCCESS;
+ }
+ return PY_SET_ATTR_FAIL;
+}
+
+#endif /* WITH_PYTHON */
diff --git a/source/gameengine/Ketsji/KX_WorldInfo.h b/source/gameengine/Ketsji/KX_WorldInfo.h
index 90b16fe1242..0e8fe3c730a 100644
--- a/source/gameengine/Ketsji/KX_WorldInfo.h
+++ b/source/gameengine/Ketsji/KX_WorldInfo.h
@@ -33,41 +33,77 @@
#define __KX_WORLDINFO_H__
#include "MT_Scalar.h"
+#include "KX_KetsjiEngine.h"
+#include "PyObjectPlus.h"
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
-class MT_CmMatrix4x4;
+#ifdef USE_MATHUTILS
+void KX_WorldInfo_Mathutils_Callback_Init(void);
+#endif
+
+struct Scene;
+struct World;
-class KX_WorldInfo
+class KX_WorldInfo : public PyObjectPlus
{
-public:
- KX_WorldInfo() {}
- virtual ~KX_WorldInfo();
+ Py_Header
- virtual bool hasWorld() = 0;
- virtual bool hasMist() = 0;
- virtual float getBackColorRed() = 0;
- virtual float getBackColorGreen() = 0;
- virtual float getBackColorBlue() = 0;
- virtual float getMistStart() = 0;
- virtual float getMistDistance() = 0;
- virtual float getMistColorRed() = 0;
- virtual float getMistColorGreen() = 0;
- virtual float getMistColorBlue() = 0;
+ STR_String m_name;
+ bool m_do_color_management;
+ bool m_hasworld;
+ bool m_hasmist;
+ short m_misttype;
+ float m_miststart;
+ float m_mistdistance;
+ float m_mistintensity;
+ float m_mistcolor[3];
+ float m_backgroundcolor[3];
+ float m_ambientcolor[3];
+ float m_con_mistcolor[3];
+ float m_con_backgroundcolor[3];
+ float m_con_ambientcolor[3];
- virtual float getAmbientColorRed() = 0;
- virtual float getAmbientColorGreen() = 0;
- virtual float getAmbientColorBlue() = 0;
+public:
+ /**
+ * Mist options
+ */
+ enum MistType {
+ KX_MIST_QUADRATIC,
+ KX_MIST_LINEAR,
+ KX_MIST_INV_QUADRATIC,
+ };
+
+ KX_WorldInfo(Scene *blenderscene, World *blenderworld);
+ ~KX_WorldInfo();
- virtual void setBackColor(float, float, float) = 0;
- virtual void setMistStart(float) = 0;
- virtual void setMistDistance(float) = 0;
- virtual void setMistColorRed(float) = 0;
- virtual void setMistColorGreen(float) = 0;
- virtual void setMistColorBlue(float) = 0;
+ const STR_String &GetName();
+ bool hasWorld();
+ void setUseMist(bool enable);
+ void setMistType(short type);
+ void setMistStart(float d);
+ void setMistDistance(float d);
+ void setMistIntensity(float intensity);
+ void setMistColor(float r, float g, float b);
+ void setBackColor(float r, float g, float b);
+ const float *getBackColor() const;
+ void setAmbientColor(float r, float g, float b);
+ void UpdateBackGround();
+ void UpdateWorldSettings();
+#ifdef WITH_PYTHON
+ /* attributes */
+ static PyObject *pyattr_get_mist_typeconst(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static PyObject *pyattr_get_mist_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_mist_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject *pyattr_get_back_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_back_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ static PyObject *pyattr_get_ambient_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_ambient_color(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+ virtual PyObject *py_repr(void);
+#endif
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:KX_WorldInfo")
diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.cpp b/source/gameengine/Ketsji/KX_WorldIpoController.cpp
index 7f83a155643..1123e07ebcc 100644
--- a/source/gameengine/Ketsji/KX_WorldIpoController.cpp
+++ b/source/gameengine/Ketsji/KX_WorldIpoController.cpp
@@ -33,6 +33,8 @@
#include "KX_WorldIpoController.h"
#include "KX_ScalarInterpolator.h"
#include "KX_WorldInfo.h"
+#include "KX_PythonInit.h"
+#include "KX_Scene.h"
#if defined(_WIN64)
typedef unsigned __int64 uint_ptr;
@@ -42,31 +44,36 @@ typedef unsigned long uint_ptr;
bool KX_WorldIpoController::Update(double currentTime)
{
- if (m_modified)
- {
+ if (m_modified) {
T_InterpolatorList::iterator i;
for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) {
- (*i)->Execute(m_ipotime);//currentTime);
+ (*i)->Execute(m_ipotime);
}
- /* TODO, this will crash! */
- KX_WorldInfo *world = NULL;
+ KX_WorldInfo *world = KX_GetActiveScene()->GetWorldInfo();
if (m_modify_mist_start) {
world->setMistStart(m_mist_start);
}
- if (m_modify_mist_color) {
- world->setMistColorRed(m_mist_rgb[0]);
- world->setMistColorGreen(m_mist_rgb[1]);
- world->setMistColorBlue(m_mist_rgb[2]);
- }
-
if (m_modify_mist_dist) {
world->setMistDistance(m_mist_dist);
}
- m_modified=false;
+ if (m_modify_mist_intensity) {
+ world->setMistIntensity(m_mist_intensity);
+ }
+
+ if (m_modify_horizon_color) {
+ world->setBackColor(m_hori_rgb[0], m_hori_rgb[1], m_hori_rgb[2]);
+ world->setMistColor(m_hori_rgb[0], m_hori_rgb[1], m_hori_rgb[2]);
+ }
+
+ if (m_modify_ambient_color) {
+ world->setAmbientColor(m_ambi_rgb[0], m_ambi_rgb[1], m_ambi_rgb[2]);
+ }
+
+ m_modified = false;
}
return false;
}
diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.h b/source/gameengine/Ketsji/KX_WorldIpoController.h
index 63983b3129b..704f421573e 100644
--- a/source/gameengine/Ketsji/KX_WorldIpoController.h
+++ b/source/gameengine/Ketsji/KX_WorldIpoController.h
@@ -39,24 +39,30 @@
class KX_WorldIpoController : public SG_Controller
{
public:
- MT_Scalar m_mist_rgb[3];
MT_Scalar m_mist_start;
MT_Scalar m_mist_dist;
+ MT_Scalar m_mist_intensity;
+ MT_Scalar m_hori_rgb[3];
+ MT_Scalar m_ambi_rgb[3];
private:
T_InterpolatorList m_interpolators;
- unsigned short m_modify_mist_color : 1;
unsigned short m_modify_mist_start : 1;
unsigned short m_modify_mist_dist : 1;
+ unsigned short m_modify_mist_intensity : 1;
+ unsigned short m_modify_horizon_color : 1;
+ unsigned short m_modify_ambient_color : 1;
bool m_modified;
double m_ipotime;
public:
KX_WorldIpoController() :
- m_modify_mist_color(false),
m_modify_mist_start(false),
m_modify_mist_dist(false),
+ m_modify_mist_intensity(false),
+ m_modify_horizon_color(false),
+ m_modify_ambient_color(false),
m_modified(true),
m_ipotime(0.0)
{}
@@ -76,14 +82,22 @@ public:
m_modify_mist_start = modify;
}
- void SetModifyMistColor(bool modify) {
- m_modify_mist_color = modify;
- }
-
void SetModifyMistDist(bool modify) {
m_modify_mist_dist = modify;
}
+ void SetModifyMistIntensity(bool modify) {
+ m_modify_mist_intensity = modify;
+ }
+
+ void SetModifyHorizonColor(bool modify) {
+ m_modify_horizon_color = modify;
+ }
+
+ void SetModifyAmbientColor(bool modify) {
+ m_modify_ambient_color = modify;
+ }
+
void
SetOption(
int option,
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index 44c4e284e7c..8ea2b4f299d 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -39,7 +39,6 @@ subject to the following restrictions:
#include "LinearMath/btConvexHull.h"
#include "BulletCollision/Gimpact/btGImpactShape.h"
-
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
#include "DNA_mesh_types.h"
@@ -65,7 +64,6 @@ extern bool gDisableDeactivation;
float gLinearSleepingTreshold;
float gAngularSleepingTreshold;
-
BlenderBulletCharacterController::BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
: btKinematicCharacterController(ghost,shape,stepHeight,2),
m_motionState(motionState),
@@ -118,6 +116,18 @@ const btVector3& BlenderBulletCharacterController::getWalkDirection()
return m_walkDirection;
}
+bool CleanPairCallback::processOverlap(btBroadphasePair &pair)
+{
+ if ((pair.m_pProxy0 == m_cleanProxy) || (pair.m_pProxy1 == m_cleanProxy)) {
+ m_pairCache->cleanOverlappingPair(pair, m_dispatcher);
+ CcdPhysicsController *ctrl0 = (CcdPhysicsController*)(((btCollisionObject*)pair.m_pProxy0->m_clientObject)->getUserPointer());
+ CcdPhysicsController *ctrl1 = (CcdPhysicsController*)(((btCollisionObject*)pair.m_pProxy1->m_clientObject)->getUserPointer());
+ ctrl0->GetCollisionObject()->activate(false);
+ ctrl1->GetCollisionObject()->activate(false);
+ }
+ return false;
+}
+
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
:m_cci(ci)
{
@@ -588,20 +598,13 @@ void CcdPhysicsController::CreateRigidbody()
static void DeleteBulletShape(btCollisionShape* shape, bool free)
{
- if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
- {
- // shapes based on meshes use an interface that contains the vertices.
- btTriangleMeshShape* meshShape = static_cast<btTriangleMeshShape*>(shape);
- btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
- if (meshInterface)
- delete meshInterface;
- }
- else if (shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
- {
- btGImpactMeshShape* meshShape = static_cast<btGImpactMeshShape*>(shape);
- btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
- if (meshInterface)
- delete meshInterface;
+ if (shape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) {
+ /* If we use Bullet scaled shape (btScaledBvhTriangleMeshShape) we have to
+ * free the child of the unscaled shape (btTriangleMeshShape) here.
+ */
+ btTriangleMeshShape *meshShape = ((btScaledBvhTriangleMeshShape *)shape)->getChildShape();
+ if (meshShape)
+ delete meshShape;
}
if (free) {
delete shape;
@@ -634,48 +637,41 @@ bool CcdPhysicsController::DeleteControllerShape( )
bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape)
{
-
- /* Note, deleting the previous collision shape must be done already */
- /* if (m_collisionShape) DeleteControllerShape(); */
+ if (m_collisionShape)
+ DeleteControllerShape();
+
+ // If newShape is NULL it means to create a new Bullet shape.
+ if (!newShape)
+ newShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft);
m_object->setCollisionShape(newShape);
- m_collisionShape= newShape;
- m_cci.m_collisionShape= newShape;
-
- if (GetSoftBody()) {
+ m_collisionShape = newShape;
+ m_cci.m_collisionShape = newShape;
+
+ btSoftBody *softBody = GetSoftBody();
+ if (softBody) {
+ btSoftRigidDynamicsWorld *world = GetPhysicsEnvironment()->GetDynamicsWorld();
+ // remove the old softBody
+ world->removeSoftBody(softBody);
+
// soft body must be recreated
- m_cci.m_physicsEnv->RemoveCcdPhysicsController(this);
delete m_object;
m_object = NULL;
// force complete reinitialization
m_softbodyMappingDone = false;
m_prototypeTransformInitialized = false;
m_softBodyTransformInitialized = false;
+
CreateSoftbody();
assert(m_object);
- // reinsert the new body
- m_cci.m_physicsEnv->AddCcdPhysicsController(this);
- }
-
- /* Copied from CcdPhysicsEnvironment::addCcdPhysicsController() */
-
- /* without this, an object can rest on the old physics mesh
- * and not move to account for the physics mesh, even with 'nosleep' */
- btSoftRigidDynamicsWorld* dw= GetPhysicsEnvironment()->GetDynamicsWorld();
- btCollisionObjectArray &obarr= dw->getCollisionObjectArray();
- btCollisionObject *ob;
- btBroadphaseProxy* proxy;
-
- for (int i= 0; i < obarr.size(); i++) {
- ob= obarr[i];
- if (ob->getCollisionShape() == newShape) {
- proxy = ob->getBroadphaseHandle();
-
- if (proxy)
- dw->getPairCache()->cleanProxyFromPairs(proxy,dw->getDispatcher());
- }
+
+ btSoftBody *newSoftBody = GetSoftBody();
+ // set the user
+ newSoftBody->setUserPointer(this);
+ // add the new softbody
+ world->addSoftBody(newSoftBody);
}
-
+
return true;
}
@@ -850,36 +846,6 @@ void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionsta
m_cci.m_physicsEnv->AddCcdPhysicsController(this);
-/* SM_Object* dynaparent=0;
- SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl;
-
- if (sumoparentctrl)
- {
- dynaparent = sumoparentctrl->GetSumoObject();
- }
-
- SM_Object* orgsumoobject = m_sumoObj;
-
-
- m_sumoObj = new SM_Object(
- orgsumoobject->getShapeHandle(),
- orgsumoobject->getMaterialProps(),
- orgsumoobject->getShapeProps(),
- dynaparent);
-
- m_sumoObj->setRigidBody(orgsumoobject->isRigidBody());
-
- m_sumoObj->setMargin(orgsumoobject->getMargin());
- m_sumoObj->setPosition(orgsumoobject->getPosition());
- m_sumoObj->setOrientation(orgsumoobject->getOrientation());
- //if it is a dyna, register for a callback
- m_sumoObj->registerCallback(*this);
-
- m_sumoScene->add(* (m_sumoObj));
- */
-
-
-
}
void CcdPhysicsController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env)
@@ -1082,6 +1048,25 @@ void CcdPhysicsController::ResolveCombinedVelocities(float linvelX,float linvel
{
}
+void CcdPhysicsController::RefreshCollisions()
+{
+ // the object is in an inactive layer so it's useless to update it and can cause problems
+ if (!GetPhysicsEnvironment()->IsActiveCcdPhysicsController(this))
+ return;
+
+ btSoftRigidDynamicsWorld *dw = GetPhysicsEnvironment()->GetDynamicsWorld();
+ btBroadphaseProxy *proxy = m_object->getBroadphaseHandle();
+ btDispatcher *dispatcher = dw->getDispatcher();
+ btOverlappingPairCache *pairCache = dw->getPairCache();
+
+ CleanPairCallback cleanPairs(proxy, pairCache, dispatcher);
+ pairCache->processAllOverlappingPairs(&cleanPairs, dispatcher);
+
+ // Forcibly recreate the physics object
+ btBroadphaseProxy* handle = m_object->getBroadphaseHandle();
+ GetPhysicsEnvironment()->UpdateCcdPhysicsController(this, GetMass(), m_object->getCollisionFlags(), handle->m_collisionFilterGroup, handle->m_collisionFilterMask);
+}
+
void CcdPhysicsController::SuspendDynamics(bool ghost)
{
btRigidBody *body = GetRigidBody();
@@ -1546,8 +1531,7 @@ void CcdPhysicsController::AddCompoundChild(PHY_IPhysicsController* child)
const btCollisionShape* childShape = childBody->getCollisionShape();
if (!rootShape ||
!childShape ||
- rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE ||
- childShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
+ rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE)
return;
btCompoundShape* compoundShape = (btCompoundShape*)rootShape;
// compute relative transformation between parent and child
@@ -1597,7 +1581,7 @@ void CcdPhysicsController::AddCompoundChild(PHY_IPhysicsController* child)
// must update the broadphase cache,
GetPhysicsEnvironment()->RefreshCcdPhysicsController(this);
// remove the children
- GetPhysicsEnvironment()->DisableCcdPhysicsController(childCtrl);
+ GetPhysicsEnvironment()->RemoveCcdPhysicsController(childCtrl);
}
/* Reverse function of the above, it will remove a shape from a compound shape
@@ -1653,7 +1637,7 @@ void CcdPhysicsController::RemoveCompoundChild(PHY_IPhysicsController* child)
// must update the broadphase cache,
GetPhysicsEnvironment()->RefreshCcdPhysicsController(this);
// reactivate the children
- GetPhysicsEnvironment()->EnableCcdPhysicsController(childCtrl);
+ GetPhysicsEnvironment()->AddCcdPhysicsController(childCtrl);
}
PHY_IPhysicsController* CcdPhysicsController::GetReplica()
@@ -1713,33 +1697,50 @@ PHY_IPhysicsController* CcdPhysicsController::GetReplicaForSensors()
* 2) from_gameobj - creates the phys mesh from the DerivedMesh where possible, else the RAS_MeshObject
* 3) this - update the phys mesh from DerivedMesh or RAS_MeshObject
*
- * Most of the logic behind this is in shapeInfo->UpdateMesh(...)
+ * Most of the logic behind this is in m_shapeInfo->UpdateMesh(...)
*/
bool CcdPhysicsController::ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject *from_meshobj)
{
- CcdShapeConstructionInfo *shapeInfo;
-
- shapeInfo = this->GetShapeInfo();
-
- if (shapeInfo->m_shapeType != PHY_SHAPE_MESH/* || spc->GetSoftBody()*/)
+ if (m_shapeInfo->m_shapeType != PHY_SHAPE_MESH)
return false;
- this->DeleteControllerShape();
-
- if (from_gameobj==NULL && from_meshobj==NULL)
- from_gameobj = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)this->GetNewClientInfo());
+ if (!from_gameobj && !from_meshobj)
+ from_gameobj = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)GetNewClientInfo());
/* updates the arrays used for making the new bullet mesh */
- shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
+ m_shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
/* create the new bullet mesh */
- CcdConstructionInfo& cci = this->GetConstructionInfo();
- btCollisionShape* bm= shapeInfo->CreateBulletShape(cci.m_margin, cci.m_bGimpact, !cci.m_bSoft);
+ GetPhysicsEnvironment()->UpdateCcdPhysicsControllerShape(m_shapeInfo);
- this->ReplaceControllerShape(bm);
return true;
}
+void CcdPhysicsController::ReplicateConstraints(KX_GameObject *replica, std::vector<KX_GameObject*> constobj)
+{
+ if (replica->GetConstraints().size() == 0 || !replica->GetPhysicsController())
+ return;
+
+ PHY_IPhysicsEnvironment *physEnv = GetPhysicsEnvironment();
+
+ vector<bRigidBodyJointConstraint*> constraints = replica->GetConstraints();
+ vector<bRigidBodyJointConstraint*>::iterator consit;
+
+ /* Object could have some constraints, iterate over all of theme to ensure that every constraint is recreated. */
+ for (consit = constraints.begin(); consit != constraints.end(); ++consit) {
+ /* Try to find the constraint targets in the list of group objects. */
+ bRigidBodyJointConstraint *dat = (*consit);
+ vector<KX_GameObject*>::iterator memit;
+ for (memit = constobj.begin(); memit != constobj.end(); ++memit) {
+ KX_GameObject *member = (*memit);
+ /* If the group member is the actual target for the constraint. */
+ if (dat->tar->id.name + 2 == member->GetName() && member->GetPhysicsController())
+ physEnv->SetupObjectConstraints(replica, member, dat);
+ }
+ }
+
+}
+
///////////////////////////////////////////////////////////
///A small utility class, DefaultMotionState
///
@@ -1821,7 +1822,7 @@ CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mes
return NULL;
}
-bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, bool polytope)
+bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject *meshobj, DerivedMesh *dm, bool polytope)
{
int numpolys, numverts;
@@ -1833,7 +1834,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
bool free_dm = false;
// No mesh object or mesh has no polys
- if (!meshobj || meshobj->HasColliderPolygon()==false) {
+ if (!meshobj || !meshobj->HasColliderPolygon()) {
m_vertexArray.clear();
m_polygonIndexArray.clear();
m_triFaceArray.clear();
@@ -1856,80 +1857,83 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
/* double lookup */
const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if (index_mf_to_mpoly == NULL) {
+ if (!index_mf_to_mpoly) {
index_mp_to_orig = NULL;
}
m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH;
/* Convert blender geometry into bullet mesh, need these vars for mapping */
- vector<bool> vert_tag_array(numverts, false);
- unsigned int tot_bt_verts= 0;
+ std::vector<bool> vert_tag_array(numverts, false);
+ unsigned int tot_bt_verts = 0;
- if (polytope)
- {
+ if (polytope) {
// Tag verts we're using
- for (int p2=0; p2<numpolys; p2++)
- {
- MFace* mf = &mface[p2];
+ for (int p2 = 0; p2 < numpolys; p2++) {
+ MFace *mf = &mface[p2];
const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2;
- RAS_Polygon* poly = meshobj->GetPolygon(origi);
+ RAS_Polygon *poly = meshobj->GetPolygon(origi);
// only add polygons that have the collision flag set
- if (poly->IsCollider())
- {
- if (vert_tag_array[mf->v1] == false) {vert_tag_array[mf->v1] = true; tot_bt_verts++;}
- if (vert_tag_array[mf->v2] == false) {vert_tag_array[mf->v2] = true; tot_bt_verts++;}
- if (vert_tag_array[mf->v3] == false) {vert_tag_array[mf->v3] = true; tot_bt_verts++;}
- if (mf->v4 && vert_tag_array[mf->v4] == false) {vert_tag_array[mf->v4] = true; tot_bt_verts++;}
+ if (poly->IsCollider()) {
+ if (!vert_tag_array[mf->v1]) {
+ vert_tag_array[mf->v1] = true;
+ tot_bt_verts++;
+ }
+ if (!vert_tag_array[mf->v2]) {
+ vert_tag_array[mf->v2] = true;
+ tot_bt_verts++;
+ }
+ if (!vert_tag_array[mf->v3]) {
+ vert_tag_array[mf->v3] = true;
+ tot_bt_verts++;
+ }
+ if (mf->v4 && !vert_tag_array[mf->v4]) {
+ vert_tag_array[mf->v4] = true;
+ tot_bt_verts++;
+ }
}
}
-
+
/* Can happen with ngons */
if (!tot_bt_verts) {
goto cleanup_empty_mesh;
}
- m_vertexArray.resize(tot_bt_verts*3);
+ m_vertexArray.resize(tot_bt_verts * 3);
- btScalar *bt= &m_vertexArray[0];
+ btScalar *bt = &m_vertexArray[0];
- for (int p2=0; p2<numpolys; p2++)
- {
- MFace* mf = &mface[p2];
+ for (int p2 = 0; p2 < numpolys; p2++) {
+ MFace *mf = &mface[p2];
const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2;
- RAS_Polygon* poly= meshobj->GetPolygon(origi);
+ RAS_Polygon *poly = meshobj->GetPolygon(origi);
// only add polygons that have the collisionflag set
- if (poly->IsCollider())
- {
- if (vert_tag_array[mf->v1]==true)
- {
- const float* vtx = mvert[mf->v1].co;
+ if (poly->IsCollider()) {
+ if (vert_tag_array[mf->v1]) {
+ const float *vtx = mvert[mf->v1].co;
vert_tag_array[mf->v1] = false;
*bt++ = vtx[0];
*bt++ = vtx[1];
*bt++ = vtx[2];
}
- if (vert_tag_array[mf->v2]==true)
- {
- const float* vtx = mvert[mf->v2].co;
+ if (vert_tag_array[mf->v2]) {
+ const float *vtx = mvert[mf->v2].co;
vert_tag_array[mf->v2] = false;
*bt++ = vtx[0];
*bt++ = vtx[1];
*bt++ = vtx[2];
}
- if (vert_tag_array[mf->v3]==true)
- {
- const float* vtx = mvert[mf->v3].co;
+ if (vert_tag_array[mf->v3]) {
+ const float *vtx = mvert[mf->v3].co;
vert_tag_array[mf->v3] = false;
*bt++ = vtx[0];
*bt++ = vtx[1];
*bt++ = vtx[2];
}
- if (mf->v4 && vert_tag_array[mf->v4]==true)
- {
- const float* vtx = mvert[mf->v4].co;
+ if (mf->v4 && vert_tag_array[mf->v4]) {
+ const float *vtx = mvert[mf->v4].co;
vert_tag_array[mf->v4] = false;
*bt++ = vtx[0];
*bt++ = vtx[1];
@@ -1939,28 +1943,38 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
}
}
else {
- unsigned int tot_bt_tris= 0;
- vector<int> vert_remap_array(numverts, 0);
-
+ unsigned int tot_bt_tris = 0;
+ std::vector<int> vert_remap_array(numverts, 0);
+
// Tag verts we're using
- for (int p2=0; p2<numpolys; p2++)
- {
- MFace* mf = &mface[p2];
+ for (int p2 = 0; p2 < numpolys; p2++) {
+ MFace *mf = &mface[p2];
const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2;
- RAS_Polygon* poly= meshobj->GetPolygon(origi);
+ RAS_Polygon *poly = meshobj->GetPolygon(origi);
// only add polygons that have the collision flag set
- if (poly->IsCollider())
- {
- if (vert_tag_array[mf->v1]==false)
- {vert_tag_array[mf->v1] = true;vert_remap_array[mf->v1] = tot_bt_verts;tot_bt_verts++;}
- if (vert_tag_array[mf->v2]==false)
- {vert_tag_array[mf->v2] = true;vert_remap_array[mf->v2] = tot_bt_verts;tot_bt_verts++;}
- if (vert_tag_array[mf->v3]==false)
- {vert_tag_array[mf->v3] = true;vert_remap_array[mf->v3] = tot_bt_verts;tot_bt_verts++;}
- if (mf->v4 && vert_tag_array[mf->v4]==false)
- {vert_tag_array[mf->v4] = true;vert_remap_array[mf->v4] = tot_bt_verts;tot_bt_verts++;}
- tot_bt_tris += (mf->v4 ? 2:1); /* a quad or a tri */
+ if (poly->IsCollider()) {
+ if (!vert_tag_array[mf->v1]) {
+ vert_tag_array[mf->v1] = true;
+ vert_remap_array[mf->v1] = tot_bt_verts;
+ tot_bt_verts++;
+ }
+ if (!vert_tag_array[mf->v2]) {
+ vert_tag_array[mf->v2] = true;
+ vert_remap_array[mf->v2] = tot_bt_verts;
+ tot_bt_verts++;
+ }
+ if (!vert_tag_array[mf->v3]) {
+ vert_tag_array[mf->v3] = true;
+ vert_remap_array[mf->v3] = tot_bt_verts;
+ tot_bt_verts++;
+ }
+ if (mf->v4 && !vert_tag_array[mf->v4]) {
+ vert_tag_array[mf->v4] = true;
+ vert_remap_array[mf->v4] = tot_bt_verts;
+ tot_bt_verts++;
+ }
+ tot_bt_tris += (mf->v4 ? 2 : 1); /* a quad or a tri */
}
}
@@ -1969,43 +1983,39 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
goto cleanup_empty_mesh;
}
- m_vertexArray.resize(tot_bt_verts*3);
+ m_vertexArray.resize(tot_bt_verts * 3);
m_polygonIndexArray.resize(tot_bt_tris);
- m_triFaceArray.resize(tot_bt_tris*3);
- btScalar *bt= &m_vertexArray[0];
- int *poly_index_pt= &m_polygonIndexArray[0];
- int *tri_pt= &m_triFaceArray[0];
+ m_triFaceArray.resize(tot_bt_tris * 3);
+ btScalar *bt = &m_vertexArray[0];
+ int *poly_index_pt = &m_polygonIndexArray[0];
+ int *tri_pt = &m_triFaceArray[0];
UVco *uv_pt = NULL;
- if (tface)
- {
- m_triFaceUVcoArray.resize(tot_bt_tris*3);
+ if (tface) {
+ m_triFaceUVcoArray.resize(tot_bt_tris * 3);
uv_pt = &m_triFaceUVcoArray[0];
- }
- else
+ }
+ else
m_triFaceUVcoArray.clear();
- for (int p2=0; p2<numpolys; p2++)
- {
- MFace* mf = &mface[p2];
- MTFace* tf = (tface) ? &tface[p2] : NULL;
+ for (int p2 = 0; p2 < numpolys; p2++) {
+ MFace *mf = &mface[p2];
+ MTFace *tf = (tface) ? &tface[p2] : NULL;
const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2;
- RAS_Polygon* poly= meshobj->GetPolygon(origi);
+ RAS_Polygon *poly = meshobj->GetPolygon(origi);
// only add polygons that have the collisionflag set
- if (poly->IsCollider())
- {
- MVert *v1= &mvert[mf->v1];
- MVert *v2= &mvert[mf->v2];
- MVert *v3= &mvert[mf->v3];
+ if (poly->IsCollider()) {
+ MVert *v1 = &mvert[mf->v1];
+ MVert *v2 = &mvert[mf->v2];
+ MVert *v3 = &mvert[mf->v3];
// the face indices
tri_pt[0] = vert_remap_array[mf->v1];
tri_pt[1] = vert_remap_array[mf->v2];
tri_pt[2] = vert_remap_array[mf->v3];
- tri_pt= tri_pt+3;
- if (tf)
- {
+ tri_pt = tri_pt + 3;
+ if (tf) {
uv_pt[0].uv[0] = tf->uv[0][0];
uv_pt[0].uv[1] = tf->uv[0][1];
uv_pt[1].uv[0] = tf->uv[1][0];
@@ -2020,19 +2030,19 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
poly_index_pt++;
// the vertex location
- if (vert_tag_array[mf->v1]==true) { /* *** v1 *** */
+ if (vert_tag_array[mf->v1]) { /* *** v1 *** */
vert_tag_array[mf->v1] = false;
*bt++ = v1->co[0];
*bt++ = v1->co[1];
*bt++ = v1->co[2];
}
- if (vert_tag_array[mf->v2]==true) { /* *** v2 *** */
+ if (vert_tag_array[mf->v2]) { /* *** v2 *** */
vert_tag_array[mf->v2] = false;
*bt++ = v2->co[0];
*bt++ = v2->co[1];
*bt++ = v2->co[2];
}
- if (vert_tag_array[mf->v3]==true) { /* *** v3 *** */
+ if (vert_tag_array[mf->v3]) { /* *** v3 *** */
vert_tag_array[mf->v3] = false;
*bt++ = v3->co[0];
*bt++ = v3->co[1];
@@ -2041,12 +2051,12 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
if (mf->v4)
{
- MVert *v4= &mvert[mf->v4];
+ MVert *v4 = &mvert[mf->v4];
tri_pt[0] = vert_remap_array[mf->v1];
tri_pt[1] = vert_remap_array[mf->v3];
tri_pt[2] = vert_remap_array[mf->v4];
- tri_pt= tri_pt+3;
+ tri_pt = tri_pt + 3;
if (tf)
{
uv_pt[0].uv[0] = tf->uv[0][0];
@@ -2063,7 +2073,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
poly_index_pt++;
// the vertex location
- if (vert_tag_array[mf->v4] == true) { /* *** v4 *** */
+ if (vert_tag_array[mf->v4]) { /* *** v4 *** */
vert_tag_array[mf->v4] = false;
*bt++ = v4->co[0];
*bt++ = v4->co[1];
@@ -2077,27 +2087,27 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
/* If this ever gets confusing, print out an OBJ file for debugging */
#if 0
printf("# vert count %d\n", m_vertexArray.size());
- for (i=0; i<m_vertexArray.size(); i+=1) {
+ for (i = 0; i < m_vertexArray.size(); i += 1) {
printf("v %.6f %.6f %.6f\n", m_vertexArray[i].x(), m_vertexArray[i].y(), m_vertexArray[i].z());
}
printf("# face count %d\n", m_triFaceArray.size());
- for (i=0; i<m_triFaceArray.size(); i+=3) {
- printf("f %d %d %d\n", m_triFaceArray[i]+1, m_triFaceArray[i+1]+1, m_triFaceArray[i+2]+1);
+ for (i = 0; i < m_triFaceArray.size(); i += 3) {
+ printf("f %d %d %d\n", m_triFaceArray[i] + 1, m_triFaceArray[i + 1] + 1, m_triFaceArray[i + 2] + 1);
}
#endif
}
#if 0
- if (validpolys==false)
+ if (validpolys == false)
{
// should not happen
m_shapeType = PHY_SHAPE_NONE;
return false;
}
#endif
-
+
m_meshObject = meshobj;
if (free_dm) {
dm->release(dm);
@@ -2105,10 +2115,9 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm,
}
// sharing only on static mesh at present, if you change that, you must also change in FindMesh
- if (!polytope && !dm)
- {
+ if (!polytope && !dm) {
// triangle shape can be shared, store the mesh object in the map
- m_meshShapeMap.insert(std::pair<RAS_MeshObject*,CcdShapeConstructionInfo*>(meshobj,this));
+ m_meshShapeMap.insert(std::pair<RAS_MeshObject *, CcdShapeConstructionInfo *>(meshobj, this));
}
return true;
@@ -2131,51 +2140,50 @@ cleanup_empty_mesh:
/* Updates the arrays used by CreateBulletShape(),
* take care that recalcLocalAabb() runs after CreateBulletShape is called.
* */
-bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RAS_MeshObject* meshobj)
+bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject *gameobj, class RAS_MeshObject *meshobj)
{
int numpolys;
int numverts;
- unsigned int tot_bt_tris= 0;
- unsigned int tot_bt_verts= 0;
+ unsigned int tot_bt_tris = 0;
+ unsigned int tot_bt_verts = 0;
int i, j;
int v_orig;
/* Use for looping over verts in a face as a try or 2 tris */
- const int quad_verts[7]= {0,1,2, 0,2,3, -1};
- const int tri_verts[4]= {0,1,2, -1};
+ const int quad_verts[7] = {0, 1, 2, 0, 2, 3, -1};
+ const int tri_verts[4] = {0, 1, 2, -1};
const int *fv_pt;
- if (gameobj==NULL && meshobj==NULL)
+ if (!gameobj && !meshobj)
return false;
-
+
if (m_shapeType != PHY_SHAPE_MESH)
return false;
- RAS_Deformer *deformer= gameobj ? gameobj->GetDeformer():NULL;
- DerivedMesh* dm = NULL;
+ RAS_Deformer *deformer = gameobj ? gameobj->GetDeformer() : NULL;
+ DerivedMesh *dm = NULL;
if (deformer)
dm = deformer->GetPhysicsMesh();
-
+
/* get the mesh from the object if not defined */
- if (meshobj==NULL) {
-
+ if (!meshobj) {
/* modifier mesh */
if (dm)
- meshobj= deformer->GetRasMesh();
-
+ meshobj = deformer->GetRasMesh();
+
/* game object first mesh */
- if (meshobj==NULL) {
+ if (!meshobj) {
if (gameobj->GetMeshCount() > 0) {
- meshobj= gameobj->GetMesh(0);
+ meshobj = gameobj->GetMesh(0);
}
}
}
-
- if (dm && deformer->GetRasMesh() == meshobj)
- { /*
+
+ if (dm && deformer->GetRasMesh() == meshobj) {
+ /*
* Derived Mesh Update
*
* */
@@ -2187,41 +2195,38 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
/* double lookup */
const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if (index_mf_to_mpoly == NULL) {
+ const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ if (!index_mf_to_mpoly) {
index_mp_to_orig = NULL;
}
MFace *mf;
MVert *mv;
- int flen;
-
- if (CustomData_has_layer(&dm->faceData, CD_MTFACE))
- {
+ if (CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
MTFace *tface = (MTFace *)dm->getTessFaceDataArray(dm, CD_MTFACE);
MTFace *tf;
- vector<bool> vert_tag_array(numverts, false);
- vector<int> vert_remap_array(numverts, 0);
+ std::vector<bool> vert_tag_array(numverts, false);
+ std::vector<int> vert_remap_array(numverts, 0);
+
+ for (mf = mface, tf = tface, i = 0; i < numpolys; mf++, tf++, i++) {
+ if (tf->mode & TF_DYNAMIC) {
+ int flen;
- for (mf= mface, tf= tface, i=0; i < numpolys; mf++, tf++, i++) {
- if (tf->mode & TF_DYNAMIC)
- {
if (mf->v4) {
- tot_bt_tris+= 2;
- flen= 4;
- } else {
+ tot_bt_tris += 2;
+ flen = 4;
+ }
+ else {
tot_bt_tris++;
- flen= 3;
+ flen = 3;
}
- for (j=0; j<flen; j++)
- {
+ for (j = 0; j < flen; j++) {
v_orig = (*(&mf->v1 + j));
- if (vert_tag_array[v_orig]==false)
- {
+ if (!vert_tag_array[v_orig]) {
vert_tag_array[v_orig] = true;
vert_remap_array[v_orig] = tot_bt_verts;
tot_bt_verts++;
@@ -2230,42 +2235,38 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
}
}
- m_vertexArray.resize(tot_bt_verts*3);
- btScalar *bt= &m_vertexArray[0];
+ m_vertexArray.resize(tot_bt_verts * 3);
+ btScalar *bt = &m_vertexArray[0];
- m_triFaceArray.resize(tot_bt_tris*3);
- int *tri_pt= &m_triFaceArray[0];
+ m_triFaceArray.resize(tot_bt_tris * 3);
+ int *tri_pt = &m_triFaceArray[0];
- m_triFaceUVcoArray.resize(tot_bt_tris*3);
- UVco *uv_pt= &m_triFaceUVcoArray[0];
+ m_triFaceUVcoArray.resize(tot_bt_tris * 3);
+ UVco *uv_pt = &m_triFaceUVcoArray[0];
m_polygonIndexArray.resize(tot_bt_tris);
- int *poly_index_pt= &m_polygonIndexArray[0];
+ int *poly_index_pt = &m_polygonIndexArray[0];
- for (mf= mface, tf= tface, i=0; i < numpolys; mf++, tf++, i++)
- {
- if (tf->mode & TF_DYNAMIC)
- {
+ for (mf = mface, tf = tface, i = 0; i < numpolys; mf++, tf++, i++) {
+ if (tf->mode & TF_DYNAMIC) {
int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
if (mf->v4) {
- fv_pt= quad_verts;
+ fv_pt = quad_verts;
*poly_index_pt++ = origi;
*poly_index_pt++ = origi;
- flen= 4;
- } else {
- fv_pt= tri_verts;
+ }
+ else {
+ fv_pt = tri_verts;
*poly_index_pt++ = origi;
- flen= 3;
}
- for (; *fv_pt > -1; fv_pt++)
- {
+ for (; *fv_pt > -1; fv_pt++) {
v_orig = (*(&mf->v1 + (*fv_pt)));
if (vert_tag_array[v_orig])
{
- mv= mvert + v_orig;
+ mv = mvert + v_orig;
*bt++ = mv->co[0];
*bt++ = mv->co[1];
*bt++ = mv->co[2];
@@ -2283,37 +2284,37 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
else {
/* no need for a vertex mapping. simple/fast */
- tot_bt_verts= numverts;
+ tot_bt_verts = numverts;
- for (mf= mface, i=0; i < numpolys; mf++, i++) {
- tot_bt_tris += (mf->v4 ? 2:1);
+ for (mf = mface, i = 0; i < numpolys; mf++, i++) {
+ tot_bt_tris += (mf->v4 ? 2 : 1);
}
- m_vertexArray.resize(tot_bt_verts*3);
- btScalar *bt= &m_vertexArray[0];
+ m_vertexArray.resize(tot_bt_verts * 3);
+ btScalar *bt = &m_vertexArray[0];
- m_triFaceArray.resize(tot_bt_tris*3);
- int *tri_pt= &m_triFaceArray[0];
+ m_triFaceArray.resize(tot_bt_tris * 3);
+ int *tri_pt = &m_triFaceArray[0];
m_polygonIndexArray.resize(tot_bt_tris);
- int *poly_index_pt= &m_polygonIndexArray[0];
+ int *poly_index_pt = &m_polygonIndexArray[0];
m_triFaceUVcoArray.clear();
- for (mv= mvert, i=0; i < numverts; mv++, i++) {
+ for (mv = mvert, i = 0; i < numverts; mv++, i++) {
*bt++ = mv->co[0]; *bt++ = mv->co[1]; *bt++ = mv->co[2];
}
- for (mf= mface, i=0; i < numpolys; mf++, i++) {
+ for (mf = mface, i = 0; i < numpolys; mf++, i++) {
int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
if (mf->v4) {
- fv_pt= quad_verts;
+ fv_pt = quad_verts;
*poly_index_pt++ = origi;
*poly_index_pt++ = origi;
}
else {
- fv_pt= tri_verts;
+ fv_pt = tri_verts;
*poly_index_pt++ = origi;
}
@@ -2322,51 +2323,46 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
}
}
}
- else { /*
- * RAS Mesh Update
- *
- * */
-
+ else { /*
+ * RAS Mesh Update
+ *
+ * */
/* Note!, gameobj can be NULL here */
/* transverts are only used for deformed RAS_Meshes, the RAS_TexVert data
* is too hard to get at, see below for details */
- float (*transverts)[3] = NULL;
- int transverts_tot= 0; /* with deformed meshes - should always be greater than the max orginal index, or we get crashes */
+ float(*transverts)[3] = NULL;
+ int transverts_tot = 0; /* with deformed meshes - should always be greater than the max orginal index, or we get crashes */
if (deformer) {
/* map locations from the deformed array
*
* Could call deformer->Update(); but rely on redraw updating.
* */
- transverts= deformer->GetTransVerts(&transverts_tot);
+ transverts = deformer->GetTransVerts(&transverts_tot);
}
// Tag verts we're using
- numpolys= meshobj->NumPolygons();
- numverts= meshobj->m_sharedvertex_map.size();
+ numpolys = meshobj->NumPolygons();
+ numverts = meshobj->m_sharedvertex_map.size();
const float *xyz;
- vector<bool> vert_tag_array(numverts, false);
- vector<int> vert_remap_array(numverts, 0);
+ std::vector<bool> vert_tag_array(numverts, false);
+ std::vector<int> vert_remap_array(numverts, 0);
- for (int p=0; p<numpolys; p++)
- {
- RAS_Polygon* poly= meshobj->GetPolygon(p);
- if (poly->IsCollider())
- {
- for (i=0; i < poly->VertexCount(); i++)
- {
- v_orig= poly->GetVertex(i)->getOrigIndex();
- if (vert_tag_array[v_orig]==false)
- {
+ for (int p = 0; p < numpolys; p++) {
+ RAS_Polygon *poly = meshobj->GetPolygon(p);
+ if (poly->IsCollider()) {
+ for (i = 0; i < poly->VertexCount(); i++) {
+ v_orig = poly->GetVertex(i)->getOrigIndex();
+ if (!vert_tag_array[v_orig]) {
vert_tag_array[v_orig] = true;
vert_remap_array[v_orig] = tot_bt_verts;
tot_bt_verts++;
}
}
- tot_bt_tris += (poly->VertexCount()==4 ? 2:1);
+ tot_bt_tris += (poly->VertexCount() == 4 ? 2 : 1);
}
}
@@ -2374,32 +2370,29 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
if (tot_bt_tris == 0 || tot_bt_verts == 0)
return false;
- m_vertexArray.resize(tot_bt_verts*3);
- btScalar *bt= &m_vertexArray[0];
+ m_vertexArray.resize(tot_bt_verts * 3);
+ btScalar *bt = &m_vertexArray[0];
- m_triFaceArray.resize(tot_bt_tris*3);
- int *tri_pt= &m_triFaceArray[0];
+ m_triFaceArray.resize(tot_bt_tris * 3);
+ int *tri_pt = &m_triFaceArray[0];
/* cant be used for anything useful in this case, since we don't rely on the original mesh
* will just be an array like pythons range(tot_bt_tris) */
m_polygonIndexArray.resize(tot_bt_tris);
- for (int p=0; p<numpolys; p++)
- {
- RAS_Polygon* poly= meshobj->GetPolygon(p);
+ int p = 0;
+ int t = 0;
+ while (t < tot_bt_tris) {
+ RAS_Polygon *poly = meshobj->GetPolygon(p);
- if (poly->IsCollider())
- {
+ if (poly->IsCollider()) {
/* quad or tri loop */
- fv_pt= (poly->VertexCount()==3 ? tri_verts:quad_verts);
+ fv_pt = (poly->VertexCount() == 3 ? tri_verts : quad_verts);
- for (; *fv_pt > -1; fv_pt++)
- {
- v_orig= poly->GetVertex(*fv_pt)->getOrigIndex();
-
- if (vert_tag_array[v_orig])
- {
+ for (; *fv_pt > -1; fv_pt++) {
+ v_orig = poly->GetVertex(*fv_pt)->getOrigIndex();
+ if (vert_tag_array[v_orig]) {
if (transverts) {
/* deformed mesh, using RAS_TexVert locations would be too troublesome
* because they are use the gameob as a hash in the material slot */
@@ -2409,55 +2402,60 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
}
else {
/* static mesh python may have modified */
- xyz= meshobj->GetVertexLocation( v_orig );
+ xyz = meshobj->GetVertexLocation(v_orig);
*bt++ = xyz[0];
*bt++ = xyz[1];
*bt++ = xyz[2];
}
-
vert_tag_array[v_orig] = false;
}
-
*tri_pt++ = vert_remap_array[v_orig];
}
}
-
- m_polygonIndexArray[p] = p; /* dumb counting */
+ // first triangle
+ m_polygonIndexArray[t] = p;
+
+ // if the poly is a quad we transform it in two triangles
+ if (poly->VertexCount() == 4) {
+ t++;
+ // second triangle
+ m_polygonIndexArray[t] = p;
+ }
+ t++;
+ p++;
}
}
-
+
#if 0
/* needs #include <cstdio> */
printf("# vert count %d\n", m_vertexArray.size());
- for (int i=0; i<m_vertexArray.size(); i+=3) {
- printf("v %.6f %.6f %.6f\n", m_vertexArray[i], m_vertexArray[i+1], m_vertexArray[i+2]);
+ for (int i = 0; i < m_vertexArray.size(); i += 3) {
+ printf("v %.6f %.6f %.6f\n", m_vertexArray[i], m_vertexArray[i + 1], m_vertexArray[i + 2]);
}
printf("# face count %d\n", m_triFaceArray.size());
- for (int i=0; i<m_triFaceArray.size(); i+=3) {
- printf("f %d %d %d\n", m_triFaceArray[i]+1, m_triFaceArray[i+1]+1, m_triFaceArray[i+2]+1);
+ for (int i = 0; i < m_triFaceArray.size(); i += 3) {
+ printf("f %d %d %d\n", m_triFaceArray[i] + 1, m_triFaceArray[i + 1] + 1, m_triFaceArray[i + 2] + 1);
}
#endif
- /* force recreation of the m_unscaledShape.
+ /* force recreation of the m_triangleIndexVertexArray.
* If this has multiple users we cant delete */
- if (m_unscaledShape) {
- // don't free now so it can re-allocate under the same location and not break pointers.
- // DeleteBulletShape(m_unscaledShape);
- m_forceReInstance= true;
+ if (m_triangleIndexVertexArray) {
+ m_forceReInstance = true;
}
// Make sure to also replace the mesh in the shape map! Otherwise we leave dangling references when we free.
// Note, this whole business could cause issues with shared meshes. If we update one mesh, do we replace
// them all?
- std::map<RAS_MeshObject*,CcdShapeConstructionInfo*>::iterator mit = m_meshShapeMap.find(m_meshObject);
+ std::map<RAS_MeshObject *, CcdShapeConstructionInfo *>::iterator mit = m_meshShapeMap.find(m_meshObject);
if (mit != m_meshShapeMap.end()) {
m_meshShapeMap.erase(mit);
m_meshShapeMap[meshobj] = this;
}
- m_meshObject= meshobj;
-
+ m_meshObject = meshobj;
+
if (dm) {
dm->needsFree = 1;
dm->release(dm);
@@ -2465,8 +2463,6 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA
return true;
}
-
-
bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo)
{
if (shapeInfo == NULL)
@@ -2529,74 +2525,61 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, b
// 9 multiplications/additions and one function call for each triangle that passes the mid phase filtering
// One possible optimization is to use directly the btBvhTriangleMeshShape when the scale is 1,1,1
// and btScaledBvhTriangleMeshShape otherwise.
- if (useGimpact)
- {
- btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(
+ if (useGimpact) {
+ if (!m_triangleIndexVertexArray || m_forceReInstance) {
+ if (m_triangleIndexVertexArray)
+ delete m_triangleIndexVertexArray;
+
+ m_triangleIndexVertexArray = new btTriangleIndexVertexArray(
m_polygonIndexArray.size(),
- &m_triFaceArray[0],
- 3*sizeof(int),
- m_vertexArray.size()/3,
+ m_triFaceArray.data(),
+ 3 * sizeof(int),
+ m_vertexArray.size() / 3,
&m_vertexArray[0],
- 3*sizeof(btScalar)
- );
- btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(indexVertexArrays);
- gimpactShape->setMargin(margin);
- gimpactShape->updateBound();
- collisionShape = gimpactShape;
-
-
- } else
- {
- if (!m_unscaledShape || m_forceReInstance)
- {
-
- btTriangleIndexVertexArray* indexVertexArrays = 0;
+ 3 * sizeof(btScalar));
+ m_forceReInstance = false;
+ }
+ btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(m_triangleIndexVertexArray);
+ gimpactShape->setMargin(margin);
+ gimpactShape->updateBound();
+ collisionShape = gimpactShape;
+ }
+ else {
+ if (!m_triangleIndexVertexArray || m_forceReInstance) {
///enable welding, only for the objects that need it (such as soft bodies)
- if (0.f != m_weldingThreshold1)
- {
- btTriangleMesh* collisionMeshData = new btTriangleMesh(true,false);
+ if (0.0f != m_weldingThreshold1) {
+ btTriangleMesh *collisionMeshData = new btTriangleMesh(true, false);
collisionMeshData->m_weldingThreshold = m_weldingThreshold1;
- bool removeDuplicateVertices=true;
+ bool removeDuplicateVertices = true;
// m_vertexArray not in multiple of 3 anymore, use m_triFaceArray
- for (unsigned int i=0; i<m_triFaceArray.size(); i+=3) {
- btScalar *bt = &m_vertexArray[3*m_triFaceArray[i]];
+ for (unsigned int i = 0; i < m_triFaceArray.size(); i += 3) {
+ btScalar *bt = &m_vertexArray[3 * m_triFaceArray[i]];
btVector3 v1(bt[0], bt[1], bt[2]);
- bt = &m_vertexArray[3*m_triFaceArray[i+1]];
+ bt = &m_vertexArray[3 * m_triFaceArray[i + 1]];
btVector3 v2(bt[0], bt[1], bt[2]);
- bt = &m_vertexArray[3*m_triFaceArray[i+2]];
+ bt = &m_vertexArray[3 * m_triFaceArray[i + 2]];
btVector3 v3(bt[0], bt[1], bt[2]);
collisionMeshData->addTriangle(v1, v2, v3, removeDuplicateVertices);
}
- indexVertexArrays = collisionMeshData;
-
- } else
- {
- indexVertexArrays = new btTriangleIndexVertexArray(
+ m_triangleIndexVertexArray = collisionMeshData;
+ }
+ else {
+ m_triangleIndexVertexArray = new btTriangleIndexVertexArray(
m_polygonIndexArray.size(),
- &m_triFaceArray[0],
- 3*sizeof(int),
- m_vertexArray.size()/3,
+ m_triFaceArray.data(),
+ 3 * sizeof(int),
+ m_vertexArray.size() / 3,
&m_vertexArray[0],
- 3*sizeof(btScalar));
- }
-
- // this shape will be shared and not deleted until shapeInfo is deleted
-
- // for UpdateMesh, reuse the last memory location so instancing wont crash.
- if (m_unscaledShape) {
- DeleteBulletShape(m_unscaledShape, false);
- m_unscaledShape->~btBvhTriangleMeshShape();
- m_unscaledShape = new(m_unscaledShape) btBvhTriangleMeshShape( indexVertexArrays, true, useBvh );
- } else {
- m_unscaledShape = new btBvhTriangleMeshShape( indexVertexArrays, true, useBvh );
+ 3 * sizeof(btScalar));
}
- m_forceReInstance= false;
- } else if (useBvh && m_unscaledShape->getOptimizedBvh() == NULL) {
- // the existing unscaledShape was not build with Bvh, do it now
- m_unscaledShape->buildOptimizedBvh();
+
+ m_forceReInstance = false;
}
- collisionShape = new btScaledBvhTriangleMeshShape(m_unscaledShape, btVector3(1.0f,1.0f,1.0f));
+
+ btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(m_triangleIndexVertexArray, true, useBvh);
+ unscaledShape->setMargin(margin);
+ collisionShape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f));
collisionShape->setMargin(margin);
}
break;
@@ -2638,10 +2621,9 @@ CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
(*sit)->Release();
}
m_shapeArray.clear();
- if (m_unscaledShape)
- {
- DeleteBulletShape(m_unscaledShape, true);
- }
+
+ if (m_triangleIndexVertexArray)
+ delete m_triangleIndexVertexArray;
m_vertexArray.clear();
if (m_shapeType == PHY_SHAPE_MESH && m_meshObject != NULL)
{
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index de40624d7bb..b1d38763fbb 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -79,7 +79,7 @@ public:
m_userData(NULL),
m_refCount(1),
m_meshObject(NULL),
- m_unscaledShape(NULL),
+ m_triangleIndexVertexArray(NULL),
m_forceReInstance(false),
m_weldingThreshold1(0.f),
m_shapeProxy(NULL)
@@ -110,10 +110,11 @@ public:
void AddShape(CcdShapeConstructionInfo* shapeInfo);
- btTriangleMeshShape* GetMeshShape(void)
+ btStridingMeshInterface *GetMeshInterface()
{
- return (m_unscaledShape);
+ return m_triangleIndexVertexArray;
}
+
CcdShapeConstructionInfo* GetChildShape(int i)
{
if (i < 0 || i >= (int)m_shapeArray.size())
@@ -195,8 +196,8 @@ protected:
int m_refCount; // this class is shared between replicas
// keep track of users so that we can release it
RAS_MeshObject* m_meshObject; // Keep a pointer to the original mesh
- btBvhTriangleMeshShape* m_unscaledShape;// holds the shared unscale BVH mesh shape,
- // the actual shape is of type btScaledBvhTriangleMeshShape
+ // The list of vertexes and indexes for the triangle mesh, shared between Bullet shape.
+ btTriangleIndexVertexArray *m_triangleIndexVertexArray;
std::vector<CcdShapeConstructionInfo*> m_shapeArray; // for compound shapes
bool m_forceReInstance; //use gimpact for concave dynamic/moving collision detection
float m_weldingThreshold1; //welding closeby vertices together can improve softbody stability etc.
@@ -447,6 +448,23 @@ public:
#endif
};
+class CleanPairCallback : public btOverlapCallback
+{
+ btBroadphaseProxy *m_cleanProxy;
+ btOverlappingPairCache *m_pairCache;
+ btDispatcher *m_dispatcher;
+
+public:
+ CleanPairCallback(btBroadphaseProxy *cleanProxy, btOverlappingPairCache *pairCache, btDispatcher *dispatcher)
+ :m_cleanProxy(cleanProxy),
+ m_pairCache(pairCache),
+ m_dispatcher(dispatcher)
+ {
+ }
+
+ virtual bool processOverlap(btBroadphasePair &pair);
+};
+
///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution.
class CcdPhysicsController : public PHY_IPhysicsController
{
@@ -498,6 +516,11 @@ protected:
return (--m_registerCount == 0) ? true : false;
}
+ bool Registered() const
+ {
+ return (m_registerCount != 0);
+ }
+
void addCcdConstraintRef(btTypedConstraint* c);
void removeCcdConstraintRef(btTypedConstraint* c);
btTypedConstraint* getCcdConstraintRef(int index);
@@ -513,7 +536,15 @@ protected:
CcdPhysicsController (const CcdConstructionInfo& ci);
+ /**
+ * Delete the current Bullet shape used in the rigid body.
+ */
bool DeleteControllerShape();
+
+ /**
+ * Delete the old Bullet shape and set the new Bullet shape : newShape
+ * \param newShape The new Bullet shape to set, if is NULL we create a new Bullet shape
+ */
bool ReplaceControllerShape(btCollisionShape *newShape);
virtual ~CcdPhysicsController();
@@ -598,7 +629,7 @@ protected:
virtual void ResolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
-
+ virtual void RefreshCollisions();
virtual void SuspendDynamics(bool ghost);
virtual void RestoreDynamics();
@@ -626,8 +657,12 @@ protected:
virtual void CalcXform() {}
virtual void SetMargin(float margin)
{
- if (m_collisionShape)
- m_collisionShape->setMargin(btScalar(margin));
+ if (m_collisionShape) {
+ m_collisionShape->setMargin(margin);
+ // if the shape use a unscaled shape we have also to set the correct margin in it
+ if (m_collisionShape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
+ ((btScaledBvhTriangleMeshShape *)m_collisionShape)->getChildShape()->setMargin(margin);
+ }
}
virtual float GetMargin() const
{
@@ -712,6 +747,11 @@ protected:
return GetConstructionInfo().m_bDyna;
}
+ virtual bool IsSuspended() const
+ {
+ return m_suspended;
+ }
+
virtual bool IsCompound()
{
return GetConstructionInfo().m_shapeInfo->m_shapeType == PHY_SHAPE_COMPOUND;
@@ -719,6 +759,9 @@ protected:
virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj);
+ /* Method to replicate rigid body joint contraints for group instances. */
+ virtual void ReplicateConstraints(KX_GameObject *gameobj, std::vector<KX_GameObject*> constobj);
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:CcdPhysicsController")
#endif
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index ac74029fbe3..3670d79a01e 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -461,6 +461,19 @@ m_scalingPropagated(false)
void CcdPhysicsEnvironment::AddCcdPhysicsController(CcdPhysicsController* ctrl)
{
+ // the controller is already added we do nothing
+ if (!m_controllers.insert(ctrl).second) {
+ return;
+ }
+
+ /* In the case of compound child controller (see also RemoveCcdPhysicsController)
+ * we add the controller to the trigger controlers list : m_triggerControllers
+ * if it use collision callbacks.
+ */
+ if (ctrl->Registered()) {
+ m_triggerControllers.insert(ctrl);
+ }
+
btRigidBody* body = ctrl->GetRigidBody();
btCollisionObject* obj = ctrl->GetCollisionObject();
@@ -469,8 +482,6 @@ void CcdPhysicsEnvironment::AddCcdPhysicsController(CcdPhysicsController* ctrl)
if (body)
body->setGravity( m_gravity );
- m_controllers.insert(ctrl);
-
if (body)
{
//use explicit group/filter for finer control over collision in bullet => near/radar sensor
@@ -505,10 +516,32 @@ void CcdPhysicsEnvironment::AddCcdPhysicsController(CcdPhysicsController* ctrl)
bool CcdPhysicsEnvironment::RemoveCcdPhysicsController(CcdPhysicsController* ctrl)
{
+ // if the physics controller is already removed we do nothing
+ if (!m_controllers.erase(ctrl)) {
+ return false;
+ }
+
+ /* In the case of compound child controller which use collision callbacks
+ * we remove it from the m_triggerControllers list but leave m_registerCount
+ * to know in AddCcdPhysicsController if we have to add it in m_triggerControllers
+ * and to avoid an useless added in RequestCollisionCallback, indeed we can't register
+ * more than one time a controller.
+ */
+ if (ctrl->Registered()) {
+ m_triggerControllers.erase(ctrl);
+ }
+
//also remove constraint
btRigidBody* body = ctrl->GetRigidBody();
if (body)
{
+ btBroadphaseProxy *proxy = ctrl->GetCollisionObject()->getBroadphaseHandle();
+ btDispatcher *dispatcher = m_dynamicsWorld->getDispatcher();
+ btOverlappingPairCache *pairCache = m_dynamicsWorld->getPairCache();
+
+ CleanPairCallback cleanPairs(proxy, pairCache, dispatcher);
+ pairCache->processAllOverlappingPairs(&cleanPairs, dispatcher);
+
for (int i = ctrl->getNumCcdConstraintRefs() - 1; i >= 0; i--)
{
btTypedConstraint* con = ctrl->getCcdConstraintRef(i);
@@ -548,13 +581,8 @@ bool CcdPhysicsEnvironment::RemoveCcdPhysicsController(CcdPhysicsController* ctr
}
}
}
- if (ctrl->m_registerCount != 0)
- printf("Warning: removing controller with non-zero m_registerCount: %d\n", ctrl->m_registerCount);
-
- //remove it from the triggers
- m_triggerControllers.erase(ctrl);
- return (m_controllers.erase(ctrl) != 0);
+ return true;
}
void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
@@ -562,6 +590,7 @@ void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctr
// this function is used when the collisionning group of a controller is changed
// remove and add the collistioning object
btRigidBody* body = ctrl->GetRigidBody();
+ btSoftBody *softBody = ctrl->GetSoftBody();
btCollisionObject* obj = ctrl->GetCollisionObject();
if (obj)
{
@@ -575,6 +604,9 @@ void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctr
body->setMassProps(newMass, inertia);
m_dynamicsWorld->addRigidBody(body, newCollisionGroup, newCollisionMask);
}
+ else if (softBody) {
+ m_dynamicsWorld->addSoftBody(softBody);
+ }
else {
m_dynamicsWorld->addCollisionObject(obj, newCollisionGroup, newCollisionMask);
}
@@ -586,43 +618,6 @@ void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctr
ctrl->m_cci.m_collisionFlags = newCollisionFlags;
}
-void CcdPhysicsEnvironment::EnableCcdPhysicsController(CcdPhysicsController* ctrl)
-{
- if (m_controllers.insert(ctrl).second)
- {
- btCollisionObject* obj = ctrl->GetCollisionObject();
- obj->setUserPointer(ctrl);
- // update the position of the object from the user
- if (ctrl->GetMotionState())
- {
- btTransform xform = CcdPhysicsController::GetTransformFromMotionState(ctrl->GetMotionState());
- ctrl->SetCenterOfMassTransform(xform);
- }
- m_dynamicsWorld->addCollisionObject(obj,
- ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
- }
-}
-
-void CcdPhysicsEnvironment::DisableCcdPhysicsController(CcdPhysicsController* ctrl)
-{
- if (m_controllers.erase(ctrl))
- {
- btRigidBody* body = ctrl->GetRigidBody();
- if (body)
- {
- m_dynamicsWorld->removeRigidBody(body);
- } else
- {
- if (ctrl->GetSoftBody())
- {
- } else
- {
- m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject());
- }
- }
- }
-}
-
void CcdPhysicsEnvironment::RefreshCcdPhysicsController(CcdPhysicsController* ctrl)
{
btCollisionObject* obj = ctrl->GetCollisionObject();
@@ -636,6 +631,11 @@ void CcdPhysicsEnvironment::RefreshCcdPhysicsController(CcdPhysicsController* ct
}
}
+bool CcdPhysicsEnvironment::IsActiveCcdPhysicsController(CcdPhysicsController *ctrl)
+{
+ return (m_controllers.find(ctrl) != m_controllers.end());
+}
+
void CcdPhysicsEnvironment::AddCcdGraphicController(CcdGraphicController* ctrl)
{
if (m_cullingTree && !ctrl->GetBroadphaseHandle())
@@ -671,6 +671,19 @@ void CcdPhysicsEnvironment::RemoveCcdGraphicController(CcdGraphicController* ctr
}
}
+void CcdPhysicsEnvironment::UpdateCcdPhysicsControllerShape(CcdShapeConstructionInfo *shapeInfo)
+{
+ for (std::set<CcdPhysicsController *>::iterator it = m_controllers.begin(); it != m_controllers.end(); ++it) {
+ CcdPhysicsController *ctrl = *it;
+
+ if (ctrl->GetShapeInfo() != shapeInfo)
+ continue;
+
+ ctrl->ReplaceControllerShape(NULL);
+ RefreshCcdPhysicsController(ctrl);
+ }
+}
+
void CcdPhysicsEnvironment::BeginFrame()
{
@@ -752,8 +765,8 @@ public:
void CcdPhysicsEnvironment::ProcessFhSprings(double curTime,float interval)
{
std::set<CcdPhysicsController*>::iterator it;
- // dynamic of Fh spring is based on a timestep of 1/60
- int numIter = (int)(interval*60.0001f);
+ // Add epsilon to the tick rate for numerical stability
+ int numIter = (int)(interval*(KX_KetsjiEngine::GetTicRate() + 0.001f));
for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
@@ -1156,17 +1169,8 @@ static bool GetHitTriangle(btCollisionShape* shape, CcdShapeConstructionInfo* sh
int indexstride;
int numfaces;
PHY_ScalarType indicestype;
- btStridingMeshInterface* meshInterface = NULL;
- btTriangleMeshShape* triangleShape = shapeInfo->GetMeshShape();
+ btStridingMeshInterface* meshInterface = shapeInfo->GetMeshInterface();
- if (triangleShape)
- meshInterface = triangleShape->getMeshInterface();
- else
- {
- // other possibility is gImpact
- if (shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE)
- meshInterface = (static_cast<btGImpactMeshShape*>(shape))->getMeshInterface();
- }
if (!meshInterface)
return false;
@@ -2188,15 +2192,8 @@ btTypedConstraint* CcdPhysicsEnvironment::GetConstraintById(int constraintId)
void CcdPhysicsEnvironment::AddSensor(PHY_IPhysicsController* ctrl)
{
-
CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
- // addSensor() is a "light" function for bullet because it is used
- // dynamically when the sensor is activated. Use enableCcdPhysicsController() instead
- //if (m_controllers.insert(ctrl1).second)
- //{
- // addCcdPhysicsController(ctrl1);
- //}
- EnableCcdPhysicsController(ctrl1);
+ AddCcdPhysicsController(ctrl1);
}
bool CcdPhysicsEnvironment::RemoveCollisionCallback(PHY_IPhysicsController* ctrl)
@@ -2211,7 +2208,7 @@ bool CcdPhysicsEnvironment::RemoveCollisionCallback(PHY_IPhysicsController* ctrl
void CcdPhysicsEnvironment::RemoveSensor(PHY_IPhysicsController* ctrl)
{
- DisableCcdPhysicsController((CcdPhysicsController*)ctrl);
+ RemoveCcdPhysicsController((CcdPhysicsController*)ctrl);
}
void CcdPhysicsEnvironment::AddTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
@@ -2644,9 +2641,6 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
if (!rb0)
return 0;
- // If either of the controllers is missing, we can't do anything.
- if (!c0 || !c1) return 0;
-
btVector3 pivotInB = rb1 ? rb1->getCenterOfMassTransform().inverse()(rb0->getCenterOfMassTransform()(pivotInA)) :
rb0->getCenterOfMassTransform() * pivotInA;
btVector3 axisInA(axisX,axisY,axisZ);
@@ -2658,6 +2652,8 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
{
case PHY_POINT2POINT_CONSTRAINT:
{
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
btPoint2PointConstraint* p2p = 0;
@@ -2686,6 +2682,9 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
case PHY_GENERIC_6DOF_CONSTRAINT:
{
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
+
btGeneric6DofConstraint* genericConstraint = 0;
if (rb1)
@@ -2739,7 +2738,7 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
*rb0,s_fixedObject2,
frameInA,frameInB,useReferenceFrameA);
}
-
+
if (genericConstraint)
{
//m_constraints.push_back(genericConstraint);
@@ -2756,6 +2755,9 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
}
case PHY_CONE_TWIST_CONSTRAINT:
{
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
+
btConeTwistConstraint* coneTwistContraint = 0;
@@ -2807,7 +2809,7 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
*rb0,s_fixedObject2,
frameInA,frameInB);
}
-
+
if (coneTwistContraint)
{
//m_constraints.push_back(genericConstraint);
@@ -2830,6 +2832,9 @@ int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl
case PHY_LINEHINGE_CONSTRAINT:
{
+ // If either of the controllers is missing, we can't do anything.
+ if (!c0 || !c1) return 0;
+
btHingeConstraint* hinge = 0;
if (rb1)
@@ -3517,20 +3522,23 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
if (isbulletdyna)
gameobj->SetRecordAnimation(true);
+ physicscontroller->SetNewClientInfo(gameobj->getClientInfo());
+
// don't add automatically sensor object, they are added when a collision sensor is registered
if (!isbulletsensor && (blenderobject->lay & activeLayerBitInfo) != 0)
{
this->AddCcdPhysicsController( physicscontroller);
}
- physicscontroller->SetNewClientInfo(gameobj->getClientInfo());
+
{
btRigidBody* rbody = physicscontroller->GetRigidBody();
if (rbody)
{
+ rbody->setLinearFactor(ci.m_linearFactor);
+
if (isbulletrigidbody)
{
- rbody->setLinearFactor(ci.m_linearFactor);
rbody->setAngularFactor(ci.m_angularFactor);
}
@@ -3591,3 +3599,79 @@ void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject
}
#endif
}
+
+
+void CcdPhysicsEnvironment::SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest,
+ bRigidBodyJointConstraint *dat)
+{
+ PHY_IPhysicsController *phy_src = obj_src->GetPhysicsController();
+ PHY_IPhysicsController *phy_dest = obj_dest->GetPhysicsController();
+ PHY_IPhysicsEnvironment *phys_env = obj_src->GetScene()->GetPhysicsEnvironment();
+
+ /* We need to pass a full constraint frame, not just axis. */
+ MT_Matrix3x3 localCFrame(MT_Vector3(dat->axX,dat->axY,dat->axZ));
+ MT_Vector3 axis0 = localCFrame.getColumn(0);
+ MT_Vector3 axis1 = localCFrame.getColumn(1);
+ MT_Vector3 axis2 = localCFrame.getColumn(2);
+ MT_Vector3 scale = obj_src->NodeGetWorldScaling();
+
+ /* Apply not only the pivot and axis values, but also take scale into count
+ * this is not working well, if only one or two axis are scaled, but works ok on
+ * homogeneous scaling. */
+ int constraintId = phys_env->CreateConstraint(
+ phy_src, phy_dest, (PHY_ConstraintType)dat->type,
+ (float)(dat->pivX * scale.x()), (float)(dat->pivY * scale.y()), (float)(dat->pivZ * scale.z()),
+ (float)(axis0.x() * scale.x()), (float)(axis0.y() * scale.y()), (float)(axis0.z() * scale.z()),
+ (float)(axis1.x() * scale.x()), (float)(axis1.y() * scale.y()), (float)(axis1.z() * scale.z()),
+ (float)(axis2.x() * scale.x()), (float)(axis2.y() * scale.y()), (float)(axis2.z() * scale.z()),
+ dat->flag);
+
+ /* PHY_POINT2POINT_CONSTRAINT = 1,
+ * PHY_LINEHINGE_CONSTRAINT = 2,
+ * PHY_ANGULAR_CONSTRAINT = 3,
+ * PHY_CONE_TWIST_CONSTRAINT = 4,
+ * PHY_VEHICLE_CONSTRAINT = 11,
+ * PHY_GENERIC_6DOF_CONSTRAINT = 12 */
+
+ if (!constraintId)
+ return;
+
+ int dof = 0;
+ int dof_max = 0;
+ int dofbit = 0;
+
+ switch (dat->type) {
+ /* Set all the limits for generic 6DOF constraint. */
+ case PHY_GENERIC_6DOF_CONSTRAINT:
+ dof_max = 6;
+ dofbit = 1;
+ break;
+ /* Set XYZ angular limits for cone twist constraint. */
+ case PHY_CONE_TWIST_CONSTRAINT:
+ dof = 3;
+ dof_max = 6;
+ dofbit = 1 << 3;
+ break;
+ /* Set only X angular limits for line hinge and angular constraint. */
+ case PHY_LINEHINGE_CONSTRAINT:
+ case PHY_ANGULAR_CONSTRAINT:
+ dof = 3;
+ dof_max = 4;
+ dofbit = 1 << 3;
+ break;
+ default:
+ break;
+ }
+
+ for (; dof < dof_max; dof++) {
+ if (dat->flag & dofbit) {
+ phys_env->SetConstraintParam(constraintId, dof, dat->minLimit[dof], dat->maxLimit[dof]);
+ }
+ else {
+ /* minLimit > maxLimit means free (no limit) for this degree of freedom. */
+ phys_env->SetConstraintParam(constraintId, dof, 1.0f, -1.0f);
+ }
+ dofbit <<= 1;
+ }
+
+}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index ff8a3f4f9f9..94aea215478 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -22,6 +22,8 @@ subject to the following restrictions:
#define __CCDPHYSICSENVIRONMENT_H__
#include "PHY_IPhysicsEnvironment.h"
+#include "KX_KetsjiEngine.h"
+
#include <vector>
#include <set>
#include <map>
@@ -52,6 +54,7 @@ class btOverlappingPairCache;
class btIDebugDraw;
class PHY_IVehicle;
class CcdOverlapFilterCallBack;
+class CcdShapeConstructionInfo;
/** CcdPhysicsEnvironment is an experimental mainloop for physics simulation using optional continuous collision detection.
* Physics Environment takes care of stepping the simulation and is a container for physics entities.
@@ -131,8 +134,7 @@ protected:
virtual void SetFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep)
{
- //based on DEFAULT_PHYSICS_TIC_RATE of 60 hertz
- SetNumTimeSubSteps((int)(fixedTimeStep / 60.f));
+ SetNumTimeSubSteps((int)(fixedTimeStep / KX_KetsjiEngine::GetTicRate()));
}
//returns 0.f if no fixed timestep is used
@@ -220,16 +222,22 @@ protected:
void UpdateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
- void DisableCcdPhysicsController(CcdPhysicsController* ctrl);
-
- void EnableCcdPhysicsController(CcdPhysicsController* ctrl);
-
void RefreshCcdPhysicsController(CcdPhysicsController* ctrl);
+ bool IsActiveCcdPhysicsController(CcdPhysicsController *ctrl);
+
void AddCcdGraphicController(CcdGraphicController* ctrl);
void RemoveCcdGraphicController(CcdGraphicController* ctrl);
+ /**
+ * Update all physics controllers shape which use the same shape construction info.
+ * Call RecreateControllerShape on controllers which use the same shape
+ * construction info that argument shapeInfo.
+ * You need to call this function when the shape construction info changed.
+ */
+ void UpdateCcdPhysicsControllerShape(CcdShapeConstructionInfo *shapeInfo);
+
btBroadphaseInterface* GetBroadphase();
btDbvtBroadphase* GetCullingTree() { return m_cullingTree; }
@@ -274,6 +282,10 @@ protected:
bool isCompoundChild,
bool hasCompoundChildren);
+ /* Set the rigid body joints constraints values for converted objects and replicated group instances. */
+ virtual void SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest,
+ bRigidBodyJointConstraint *dat);
+
protected:
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h
index 1717f8d90cb..3e2337f01ea 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsController.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsController.h
@@ -32,6 +32,7 @@
#ifndef __PHY_IPHYSICSCONTROLLER_H__
#define __PHY_IPHYSICSCONTROLLER_H__
+#include <vector>
#include "PHY_IController.h"
class PHY_IMotionState;
@@ -95,6 +96,7 @@ class PHY_IPhysicsController : public PHY_IController
virtual void SetAngularDamping(float damping)=0;
virtual void SetDamping(float linear, float angular)=0;
+ virtual void RefreshCollisions() = 0;
virtual void SuspendDynamics(bool ghost=false)=0;
virtual void RestoreDynamics()=0;
@@ -132,9 +134,12 @@ class PHY_IPhysicsController : public PHY_IController
virtual bool IsDynamic() = 0;
virtual bool IsCompound() = 0;
+ virtual bool IsSuspended() const = 0;
virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj) = 0;
+ /* Method to replicate rigid body joint contraints for group instances. */
+ virtual void ReplicateConstraints(KX_GameObject *gameobj, std::vector<KX_GameObject*> constobj) = 0;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IPhysicsController")
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index dd762b02b4e..44b61136d3f 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -55,6 +55,7 @@ class KX_Scene;
struct PHY_ShapeProps;
struct PHY_MaterialProps;
class PHY_IMotionState;
+struct bRigidBodyJointConstraint;
/**
* pass back information from rayTest
@@ -213,6 +214,9 @@ class PHY_IPhysicsEnvironment
bool isCompoundChild,
bool hasCompoundChildren) = 0;
+ /* Set the rigid body joints constraints values for converted objects and replicated group instances. */
+ virtual void SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest,
+ bRigidBodyJointConstraint *dat) {}
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IPhysicsEnvironment")
diff --git a/source/gameengine/Rasterizer/RAS_ICanvas.h b/source/gameengine/Rasterizer/RAS_ICanvas.h
index d90cbea286e..471c2c97fa1 100644
--- a/source/gameengine/Rasterizer/RAS_ICanvas.h
+++ b/source/gameengine/Rasterizer/RAS_ICanvas.h
@@ -237,6 +237,8 @@ public:
const char* filename
)=0;
+ virtual void GetDisplayDimensions(int &width, int &height) = 0;
+
virtual
void
ResizeWindow(
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index d7b52213191..aadecd56992 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -297,15 +297,11 @@ public:
/**
* Fog
*/
- virtual void SetFog(float start, float dist, float r, float g, float b) = 0;
- virtual void SetFogColor(float r, float g,float b) = 0;
- virtual void SetFogStart(float start) = 0;
- virtual void SetFogEnd(float end) = 0;
+ virtual void SetFog(short type, float start, float dist, float intensity, float color[3]) = 0;
virtual void DisplayFog() = 0;
- virtual void DisableFog() = 0;
- virtual bool IsFogEnabled() = 0;
+ virtual void EnableFog(bool enable) = 0;
- virtual void SetBackColor(float red, float green, float blue, float alpha) = 0;
+ virtual void SetBackColor(float color[3]) = 0;
/**
* \param drawingmode = KX_BOUNDINGBOX, KX_WIREFRAME, KX_SOLID, KX_SHADED or KX_TEXTURED.
@@ -380,7 +376,7 @@ public:
*/
virtual void SetEmissive(float eX, float eY, float eZ, float e) = 0;
- virtual void SetAmbientColor(float red, float green, float blue) = 0;
+ virtual void SetAmbientColor(float color[3]) = 0;
virtual void SetAmbient(float factor) = 0;
/**
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
index b3da5e1f812..34184f73953 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
@@ -79,10 +79,6 @@ void RAS_ListSlot::RemoveList()
void RAS_ListSlot::DrawList()
{
- if (m_flag &LIST_STREAM || m_flag& LIST_NOCREATE) {
- RemoveList();
- return;
- }
if (m_flag &LIST_MODIFY) {
if (m_flag &LIST_CREATE) {
if (m_list == 0) {
@@ -115,7 +111,7 @@ void RAS_ListSlot::SetModified(bool mod)
if (mod && !(m_flag & LIST_MODIFY)) {
spit("Modifying list (" << m_list << ")");
m_flag = m_flag &~ LIST_END;
- m_flag |= LIST_STREAM;
+ m_flag |= LIST_MODIFY;
}
}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
index d394c72b2a2..5e1c662bc17 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
@@ -35,12 +35,9 @@ public:
enum RAS_ListSlotFlags {
LIST_CREATE =1,
LIST_MODIFY =2,
- LIST_STREAM =4,
- LIST_NOCREATE =8,
- LIST_BEGIN =16,
- LIST_END =32,
- LIST_REGEN =64,
- LIST_DERIVEDMESH=128,
+ LIST_BEGIN =4,
+ LIST_END =8,
+ LIST_DERIVEDMESH=16,
};
struct DerivedMesh;
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 116a11339d9..95c153a7e2a 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -194,113 +194,52 @@ bool RAS_OpenGLRasterizer::Init()
}
-void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
+void RAS_OpenGLRasterizer::SetAmbientColor(float color[3])
{
- m_ambr = red;
- m_ambg = green;
- m_ambb = blue;
+ m_ambr = color[0];
+ m_ambg = color[1];
+ m_ambb = color[2];
}
-
void RAS_OpenGLRasterizer::SetAmbient(float factor)
{
- float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
+ float ambient[] = {m_ambr * factor, m_ambg * factor, m_ambb * factor, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
}
-
-void RAS_OpenGLRasterizer::SetBackColor(float red,
- float green,
- float blue,
- float alpha)
-{
- m_redback = red;
- m_greenback = green;
- m_blueback = blue;
- m_alphaback = alpha;
-}
-
-
-
-void RAS_OpenGLRasterizer::SetFogColor(float r,
- float g,
- float b)
-{
- m_fogr = r;
- m_fogg = g;
- m_fogb = b;
- m_fogenabled = true;
-}
-
-
-
-void RAS_OpenGLRasterizer::SetFogStart(float start)
+void RAS_OpenGLRasterizer::SetBackColor(float color[3])
{
- m_fogstart = start;
- m_fogenabled = true;
+ m_redback = color[0];
+ m_greenback = color[1];
+ m_blueback = color[2];
+ m_alphaback = 1.0f;
}
-
-
-void RAS_OpenGLRasterizer::SetFogEnd(float fogend)
+void RAS_OpenGLRasterizer::SetFog(short type, float start, float dist, float intensity, float color[3])
{
- m_fogdist = fogend;
- m_fogenabled = true;
+ float params[4] = {color[0], color[1], color[2], 1.0f};
+ glFogi(GL_FOG_MODE, GL_LINEAR);
+ glFogf(GL_FOG_DENSITY, intensity / 10.0f);
+ glFogf(GL_FOG_START, start);
+ glFogf(GL_FOG_END, start + dist);
+ glFogfv(GL_FOG_COLOR, params);
}
-
-
-void RAS_OpenGLRasterizer::SetFog(float start,
- float dist,
- float r,
- float g,
- float b)
+void RAS_OpenGLRasterizer::EnableFog(bool enable)
{
- m_fogstart = start;
- m_fogdist = dist;
- m_fogr = r;
- m_fogg = g;
- m_fogb = b;
- m_fogenabled = true;
+ m_fogenabled = enable;
}
-
-
-void RAS_OpenGLRasterizer::DisableFog()
-{
- m_fogenabled = false;
-}
-
-bool RAS_OpenGLRasterizer::IsFogEnabled()
-{
- return m_fogenabled;
-}
-
-
void RAS_OpenGLRasterizer::DisplayFog()
{
- if ((m_drawingmode >= KX_SOLID) && m_fogenabled)
- {
- float params[5];
- glFogi(GL_FOG_MODE, GL_LINEAR);
- glFogf(GL_FOG_DENSITY, 0.1f);
- glFogf(GL_FOG_START, m_fogstart);
- glFogf(GL_FOG_END, m_fogstart + m_fogdist);
- params[0] = m_fogr;
- params[1] = m_fogg;
- params[2] = m_fogb;
- params[3] = 0.0;
- glFogfv(GL_FOG_COLOR, params);
+ if ((m_drawingmode >= KX_SOLID) && m_fogenabled) {
glEnable(GL_FOG);
- }
- else
- {
+ }
+ else {
glDisable(GL_FOG);
}
}
-
-
bool RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
{
return mat.Activate(this, m_materialCachingInfo);
@@ -1135,12 +1074,17 @@ void RAS_OpenGLRasterizer::SetMipmapping(MipmapOption val)
RAS_IRasterizer::MipmapOption RAS_OpenGLRasterizer::GetMipmapping()
{
- if (GPU_get_linear_mipmap())
- return RAS_IRasterizer::RAS_MIPMAP_LINEAR;
- else if (GPU_get_mipmap())
- return RAS_IRasterizer::RAS_MIPMAP_NEAREST;
- else
+ if (GPU_get_mipmap()) {
+ if (GPU_get_linear_mipmap()) {
+ return RAS_IRasterizer::RAS_MIPMAP_LINEAR;
+ }
+ else {
+ return RAS_IRasterizer::RAS_MIPMAP_NEAREST;
+ }
+ }
+ else {
return RAS_IRasterizer::RAS_MIPMAP_NONE;
+ }
}
void RAS_OpenGLRasterizer::SetUsingOverrideShader(bool val)
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index 1334ddb2a26..b034315e3d6 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -80,12 +80,7 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
/* fogging vars */
bool m_fogenabled;
- float m_fogstart;
- float m_fogdist;
- float m_fogr;
- float m_fogg;
- float m_fogb;
-
+
float m_redback;
float m_greenback;
float m_blueback;
@@ -198,16 +193,12 @@ public:
virtual const MT_Point3& GetCameraPosition();
virtual bool GetCameraOrtho();
- virtual void SetFog(float start, float dist, float r, float g, float b);
- virtual void SetFogColor(float r, float g, float b);
- virtual void SetFogStart(float fogstart);
- virtual void SetFogEnd(float fogend);
- void DisableFog();
+ virtual void SetFog(short type, float start, float dist, float intensity, float color[3]);
+ virtual void EnableFog(bool enable);
virtual void DisplayFog();
- virtual bool IsFogEnabled();
- virtual void SetBackColor(float red, float green, float blue, float alpha);
-
+ virtual void SetBackColor(float color[3]);
+
virtual void SetDrawingMode(int drawingmode);
virtual int GetDrawingMode();
@@ -227,7 +218,7 @@ public:
virtual void SetDiffuse(float difX, float difY, float difZ, float diffuse);
virtual void SetEmissive(float eX, float eY, float eZ, float e);
- virtual void SetAmbientColor(float red, float green, float blue);
+ virtual void SetAmbientColor(float color[3]);
virtual void SetAmbient(float factor);
virtual void SetPolygonOffset(float mult, float add);
diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp
index 57b2e85845c..2b2a6e0778b 100644
--- a/source/gameengine/VideoTexture/ImageRender.cpp
+++ b/source/gameengine/VideoTexture/ImageRender.cpp
@@ -75,8 +75,8 @@ ImageRender::ImageRender (KX_Scene *scene, KX_Camera * camera) :
m_mirrorHalfWidth(0.f),
m_mirrorHalfHeight(0.f)
{
- // initialize background color
- setBackground(0, 0, 255, 255);
+ // initialize background color to scene background color as default
+ setBackgroundFromScene(m_scene);
// retrieve rendering objects
m_engine = KX_GetActiveEngine();
m_rasterizer = m_engine->GetRasterizer();
@@ -100,6 +100,18 @@ void ImageRender::setBackground (int red, int green, int blue, int alpha)
m_background[3] = (alpha < 0) ? 0.f : (alpha > 255) ? 1.f : float(alpha)/255.f;
}
+// set background color from scene
+void ImageRender::setBackgroundFromScene (KX_Scene *scene)
+{
+ if (scene) {
+ const float *background_color = scene->GetWorldInfo()->getBackColor();
+ setBackground((int) (background_color[0] * 255.0f), (int) (background_color[1] * 255.0f), (int) (background_color[2] * 255.0f), 255);
+ }
+ else {
+ setBackground(0, 0, 255, 255);
+ }
+}
+
// capture image from viewport
void ImageRender::calcImage (unsigned int texId, double ts)
@@ -200,7 +212,7 @@ void ImageRender::Render()
m_canvas->ClearColor(m_background[0], m_background[1], m_background[2], m_background[3]);
m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
m_rasterizer->BeginFrame(m_engine->GetClockTime());
- m_engine->SetWorldSettings(m_scene->GetWorldInfo());
+ m_scene->GetWorldInfo()->UpdateWorldSettings();
m_rasterizer->SetAuxilaryClientInfo(m_scene);
m_rasterizer->DisplayFog();
// matrix calculation, don't apply any of the stereo mode
@@ -272,6 +284,12 @@ void ImageRender::Render()
// restore the stereo mode now that the matrix is computed
m_rasterizer->SetStereoMode(stereomode);
+ if (stereomode == RAS_IRasterizer::RAS_STEREO_QUADBUFFERED) {
+ // In QUAD buffer stereo mode, the GE render pass ends with the right eye on the right buffer
+ // but we need to draw on the left buffer to capture the render
+ // TODO: implement an explicit function in rasterizer to restore the left buffer.
+ m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE);
+ }
m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
m_scene->RenderBuckets(camtrans, m_rasterizer);
@@ -727,7 +745,8 @@ ImageRender::ImageRender (KX_Scene *scene, KX_GameObject *observer, KX_GameObjec
m_mirrorX = m_mirrorY.cross(m_mirrorZ);
m_render = true;
- setBackground(0, 0, 255, 255);
+ // set mirror background color to scene background color as default
+ setBackgroundFromScene(m_scene);
}
diff --git a/source/gameengine/VideoTexture/ImageRender.h b/source/gameengine/VideoTexture/ImageRender.h
index 98dceeaafe1..bdf442c82d0 100644
--- a/source/gameengine/VideoTexture/ImageRender.h
+++ b/source/gameengine/VideoTexture/ImageRender.h
@@ -100,7 +100,7 @@ protected:
void Render();
void SetupRenderFrame(KX_Scene *scene, KX_Camera* cam);
void RenderFrame(KX_Scene* scene, KX_Camera* cam);
- void SetBackGround(KX_WorldInfo* wi);
+ void setBackgroundFromScene(KX_Scene *scene);
void SetWorldSettings(KX_WorldInfo* wi);
};
diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp
index 9640c5544da..c31faf5a463 100644
--- a/source/gameengine/VideoTexture/Texture.cpp
+++ b/source/gameengine/VideoTexture/Texture.cpp
@@ -79,9 +79,21 @@ void loadTexture(unsigned int texId, unsigned int *texture, short *size,
glBindTexture(GL_TEXTURE_2D, texId);
if (mipmap)
{
+ int i;
+ ImBuf *ibuf;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, texture);
+
+ ibuf = IMB_allocFromBuffer(texture, NULL, size[0], size[1]);
+
+ IMB_makemipmap(ibuf, true);
+
+ for (i = 0; i < ibuf->miptot; i++) {
+ ImBuf *mip = IMB_getmipmap(ibuf, i);
+
+ glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, mip->x, mip->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip->rect);
+ }
+ IMB_freeImBuf(ibuf);
}
else
{