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:
authorDaniel Genrich <daniel.genrich@gmx.net>2008-07-20 12:52:48 +0400
committerDaniel Genrich <daniel.genrich@gmx.net>2008-07-20 12:52:48 +0400
commit037f1188e63c1b8b05d9421ee8f6395bcb3f1ab7 (patch)
treec9476e0daa75e0e4dbd8cfc9035f851067d4ea29
parentb369936b1168984b37b04d4d78184ce59442de9e (diff)
parenta8785893c5657592c9cc27ce844664b5d62397de (diff)
svn merge -r 15529:15649 https://svn.blender.org/svnroot/bf-blender/trunk/blender
-rw-r--r--CMakeLists.txt27
-rw-r--r--README14
-rw-r--r--intern/bsp/intern/BSP_CSGMesh.cpp2
-rw-r--r--intern/container/CTR_TaggedIndex.h16
-rw-r--r--intern/decimation/intern/LOD_ManMesh2.cpp6
-rw-r--r--intern/elbeem/intern/controlparticles.cpp2
-rw-r--r--intern/elbeem/intern/solver_init.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp8
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp8
-rw-r--r--projectfiles_vc7/blender/src/BL_src.vcproj4
-rw-r--r--projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj8
-rw-r--r--source/blender/blenkernel/intern/pointcache.c16
-rw-r--r--source/blender/blenlib/intern/arithb.c252
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp2
-rw-r--r--source/blender/include/BIF_editaction.h2
-rw-r--r--source/blender/include/BIF_resources.h3
-rw-r--r--source/blender/include/blendef.h6
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h4
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h1
-rw-r--r--source/blender/python/api2_2x/Library.c69
-rw-r--r--source/blender/python/api2_2x/doc/LibData.py42
-rw-r--r--source/blender/python/api2_2x/doc/Render.py4
-rw-r--r--source/blender/python/api2_2x/sceneRender.c2
-rw-r--r--source/blender/render/intern/source/rendercore.c27
-rw-r--r--source/blender/render/intern/source/zbuf.c24
-rw-r--r--source/blender/src/buttons_editing.c54
-rw-r--r--source/blender/src/buttons_logic.c6
-rw-r--r--source/blender/src/buttons_scene.c72
-rw-r--r--source/blender/src/drawaction.c107
-rw-r--r--source/blender/src/editaction.c108
-rw-r--r--source/blender/src/editmesh.c11
-rw-r--r--source/blender/src/editobject.c1
-rw-r--r--source/blender/src/editsound.c2
-rw-r--r--source/blender/src/interface.c4
-rw-r--r--source/blender/src/poselib.c18
-rw-r--r--source/blender/src/resources.c28
-rw-r--r--source/blender/src/space.c4
-rw-r--r--source/blender/src/transform_conversions.c2
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp11
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp4
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp243
-rw-r--r--source/gameengine/Converter/BL_DeformableGameObject.h1
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.cpp7
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp48
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h6
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp6
-rw-r--r--source/gameengine/Expressions/Value.cpp15
-rw-r--r--source/gameengine/Expressions/Value.h1
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp12
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h6
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h3
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp2
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.cpp33
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.h8
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp14
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp4
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.h2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp32
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.h7
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp62
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.h8
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp28
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h8
-rw-r--r--source/gameengine/Ketsji/KX_IPhysicsController.h2
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_OdePhysicsController.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_OdePhysicsController.h2
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp51
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.h7
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp13
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.h1
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp9
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp50
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h13
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp270
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h16
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.cpp45
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.h3
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp3
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_SumoPhysicsController.h2
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.h1
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp10
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h2
-rw-r--r--source/gameengine/Rasterizer/CMakeLists.txt2
-rw-r--r--source/gameengine/Rasterizer/Makefile3
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp186
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.h24
-rw-r--r--source/gameengine/Rasterizer/RAS_IRenderTools.h2
-rw-r--r--source/gameengine/Rasterizer/SConscript3
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.cpp6
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.h2
-rw-r--r--source/gameengine/SceneGraph/SG_Node.cpp29
-rw-r--r--source/gameengine/SceneGraph/SG_Node.h2
99 files changed, 1706 insertions, 626 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b58fe945663..5a23e77d9f8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -197,10 +197,17 @@ IF(UNIX)
ENDIF(UNIX)
IF(WIN32)
- INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake)
+ INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake)
+
SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows)
+ # Setup 64bit and 64bit windows systems
+ IF(CMAKE_CL_64)
+ message("64 bit compiler detected.")
+ SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/win64)
+ ENDIF(CMAKE_CL_64)
+
SET(PYTHON ${LIBDIR}/python)
SET(PYTHON_VERSION 2.5)
SET(PYTHON_INC "${PYTHON}/include/python${PYTHON_VERSION}")
@@ -214,12 +221,20 @@ IF(WIN32)
SET(OPENAL_LIB openal_static)
SET(OPENAL_LIBPATH ${OPENAL}/lib)
- SET(PNG_LIB libpng_st)
+ IF(CMAKE_CL_64)
+ SET(PNG_LIB libpng)
+ ELSE(CMAKE_CL_64)
+ SET(PNG_LIB libpng_st)
+ ENDIF(CMAKE_CL_64)
SET(JPEG_LIB libjpeg)
SET(ZLIB ${LIBDIR}/zlib)
SET(ZLIB_INC ${ZLIB}/include)
- SET(ZLIB_LIB libz)
+ IF(CMAKE_CL_64)
+ SET(ZLIB_LIB zlib)
+ ELSE(CMAKE_CL_64)
+ SET(ZLIB_LIB libz)
+ ENDIF(CMAKE_CL_64)
SET(ZLIB_LIBPATH ${ZLIB}/lib)
SET(PTHREADS ${LIBDIR}/pthreads)
@@ -302,7 +317,11 @@ IF(WIN32)
SET(WINTAB_INC ${LIBDIR}/wintab/include)
- SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib")
+ IF(CMAKE_CL_64)
+ SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib;MSVCRT.lib ")
+ ELSE(CMAKE_CL_64)
+ SET(PLATFORM_LINKFLAGS "/NODEFAULTLIB:libc.lib ")
+ ENDIF(CMAKE_CL_64)
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib;libc.lib ")
ENDIF(WIN32)
diff --git a/README b/README
index d123a90ba48..1a7964f954e 100644
--- a/README
+++ b/README
@@ -24,22 +24,22 @@ dir to one of these locations (your home directory being recommended).
-------------------------------------Links--------------------------------------
Getting Involved:
-http://www.blender.org/docs/get_involved.html
+http://www.blender.org/community/get-involved
Community:
-http://www.blender3d.org/Community/
+http://www.blender.org/Community
Main blender development site:
-http://www.blender.org/
+http://www.blender.org
The Blender project homepage:
-http://projects.blender.org/projects/bf-blender/
+http://projects.blender.org/projects/bf-blender
Documentation:
-http://www.blender.org/modules.php?op=modload&name=documentation&file=index
+http://www.blender.org/education-help
Bug tracker:
-http://projects.blender.org/tracker/?atid=125&group_id=9&func=browse
+http://www.blender.org/development/report-a-bug
Feature request tracker:
-http://projects.blender.org/tracker/?atid=128&group_id=9&func=browse
+http://wiki.blender.org/index.php/Requests
diff --git a/intern/bsp/intern/BSP_CSGMesh.cpp b/intern/bsp/intern/BSP_CSGMesh.cpp
index 553f39a4642..ca7795b3cf5 100644
--- a/intern/bsp/intern/BSP_CSGMesh.cpp
+++ b/intern/bsp/intern/BSP_CSGMesh.cpp
@@ -197,7 +197,7 @@ BuildEdges(
for (int vert = 0; vert < vertex_num; ++vert) {
- BSP_FaceInd fi(f_it - f_it_begin);
+ BSP_FaceInd fi(size_t (f_it - f_it_begin));
InsertEdge(prev_vi,face.m_verts[vert],fi,dummy);
prev_vi = face.m_verts[vert];
}
diff --git a/intern/container/CTR_TaggedIndex.h b/intern/container/CTR_TaggedIndex.h
index 7a7bd85e890..68d2536c879 100644
--- a/intern/container/CTR_TaggedIndex.h
+++ b/intern/container/CTR_TaggedIndex.h
@@ -93,6 +93,16 @@ public:
}
+#if defined(_WIN64)
+ CTR_TaggedIndex(
+ const unsigned __int64 val
+ ) :
+ m_val ( ((unsigned __int64)val & index_mask)
+ | ( (empty_tag << tag_shift)
+ & (~index_mask) ) ) {
+ }
+#endif
+
CTR_TaggedIndex(
const CTR_TaggedIndex &my_index
):
@@ -124,6 +134,12 @@ public:
return (long int)(m_val & index_mask);
}
+#if defined(_WIN64)
+ operator unsigned __int64 () const {
+ return (unsigned __int64)(m_val & index_mask);
+ }
+#endif
+
bool
IsEmpty(
) const {
diff --git a/intern/decimation/intern/LOD_ManMesh2.cpp b/intern/decimation/intern/LOD_ManMesh2.cpp
index eeb497bb09e..2fe49b36583 100644
--- a/intern/decimation/intern/LOD_ManMesh2.cpp
+++ b/intern/decimation/intern/LOD_ManMesh2.cpp
@@ -477,7 +477,7 @@ DeleteVertex(
return;
}
- LOD_VertexInd last = LOD_VertexInd(verts.end() - verts.begin() - 1);
+ LOD_VertexInd last = LOD_VertexInd(size_t(verts.end() - verts.begin() - 1));
if (!(last == v)) {
@@ -533,7 +533,7 @@ DeleteEdge(
return;
}
- LOD_EdgeInd last = LOD_EdgeInd(edges.end() - edges.begin() - 1);
+ LOD_EdgeInd last = LOD_EdgeInd(size_t(edges.end() - edges.begin() - 1));
if (!(last == e)) {
vector<LOD_EdgeInd> e_verts;
@@ -573,7 +573,7 @@ DeleteFace(
return;
}
- LOD_FaceInd last = LOD_FaceInd(faces.end() - faces.begin() - 1);
+ LOD_FaceInd last = LOD_FaceInd(size_t (faces.end() - faces.begin() - 1));
if (!(last == f)) {
diff --git a/intern/elbeem/intern/controlparticles.cpp b/intern/elbeem/intern/controlparticles.cpp
index 70a94bb2d1a..75b7e9bfd80 100644
--- a/intern/elbeem/intern/controlparticles.cpp
+++ b/intern/elbeem/intern/controlparticles.cpp
@@ -177,8 +177,6 @@ int ControlParticles::initFromObject(ntlGeometryObjModel *model) {
}
model->setGeoInitType(FGI_CONTROL);
-
- initTime(mCPSTimeStart , mCPSTimeEnd);
delete tree;
delete genscene;
diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp
index fd7a0b6be2c..b1222d48ce5 100644
--- a/intern/elbeem/intern/solver_init.cpp
+++ b/intern/elbeem/intern/solver_init.cpp
@@ -704,7 +704,7 @@ bool LbmFsgrSolver::initializeSolverMemory()
//std::cerr<<" memEstFine "<< memEstFine <<" maxWin:" <<maxWinMemChunk <<" maxMac:" <<maxMacMemChunk ; // DEBUG
#ifdef WIN32
double maxWinMemChunk = 1100.*1024.*1024.;
- if(memEstFine> maxWinMemChunk) {
+ if(sizeof(void *)==4 && memEstFine>maxWinMemChunk) {
memBlockAllocProblem = true;
}
#endif // WIN32
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 293f8fc1661..f5c7c08ebfe 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -42,6 +42,14 @@
#include "GHOST_SystemWin32.h"
+// win64 doesn't define GWL_USERDATA
+#ifdef WIN32
+#ifndef GWL_USERDATA
+#define GWL_USERDATA GWLP_USERDATA
+#define GWL_WNDPROC GWLP_WNDPROC
+#endif
+#endif
+
/*
* According to the docs the mouse wheel message is supported from windows 98
* upwards. Leaving WINVER at default value, the WM_MOUSEWHEEL message and the
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 905b2f7ac63..fef58d071a4 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -48,6 +48,14 @@
#define M_PI 3.1415926536
#endif
+// win64 doesn't define GWL_USERDATA
+#ifdef WIN32
+#ifndef GWL_USERDATA
+#define GWL_USERDATA GWLP_USERDATA
+#define GWL_WNDPROC GWLP_WNDPROC
+#endif
+#endif
+
LPCSTR GHOST_WindowWin32::s_windowClassName = "GHOST_WindowClass";
const int GHOST_WindowWin32::s_maxTitleLength = 128;
HGLRC GHOST_WindowWin32::s_firsthGLRc = NULL;
diff --git a/projectfiles_vc7/blender/src/BL_src.vcproj b/projectfiles_vc7/blender/src/BL_src.vcproj
index 6f91aeed8b5..226bedbbfd8 100644
--- a/projectfiles_vc7/blender/src/BL_src.vcproj
+++ b/projectfiles_vc7/blender/src/BL_src.vcproj
@@ -21,7 +21,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER=1;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET=1;WITH_FFMPEG"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -73,7 +73,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\sdl\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\build\msvc_7\intern\bsp\include;..\..\..\..\build\msvc_7\intern\ghost\include;..\..\..\..\build\msvc_7\intern\elbeem\include;..\..\..\..\build\msvc_7\intern\opennl\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\blenkey\include;..\..\..\..\build\msvc_7\intern\decimation\include;..\..\..\..\build\msvc_7\intern\memutil\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\source\blender;..\..\..\source\blender\img;..\..\..\source\blender\verify;..\..\..\source\blender\ftfont;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\include;..\..\..\source\blender\renderui;..\..\..\source\blender\blenloader;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\nodes;..\..\..\source\blender\blenpluginapi;..\..\..\source\blender\renderconverter;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include;..\..\..\source\blender\radiosity\extern\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\network;..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\build\msvc_7\extern\verse\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\build\msvc_7\extern\glew\include"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;_CONSOLE;GAMEBLENDER;WITH_QUICKTIME;INTERNATIONAL;WITH_VERSE;WITH_OPENEXR;WITH_DDS;WITH_BULLET = 1;WITH_FFMPEG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
diff --git a/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj b/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj
index 31520b06546..9d55a7712fc 100644
--- a/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj
+++ b/projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj
@@ -21,7 +21,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -125,7 +125,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
StringPooling="TRUE"
RuntimeLibrary="0"
@@ -229,7 +229,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -281,7 +281,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system"
+ AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\extern\glew\include;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\Expressions;..\..\..\..\lib\windows\python\include\python2.5"
PreprocessorDefinitions="NDEBUG;WIN32;_LIB;WITH_GLEXT"
StringPooling="TRUE"
RuntimeLibrary="0"
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 57ecffbb796..43805959e62 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -459,9 +459,10 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
PTCacheID pid;
ParticleSystem *psys;
ModifierData *md;
- int reset;
+ int reset, skip;
reset= 0;
+ skip= 0;
if(ob->soft) {
BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
@@ -469,11 +470,18 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- BKE_ptcache_id_from_particles(&pid, ob, psys);
- reset |= BKE_ptcache_id_reset(&pid, mode);
-
+ /* Baked softbody hair has to be checked first, because we don't want to reset */
+ /* particles or softbody in that case -jahka */
if(psys->soft) {
BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
+ if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED)))
+ reset |= BKE_ptcache_id_reset(&pid, mode);
+ else
+ skip = 1;
+ }
+
+ if(skip == 0) {
+ BKE_ptcache_id_from_particles(&pid, ob, psys);
reset |= BKE_ptcache_id_reset(&pid, mode);
}
}
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index c97ca3c6a8a..b7598ec0c4d 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -60,6 +60,7 @@
#define SMALL_NUMBER 1.e-8
#define ABS(x) ((x) < 0 ? -(x) : (x))
#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
+#define CLAMP(a, b, c) if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c)
#if defined(WIN32) || defined(__APPLE__)
@@ -3800,12 +3801,50 @@ int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], flo
/* Adapted from the paper by Kasper Fauerby */
/* "Improved Collision detection and Response" */
+static int getLowestRoot(float a, float b, float c, float maxR, float* root)
+{
+ // Check if a solution exists
+ float determinant = b*b - 4.0f*a*c;
+
+ // If determinant is negative it means no solutions.
+ if (determinant >= 0.0f)
+ {
+ // calculate the two roots: (if determinant == 0 then
+ // x1==x2 but let’s disregard that slight optimization)
+ float sqrtD = sqrt(determinant);
+ float r1 = (-b - sqrtD) / (2.0f*a);
+ float r2 = (-b + sqrtD) / (2.0f*a);
+
+ // Sort so x1 <= x2
+ if (r1 > r2)
+ SWAP( float, r1, r2);
+
+ // Get lowest root:
+ if (r1 > 0.0f && r1 < maxR)
+ {
+ *root = r1;
+ return 1;
+ }
+
+ // It is possible that we want x2 - this can happen
+ // if x1 < 0
+ if (r2 > 0.0f && r2 < maxR)
+ {
+ *root = r2;
+ return 1;
+ }
+ }
+ // No (valid) solutions
+ return 0;
+}
+
int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint)
{
float e1[3], e2[3], e3[3], point[3], vel[3], /*dist[3],*/ nor[3], temp[3], bv[3];
- float a, b, c, d, e, x, y, z, t, t0, t1, radius2=radius*radius;
+ float a, b, c, d, e, x, y, z, radius2=radius*radius;
float elen2,edotv,edotbv,nordotv,vel2;
- int embedded_in_plane=0, found_by_sweep=0;
+ float newLambda;
+ int found_by_sweep=0;
VecSubf(e1,v1,v0);
VecSubf(e2,v2,v0);
@@ -3814,44 +3853,41 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
/*---test plane of tri---*/
Crossf(nor,e1,e2);
Normalize(nor);
+
/* flip normal */
if(Inpf(nor,vel)>0.0f) VecMulf(nor,-1.0f);
a=Inpf(p1,nor)-Inpf(v0,nor);
-
nordotv=Inpf(nor,vel);
- if ((nordotv > -0.000001) && (nordotv < 0.000001)) {
- if(fabs(a)>=1.0f)
+ if (fabs(nordotv) < 0.000001)
+ {
+ if(fabs(a)>=radius)
+ {
return 0;
- else{
- embedded_in_plane=1;
- t0=0.0f;
- t1=1.0f;
}
}
- else{
- t0=(radius-a)/nordotv;
- t1=(-radius-a)/nordotv;
- /* make t0<t1 */
- if(t0>t1){b=t1; t1=t0; t0=b;}
+ else
+ {
+ float t0=(-a+radius)/nordotv;
+ float t1=(-a-radius)/nordotv;
+
+ if(t0>t1)
+ SWAP(float, t0, t1);
if(t0>1.0f || t1<0.0f) return 0;
/* clamp to [0,1] */
- t0=(t0<0.0f)?0.0f:((t0>1.0f)?1.0:t0);
- t1=(t1<0.0f)?0.0f:((t1>1.0f)?1.0:t1);
- }
+ CLAMP(t0, 0.0f, 1.0f);
+ CLAMP(t1, 0.0f, 1.0f);
-/*---test inside of tri---*/
- if(embedded_in_plane==0){
+ /*---test inside of tri---*/
/* plane intersection point */
- VecCopyf(point,vel);
- VecMulf(point,t0);
- VecAddf(point,point,p1);
- VecCopyf(temp,nor);
- VecMulf(temp,radius);
- VecSubf(point,point,temp);
+
+ point[0] = p1[0] + vel[0]*t0 - nor[0]*radius;
+ point[1] = p1[1] + vel[1]*t0 - nor[1]*radius;
+ point[2] = p1[2] + vel[2]*t0 - nor[2]*radius;
+
/* is the point in the tri? */
a=Inpf(e1,e1);
@@ -3866,14 +3902,19 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
y=e*a-d*b;
z=x+y-(a*c-b*b);
- if(( ((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y)) ) & 0x80000000){
+
+ if( z <= 0.0f && (x >= 0.0f && y >= 0.0f))
+ {
+ //( ((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y)) ) & 0x80000000){
*lambda=t0;
VecCopyf(ipoint,point);
return 1;
}
}
+
*lambda=1.0f;
+
/*---test points---*/
a=vel2=Inpf(vel,vel);
@@ -3881,73 +3922,42 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
VecSubf(temp,p1,v0);
b=2.0f*Inpf(vel,temp);
c=Inpf(temp,temp)-radius2;
- d=b*b-4*a*c;
-
- if(d>=0.0f){
- if(d==0.0f)
- t=-b/2*a;
- else{
- z=sqrt(d);
- x=(-b-z)*0.5/a;
- y=(-b+z)*0.5/a;
- t=x<y?x:y;
- }
- if(t>0.0 && t < *lambda){
- *lambda=t;
- VecCopyf(ipoint,v0);
- found_by_sweep=1;
- }
+ if(getLowestRoot(a, b, c, *lambda, lambda))
+ {
+ VecCopyf(ipoint,v0);
+ found_by_sweep=1;
}
/*v1*/
VecSubf(temp,p1,v1);
b=2.0f*Inpf(vel,temp);
c=Inpf(temp,temp)-radius2;
- d=b*b-4*a*c;
-
- if(d>=0.0f){
- if(d==0.0f)
- t=-b/2*a;
- else{
- z=sqrt(d);
- x=(-b-z)*0.5/a;
- y=(-b+z)*0.5/a;
- t=x<y?x:y;
- }
- if(t>0.0 && t < *lambda){
- *lambda=t;
- VecCopyf(ipoint,v1);
- found_by_sweep=1;
- }
+ if(getLowestRoot(a, b, c, *lambda, lambda))
+ {
+ VecCopyf(ipoint,v1);
+ found_by_sweep=1;
}
+
/*v2*/
VecSubf(temp,p1,v2);
b=2.0f*Inpf(vel,temp);
c=Inpf(temp,temp)-radius2;
- d=b*b-4*a*c;
-
- if(d>=0.0f){
- if(d==0.0f)
- t=-b/2*a;
- else{
- z=sqrt(d);
- x=(-b-z)*0.5/a;
- y=(-b+z)*0.5/a;
- t=x<y?x:y;
- }
- if(t>0.0 && t < *lambda){
- *lambda=t;
- VecCopyf(ipoint,v2);
- found_by_sweep=1;
- }
+ if(getLowestRoot(a, b, c, *lambda, lambda))
+ {
+ VecCopyf(ipoint,v2);
+ found_by_sweep=1;
}
/*---test edges---*/
+ VecSubf(e3,v2,v1); //wasnt yet calculated
+
+
/*e1*/
VecSubf(bv,v0,p1);
+
elen2 = Inpf(e1,e1);
edotv = Inpf(e1,vel);
edotbv = Inpf(e1,bv);
@@ -3955,27 +3965,18 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
a=elen2*(-Inpf(vel,vel))+edotv*edotv;
b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
- d=b*b-4*a*c;
- if(d>=0.0f){
- if(d==0.0f)
- t=-b/2*a;
- else{
- z=sqrt(d);
- x=(-b-z)*0.5/a;
- y=(-b+z)*0.5/a;
- t=x<y?x:y;
- }
- e=(edotv*t-edotbv)/elen2;
+ if(getLowestRoot(a, b, c, *lambda, &newLambda))
+ {
+ e=(edotv*newLambda-edotbv)/elen2;
- if((e>=0.0f) && (e<=1.0f)){
- if(t>0.0 && t < *lambda){
- *lambda=t;
- VecCopyf(ipoint,e1);
- VecMulf(ipoint,e);
- VecAddf(ipoint,ipoint,v0);
- found_by_sweep=1;
- }
+ if(e >= 0.0f && e <= 1.0f)
+ {
+ *lambda = newLambda;
+ VecCopyf(ipoint,e1);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v0);
+ found_by_sweep=1;
}
}
@@ -3988,32 +3989,27 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
a=elen2*(-Inpf(vel,vel))+edotv*edotv;
b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
- d=b*b-4*a*c;
- if(d>=0.0f){
- if(d==0.0f)
- t=-b/2*a;
- else{
- z=sqrt(d);
- x=(-b-z)*0.5/a;
- y=(-b+z)*0.5/a;
- t=x<y?x:y;
- }
- e=(edotv*t-edotbv)/elen2;
+ if(getLowestRoot(a, b, c, *lambda, &newLambda))
+ {
+ e=(edotv*newLambda-edotbv)/elen2;
- if((e>=0.0f) && (e<=1.0f)){
- if(t>0.0 && t < *lambda){
- *lambda=t;
- VecCopyf(ipoint,e2);
- VecMulf(ipoint,e);
- VecAddf(ipoint,ipoint,v0);
- found_by_sweep=1;
- }
+ if(e >= 0.0f && e <= 1.0f)
+ {
+ *lambda = newLambda;
+ VecCopyf(ipoint,e2);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v0);
+ found_by_sweep=1;
}
}
/*e3*/
- VecSubf(e3,v2,v1);
+ VecSubf(bv,v0,p1);
+ elen2 = Inpf(e1,e1);
+ edotv = Inpf(e1,vel);
+ edotbv = Inpf(e1,bv);
+
VecSubf(bv,v1,p1);
elen2 = Inpf(e3,e3);
edotv = Inpf(e3,vel);
@@ -4022,30 +4018,22 @@ int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, f
a=elen2*(-Inpf(vel,vel))+edotv*edotv;
b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
- d=b*b-4*a*c;
- if(d>=0.0f){
- if(d==0.0f)
- t=-b/2*a;
- else{
- z=sqrt(d);
- x=(-b-z)*0.5/a;
- y=(-b+z)*0.5/a;
- t=x<y?x:y;
- }
- e=(edotv*t-edotbv)/elen2;
+ if(getLowestRoot(a, b, c, *lambda, &newLambda))
+ {
+ e=(edotv*newLambda-edotbv)/elen2;
- if((e>=0.0f) && (e<=1.0f)){
- if(t>0.0 && t < *lambda){
- *lambda=t;
- VecCopyf(ipoint,e3);
- VecMulf(ipoint,e);
- VecAddf(ipoint,ipoint,v1);
- found_by_sweep=1;
- }
+ if(e >= 0.0f && e <= 1.0f)
+ {
+ *lambda = newLambda;
+ VecCopyf(ipoint,e3);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v1);
+ found_by_sweep=1;
}
}
+
return found_by_sweep;
}
int AxialLineIntersectsTriangle(int axis, float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda)
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index fe352610a40..3e618a483e3 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -451,7 +451,7 @@ void IMB_exr_begin_write(void *handle, char *filename, int width, int height, in
openexr_header_compression(&header, compress);
/* header.lineOrder() = DECREASING_Y; this crashes in windows for file read! */
- header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43"));
+ header.insert ("BlenderMultiChannel", StringAttribute ("Blender V2.43 and newer"));
data->ofile = new OutputFile(filename, header);
}
diff --git a/source/blender/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h
index 2d751f56fc5..7e0f703681b 100644
--- a/source/blender/include/BIF_editaction.h
+++ b/source/blender/include/BIF_editaction.h
@@ -141,6 +141,7 @@ void paste_actdata(void);
/* Group/Channel Operations */
struct bActionGroup *get_active_actiongroup(struct bAction *act);
void set_active_actiongroup(struct bAction *act, struct bActionGroup *agrp, short select);
+void actionbone_group_copycolors(struct bActionGroup *grp, short init_new);
void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]);
void sync_pchan2achan_grouping(void);
void action_groups_group(short add_group);
@@ -166,6 +167,7 @@ void deselect_action_channels(short mode);
void deselect_actionchannels(struct bAction *act, short mode);
int select_channel(struct bAction *act, struct bActionChannel *achan, int selectmode);
void select_actionchannel_by_name(struct bAction *act, char *name, int select);
+void select_action_group_channels(struct bAction *act, struct bActionGroup *agrp);
void selectkeys_leftright (short leftright, short select_mode);
/* Action Markers */
diff --git a/source/blender/include/BIF_resources.h b/source/blender/include/BIF_resources.h
index e6cbe7bb69a..df514190270 100644
--- a/source/blender/include/BIF_resources.h
+++ b/source/blender/include/BIF_resources.h
@@ -591,6 +591,9 @@ void BIF_load_ui_colors (void);
char *BIF_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid);
char *BIF_ThemeColorsPup(int spacetype);
+/* only for Bone Color sets */
+char *BIF_ThemeColorSetsPup(short inc_custom);
+
void BIF_def_color (BIFColorID colorid, unsigned char r, unsigned char g, unsigned char b);
diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h
index a798224b35b..6f8b94d7cd1 100644
--- a/source/blender/include/blendef.h
+++ b/source/blender/include/blendef.h
@@ -409,6 +409,12 @@
#define B_ACTCOPYKEYS 710
#define B_ACTPASTEKEYS 711
+#define B_ACTCUSTCOLORS 712
+#define B_ACTCOLSSELECTOR 713
+#define B_ACTGRP_SELALL 714
+#define B_ACTGRP_ADDTOSELF 715
+#define B_ACTGRP_UNGROUP 716
+
/* TIME: 751 - 800 */
#define B_TL_REW 751
#define B_TL_PLAY 752
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index a467722e8e1..ac9761f165d 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -196,9 +196,7 @@ typedef struct bVisibilityActuator {
} bVisibilityActuator;
typedef struct bTwoDFilterActuator{
- char pad[2];
- /* bitwise flag for enabling or disabling depth(bit 0) and luminance(bit 1) */
- short texture_flag;
+ char pad[4];
/* Tells what type of 2D Filter */
short type;
/* (flag == 0) means 2D filter is activate and
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 3de5b0ff5ba..cd1c047dac9 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -116,6 +116,7 @@ typedef struct ThemeWireColor {
/* flags for ThemeWireColor */
#define TH_WIRECOLOR_CONSTCOLS (1<<0)
+#define TH_WIRECOLOR_TEXTCOLS (1<<1)
/* A theme */
typedef struct bTheme {
diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c
index 799735c2062..468263c4208 100644
--- a/source/blender/python/api2_2x/Library.c
+++ b/source/blender/python/api2_2x/Library.c
@@ -1135,9 +1135,78 @@ static PyObject *M_Library_Load(PyObject *self, PyObject * args)
return (PyObject *)lib;
}
+static PyObject *M_Library_GetPaths(PyObject *self, PyObject * args)
+{
+ PyObject *list;
+ PyObject *name;
+ int type=0;
+ Library *lib;
+
+ if( !PyArg_ParseTuple( args, "|i", &type ) || type < 0 || type > 2 ) {
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected an int between 0 and 2." );
+ }
+
+ list = PyList_New(0);
+
+ for(lib= G.main->library.first; lib; lib= lib->id.next) {
+ if (type==0) {
+ /* any type is ok */
+ } else if (type==1 && lib->parent == 0) {
+ /* only direct linked */
+ } else if (type==2 && lib->parent != 0) {
+ /* only indirect */
+ } else {
+ continue; /* incompatible type */
+ }
+
+ name = PyString_FromString(lib->name);
+ PyList_Append(list, name);
+ Py_DECREF(name);
+ }
+ return list;
+}
+
+static PyObject *M_Library_ReplacePath(PyObject *self, PyObject * args)
+{
+ char *name_from, *name_to;
+ Library *lib;
+
+ if( !PyArg_ParseTuple( args, "ss", &name_from, &name_to )) {
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected the name of a library path" );
+ }
+
+ for(lib= G.main->library.first; lib; lib= lib->id.next) {
+ if (strcmp(lib->name, name_from)==0) {
+ if (lib->parent) {
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "path is indirectly linked, cannot be changed." );
+ }
+
+ if (strlen(name_to) > sizeof(lib->name)) {
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "string length too long, cannot set path." );
+ }
+
+ strcpy(lib->name, name_to);
+ Py_RETURN_NONE;
+ }
+ }
+
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "path given does not exist as a library" );
+}
+
+
+
static struct PyMethodDef M_Library_methods[] = {
{"load", (PyCFunction)M_Library_Load, METH_VARARGS,
"(string) - declare a .blend file for use as a library"},
+ {"paths", (PyCFunction)M_Library_GetPaths, METH_VARARGS,
+ "(type) - return a list of library paths, type 0 for all, 1 only direct links, 2 only indirect links"},
+ {"replace", (PyCFunction)M_Library_ReplacePath, METH_VARARGS,
+ "(from, to) - replace the path of an existing, directly linked library."},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/api2_2x/doc/LibData.py b/source/blender/python/api2_2x/doc/LibData.py
index 47bd7fdb763..daa6a186531 100644
--- a/source/blender/python/api2_2x/doc/LibData.py
+++ b/source/blender/python/api2_2x/doc/LibData.py
@@ -27,17 +27,37 @@ Example::
"""
def load(filename,relative=False):
- """
- Select an existing .blend file for use as a library. Unlike the
- Library module, multiple libraries can be defined at the same time.
-
- @type filename: string
- @param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
- @type relative: boolean
- @param relative: Convert relative paths to absolute paths (default). Setting this parameter to True will leave paths relative.
- @rtype: Library
- @return: return a L{Library} object.
- """
+ """
+ Select an existing .blend file for use as a library. Unlike the
+ Library module, multiple libraries can be defined at the same time.
+
+ @type filename: string
+ @param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
+ @type relative: boolean
+ @param relative: Convert relative paths to absolute paths (default). Setting this parameter to True will leave paths relative.
+ @rtype: Library
+ @return: return a L{Library} object.
+ """
+
+def paths(link=0):
+ """
+ Returns a list of paths used in the current blend file.
+
+ @type link: int
+ @param link: 0 (default if no args given) for all library paths, 1 for directly linked library paths only, 2 for indirectly linked library paths only.
+ @rtype: List
+ @return: return a list of path strings.
+ """
+
+def replace(pathFrom, pathTo):
+ """
+ Replaces an existing directly linked path.
+
+ @type pathFrom: string
+ @param pathFrom: An existing library path.
+ @type pathTo: string
+ @param pathTo: A new library path.
+ """
class Libraries:
"""
diff --git a/source/blender/python/api2_2x/doc/Render.py b/source/blender/python/api2_2x/doc/Render.py
index 475a4fc5b10..d4dc83e84a0 100644
--- a/source/blender/python/api2_2x/doc/Render.py
+++ b/source/blender/python/api2_2x/doc/Render.py
@@ -833,9 +833,7 @@ class RenderData:
def enableCropping(toggle):
"""
- Enable/disable exclusion of border rendering from total image.
- @type toggle: int
- @param toggle: pass 1 for on / 0 for off
+ Deprecated: see the L{crop} attribute.
"""
def setImageType(type):
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index b446af7efd4..d382d450970 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -985,7 +985,7 @@ PyObject *RenderData_EnableCropping( void )
/* return M_Render_BitToggleInt( args, R_MOVIECROP,
&self->renderContext->mode );
*/
- printf("cropping option is now default, obsolete\n");
+ printf("obsolete: movie cropping option is now default\n");
Py_RETURN_NONE;
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 67be0ce4c00..4520e4c10bb 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -671,8 +671,10 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
RenderPass *zpass;
GroupObject *go;
LampRen *lar;
-
- int x, y;
+ RenderLayer *rlpp[RE_MAX_OSA];
+
+ int totsample, fullsample, sample;
+ int x, y,od;
short first_lamp;
float *zrect;
float *rgbrect;
@@ -683,7 +685,10 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
fac = 0.5;
facm = 1.0 - fac;
-
+
+ totsample= get_sample_layers(pa, rl, rlpp);
+ fullsample= (totsample > 1);
+
/* check that z pass is enabled */
if(pa->rectz==NULL) return;
for(zpass= rl->passes.first; zpass; zpass= zpass->next)
@@ -708,9 +713,10 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
zrect = zpass->rect;
rgbrect = rl->rectf;
+ od=0;
/* for each x,y and sun lamp*/
for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
- for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, zrect++, rgbrect+=4) {
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, zrect++, od++) {
first_lamp = 1;
for(go=R.lights.first; go; go= go->next) {
@@ -724,7 +730,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
}
if(lar->sunsky->effect_type & LA_SUN_EFFECT_AP){
- VECCOPY(tmp_rgb, rgbrect);
+ VECCOPY(tmp_rgb, (float*)(rgbrect+4*od));
shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
@@ -743,7 +749,16 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
/* if at least for one sun lamp aerial perspective was applied*/
if(first_lamp==0)
- VECCOPY(rgbrect, rgb);
+ {
+ if(fullsample) {
+ for(sample=0; sample<totsample; sample++) {
+ VECCOPY((float*)(rlpp[sample]->rectf + od*4), rgb);
+ }
+ }
+ else {
+ VECCOPY((float*)(rgbrect+4*od), rgb);
+ }
+ }
}
}
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 579905315bb..c91c9e2f799 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -3545,7 +3545,7 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
float *col= NULL;
- int pixsize= 0;
+ int pixsize= 3;
switch(rpass->passtype) {
case SCE_PASS_RGBA:
@@ -3580,6 +3580,10 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
col= &shr->mist;
pixsize= 1;
break;
+ case SCE_PASS_Z:
+ col= &shr->z;
+ pixsize= 1;
+ break;
case SCE_PASS_VECTOR:
{
@@ -3612,14 +3616,18 @@ void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
for(samp= 1; samp<R.osa; samp++, fp+=delta) {
col[0]+= fp[0];
- col[1]+= fp[1];
- col[2]+= fp[2];
- if(pixsize) col[3]+= fp[3];
+ if(pixsize>1) {
+ col[1]+= fp[1];
+ col[2]+= fp[2];
+ if(pixsize==4) col[3]+= fp[3];
+ }
}
col[0]*= weight;
- col[1]*= weight;
- col[2]*= weight;
- if(pixsize) col[3]*= weight;
+ if(pixsize>1) {
+ col[1]*= weight;
+ col[2]*= weight;
+ if(pixsize==4) col[3]*= weight;
+ }
}
}
@@ -3973,7 +3981,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
/* general shader info, passes */
shade_sample_initialize(&ssamp, pa, rl);
- addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
+ addpassflag= rl->passflag & ~(SCE_PASS_COMBINED);
addzbuf= rl->passflag & SCE_PASS_Z;
if(R.osa)
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 7eff79fec88..529a795a101 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -513,7 +513,6 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
} else {
editmesh_deselect_by_material(G.obedit->actcol-1);
}
- allqueue(REDRAWVIEW3D, 0);
}
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
nu= editNurb.first;
@@ -553,8 +552,9 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
nu= nu->next;
}
BIF_undo_push("Select material index");
- allqueue(REDRAWVIEW3D, 0);
}
+ allqueue(REDRAWIMAGE, 0);
+ allqueue(REDRAWVIEW3D, 0);
}
countall();
break;
@@ -5153,32 +5153,6 @@ static void verify_posegroup_groupname(void *arg1, void *arg2)
BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
}
-static char *build_colorsets_menustr ()
-{
- DynStr *pupds= BLI_dynstr_new();
- char *str;
- char buf[48];
- int i;
-
- /* add title first (and the "default" entry) */
- BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|");
-
- /* loop through set indices, adding them */
- for (i=1; i<21; i++) {
- sprintf(buf, "%d - Theme Color Set%%x%d|", i, i);
- BLI_dynstr_append(pupds, buf);
- }
-
- /* add the 'custom' entry */
- BLI_dynstr_append(pupds, "Custom Set %x-1");
-
- /* convert to normal MEM_malloc'd string */
- str= BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-
- return str;
-}
-
static void editing_panel_links(Object *ob)
{
uiBlock *block;
@@ -5338,32 +5312,14 @@ static void editing_panel_links(Object *ob)
/* color set for 'active' group */
if (pose->active_group && grp) {
uiBlockBeginAlign(block);
- menustr= build_colorsets_menustr();
+ menustr= BIF_ThemeColorSetsPup(1);
uiDefButI(block, MENU,B_POSEGRP_RECALC, menustr, xco,85,140,19, &grp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme");
MEM_freeN(menustr);
/* show color-selection/preview */
if (grp->customCol) {
- if (grp->customCol > 0) {
- /* copy theme colors on-to group's custom color in case user tries to edit color */
- bTheme *btheme= U.themes.first;
- ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
-
- memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
- }
- else {
- /* init custom colors with a generic multi-color rgb set, if not initialised already */
- if (grp->cs.solid[0] == 0) {
- /* define for setting colors in theme below */
- #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
-
- SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
- SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
- SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
-
- #undef SETCOL
- }
- }
+ /* do color copying/init (to stay up to date) */
+ actionbone_group_copycolors(grp, 1);
/* color changing */
uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "", xco, 65, 30, 19, grp->cs.solid, 0, 0, 0, 0, "Color to use for surface of bones");
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index cc4df06e22d..441d00ffc30 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -2536,11 +2536,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
break;
case ACT_2DFILTER_CUSTOMFILTER:
uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
- uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width/2-32, 19, &tdfa->text, "");
- uiDefButS(block, TOG|BIT|0, B_REDR, "Depth", xco+width/2+2 , yco - 64, width/4-16 , 19,
- &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Depth Texture (bgl_DepthTexture)");
- uiDefButS(block, TOG|BIT|1, B_REDR, "Luminance", xco+3*width/4-14 , yco - 64, width/4-16 , 19,
- &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Luminance Texture (bgl_LuminanceTexture)");
+ uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
break;
}
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index af90d01fb59..3b0167d673c 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -137,36 +137,42 @@ static void load_new_sample(char *str) /* called from fileselect */
bSample *sample, *newsample;
sound = G.buts->lockpoin;
+
+ /* No Sound or Selected the same sample as we alredy have, just ignore */
+ if (sound==NULL || str==sound->name)
+ return;
+
+ if (sizeof(sound->sample->name) < strlen(str)) {
+ error("Path too long: %s", str);
+ return;
+ }
+
+ // save values
+ sample = sound->sample;
+ strcpy(name, sound->sample->name);
+ strcpy(sound->name, str);
+ sound_set_sample(sound, NULL);
+ sound_initialize_sample(sound);
- if (sound) {
- // save values
- sample = sound->sample;
- strcpy(name, sound->sample->name);
-
- strcpy(sound->name, str);
- sound_set_sample(sound, NULL);
- sound_initialize_sample(sound);
-
- if (sound->sample->type == SAMPLE_INVALID) {
- error("Not a valid sample: %s", str);
+ if (sound->sample->type == SAMPLE_INVALID) {
+ error("Not a valid sample: %s", str);
- newsample = sound->sample;
+ newsample = sound->sample;
- // restore values
- strcpy(sound->name, name);
- sound_set_sample(sound, sample);
+ // restore values
+ strcpy(sound->name, name);
+ sound_set_sample(sound, sample);
- // remove invalid sample
+ // remove invalid sample
- sound_free_sample(newsample);
- BLI_remlink(samples, newsample);
- MEM_freeN(newsample);
- }
+ sound_free_sample(newsample);
+ BLI_remlink(samples, newsample);
+ MEM_freeN(newsample);
+ return;
}
-
+
BIF_undo_push("Load new audio file");
allqueue(REDRAWBUTSSCENE, 0);
-
}
@@ -403,7 +409,7 @@ static void sound_panel_sound(bSound *sound)
sample = sound->sample;
/* info string */
- if (sound->sample && sound->sample->len) {
+ if (sound->sample && sound->sample->len && sound->sample->channels && sound->sample->bits) {
char *tmp;
if (sound->sample->channels == 1) tmp= "Mono";
else if (sound->sample->channels == 2) tmp= "Stereo";
@@ -1174,18 +1180,18 @@ static void seq_panel_proxy()
130,140,120,19, &last_seq->flag,
0.0, 21.0, 100, 0,
"Use a custom directory to store data");
- }
- if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
- uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_DIR,
- ICON_FILESEL, 10, 120, 20, 20, 0, 0, 0, 0, 0,
- "Select the directory/name for "
- "the proxy storage");
+ if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_DIR,
+ ICON_FILESEL, 10, 120, 20, 20, 0, 0, 0, 0, 0,
+ "Select the directory/name for "
+ "the proxy storage");
- uiDefBut(block, TEX,
- B_SEQ_BUT_RELOAD, "Dir: ",
- 30,120,220,20, last_seq->strip->proxy->dir,
- 0.0, 160.0, 100, 0, "");
+ uiDefBut(block, TEX,
+ B_SEQ_BUT_RELOAD, "Dir: ",
+ 30,120,220,20, last_seq->strip->proxy->dir,
+ 0.0, 160.0, 100, 0, "");
+ }
}
if (last_seq->flag & SEQ_USE_PROXY) {
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index 89466151a39..6fe37c1c6e5 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -32,6 +32,7 @@
#include <math.h>
#include <stdlib.h>
+#include <string.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -56,6 +57,7 @@
#include "DNA_space_types.h"
#include "DNA_constraint_types.h"
#include "DNA_key_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_action.h"
#include "BKE_depsgraph.h"
@@ -928,12 +930,55 @@ static void draw_channel_strips(void)
void do_actionbuts(unsigned short event)
{
switch(event) {
+ /* general */
case REDRAWVIEW3D:
allqueue(REDRAWVIEW3D, 0);
break;
case B_REDR:
allqueue(REDRAWACTION, 0);
break;
+
+ /* action-groups */
+ case B_ACTCUSTCOLORS: /* only when of the color wells is edited */
+ {
+ bActionGroup *agrp= get_active_actiongroup(G.saction->action);
+
+ if (agrp)
+ agrp->customCol= -1;
+
+ allqueue(REDRAWACTION, 0);
+ }
+ break;
+ case B_ACTCOLSSELECTOR: /* sync color set after using selector */
+ {
+ bActionGroup *agrp= get_active_actiongroup(G.saction->action);
+
+ if (agrp)
+ actionbone_group_copycolors(agrp, 1);
+
+ allqueue(REDRAWACTION, 0);
+ }
+ break;
+ case B_ACTGRP_SELALL: /* select all grouped channels */
+ {
+ bAction *act= G.saction->action;
+ bActionGroup *agrp= get_active_actiongroup(act);
+
+ /* select all in group, then reselect/activate group as the previous operation clears that */
+ select_action_group_channels(act, agrp);
+ agrp->flag |= (AGRP_ACTIVE|AGRP_SELECTED);
+
+ allqueue(REDRAWACTION, 0);
+ }
+ break;
+ case B_ACTGRP_ADDTOSELF: /* add all selected action channels to self */
+ action_groups_group(0);
+ break;
+ case B_ACTGRP_UNGROUP: /* remove channels from active group */
+ // FIXME: todo...
+ printf("FIXME: remove achans from active Action-Group not implemented yet! \n");
+ break;
+
}
}
@@ -941,14 +986,68 @@ void do_actionbuts(unsigned short event)
static void action_panel_properties(short cntrl) // ACTION_HANDLER_PROPERTIES
{
uiBlock *block;
-
+ void *data;
+ short datatype;
+
block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(ACTION_HANDLER_PROPERTIES); // for close and esc
- if (uiNewPanel(curarea, block, "Transform Properties", "Action", 10, 230, 318, 204)==0)
+
+ /* get datatype */
+ data= get_action_context(&datatype);
+ //if (data == NULL) return;
+
+ if (uiNewPanel(curarea, block, "Active Channel Properties", "Action", 10, 230, 318, 204)==0)
return;
-
- uiDefBut(block, LABEL, 0, "test text", 10,180,300,19, 0, 0, 0, 0, 0, "");
+
+ /* currently, only show data for actions */
+ if (datatype == ACTCONT_ACTION) {
+ bActionGroup *agrp= get_active_actiongroup(data);
+ //bActionChannel *achan= get_hilighted_action_channel(data);
+ char *menustr;
+
+ /* only for action-groups */
+ if (agrp) {
+ /* general stuff */
+ uiDefBut(block, LABEL, 1, "Action Group:", 10, 180, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefBut(block, TEX, B_REDR, "Name: ", 10,160,150,20, agrp->name, 0.0, 31.0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, AGRP_EXPANDED, B_REDR, "Expanded", 170, 160, 75, 20, &agrp->flag, 0, 0, 0, 0, "Action Group is expanded");
+ uiDefButBitI(block, TOG, AGRP_PROTECTED, B_REDR, "Protected", 245, 160, 75, 20, &agrp->flag, 0, 0, 0, 0, "Action Group is protected");
+ uiBlockEndAlign(block);
+
+ /* color stuff */
+ uiDefBut(block, LABEL, 1, "Group Colors:", 10, 107, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ menustr= BIF_ThemeColorSetsPup(1);
+ uiDefButI(block, MENU,B_ACTCOLSSELECTOR, menustr, 10,85,150,19, &agrp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme");
+ MEM_freeN(menustr);
+
+ /* show color-selection/preview */
+ if (agrp->customCol) {
+ /* do color copying/init (to stay up to date) */
+ actionbone_group_copycolors(agrp, 1);
+
+ /* color changing */
+ uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 10, 65, 50, 19, agrp->cs.active, 0, 0, 0, 0, "Color to use for 'top-level' channels");
+ uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 60, 65, 50, 19, agrp->cs.select, 0, 0, 0, 0, "Color to use for '2nd-level' channels");
+ uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 110, 65, 50, 19, agrp->cs.solid, 0, 0, 0, 0, "Color to use for '3rd-level' channels");
+ }
+ uiBlockEndAlign(block);
+
+ /* commands for active group */
+ uiDefBut(block, BUT, B_ACTGRP_SELALL, "Select Grouped", 170,85,150,20, 0, 21, 0, 0, 0, "Select all action-channels belonging to this group (same as doing Ctrl-Shift-LMB)");
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, BUT, B_ACTGRP_ADDTOSELF, "Add to Group", 170,60,150,20, 0, 21, 0, 0, 0, "Add selected action-channels to this group");
+ uiDefBut(block, BUT, B_ACTGRP_UNGROUP, "Un-Group", 170,40,150,20, 0, 21, 0, 0, 0, "Remove selected action-channels from this group (unimplemented)");
+ uiBlockEndAlign(block);
+ }
+ }
+ else {
+ /* Currently, there isn't anything to display for these types ... */
+ }
}
static void action_blockhandlers(ScrArea *sa)
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index f93a1526e3c..4cc0e52ce3f 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -1114,6 +1114,38 @@ void action_groups_ungroup (void)
allqueue(REDRAWACTION, 0);
}
+/* Copy colors from a specified theme's color set to an Action/Bone Group */
+void actionbone_group_copycolors (bActionGroup *grp, short init_new)
+{
+ /* error checking */
+ if (grp == NULL)
+ return;
+
+ /* only do color copying if using a custom color */
+ if (grp->customCol) {
+ if (grp->customCol > 0) {
+ /* copy theme colors on-to group's custom color in case user tries to edit color */
+ bTheme *btheme= U.themes.first;
+ ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
+
+ memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
+ }
+ else if (init_new) {
+ /* init custom colors with a generic multi-color rgb set, if not initialised already (and allowed to do so) */
+ if (grp->cs.solid[0] == 0) {
+ /* define for setting colors in theme below */
+ #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
+
+ SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
+ SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
+ SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
+
+ #undef SETCOL
+ }
+ }
+ }
+}
+
/* This function is used when inserting keyframes for pose-channels. It assigns the
* action-channel with the nominated name to a group with the same name as that of
* the pose-channel with the nominated name.
@@ -1160,34 +1192,9 @@ void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
/* copy name */
sprintf(grp->name, agrp->name);
- /* deal with group-color copying */
- if (agrp->customCol) {
- if (agrp->customCol > 0) {
- /* copy theme colors on-to group's custom color in case user tries to edit color */
- bTheme *btheme= U.themes.first;
- ThemeWireColor *col_set= &btheme->tarm[(agrp->customCol - 1)];
-
- memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
- }
- else {
- /* init custom colors with a generic multi-color rgb set, if not initialised already */
- if (agrp->cs.solid[0] == 0) {
- /* define for setting colors in theme below */
- #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
-
- SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
- SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
- SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
-
- #undef SETCOL
- }
- else {
- /* just copy color set specified */
- memcpy(&grp->cs, &agrp->cs, sizeof(ThemeWireColor));
- }
- }
- }
- grp->customCol= agrp->customCol;
+ /* deal with group-color copying (grp is destination, agrp is source) */
+ memcpy(grp, agrp, sizeof(bActionGroup));
+ actionbone_group_copycolors(grp, 1);
BLI_addtail(&act->groups, grp);
}
@@ -2697,6 +2704,28 @@ int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode)
return flag;
}
+
+/* select only the active action-group's action channels */
+void select_action_group_channels (bAction *act, bActionGroup *agrp)
+{
+ bActionChannel *achan;
+
+ /* error checking */
+ if (ELEM(NULL, act, agrp))
+ return;
+
+ /* deselect all other channels */
+ deselect_actionchannels(act, 0);
+
+ /* only select channels in group */
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ select_channel(act, achan, SELECT_ADD);
+
+ /* messy... set active bone */
+ select_poseelement_by_name(achan->name, 1);
+ }
+}
+
/* ----------------------------------------- */
/* De-selects or inverts the selection of Channels in a given Action
@@ -3672,17 +3701,8 @@ static void mouse_actionchannels (short mval[])
select_action_group(act, agrp, SELECT_INVERT);
}
else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
- bActionChannel *achan;
-
/* select all in group (and deselect everthing else) */
- deselect_actionchannels(act, 0);
-
- for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
- select_channel(act, achan, SELECT_ADD);
-
- /* messy... set active bone */
- select_poseelement_by_name(achan->name, 1);
- }
+ select_action_group_channels(act, agrp);
select_action_group(act, agrp, SELECT_ADD);
}
else {
@@ -4682,11 +4702,13 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case NKEY:
if (G.qual==0) {
- numbuts_action();
-
- /* no panel (yet). current numbuts are not easy to put in panel... */
- //add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
- //scrarea_queue_winredraw(curarea);
+ /* panel will not always show useful info! */
+ if (mval[0] > ACTWIDTH) {
+ add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
+ scrarea_queue_winredraw(curarea);
+ }
+ else
+ numbuts_action();
}
break;
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 9eef61e11f9..188f7476728 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -340,8 +340,9 @@ void free_editface(EditFace *efa)
#endif
EM_remove_selection(efa, EDITFACE);
- if (G.editMesh->act_face==efa)
- EM_set_actFace(NULL);
+ if (G.editMesh->act_face==efa) {
+ EM_set_actFace( G.editMesh->faces.first == efa ? NULL : G.editMesh->faces.first);
+ }
CustomData_em_free_block(&G.editMesh->fdata, &efa->data);
if(efa->fast==0)
@@ -1059,7 +1060,11 @@ void make_editMesh()
EM_hide_reset();
/* sets helper flags which arent saved */
EM_fgon_flags();
-
+
+ if (EM_get_actFace(0)==NULL) {
+ EM_set_actFace( G.editMesh->faces.first ); /* will use the first face, this is so we alwats have an active face */
+ }
+
/* vertex coordinates change with cache edit, need to recalc */
if(cacheedit)
recalc_editnormals();
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 2e5785eaab8..6af4f47ed11 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -5505,6 +5505,7 @@ void selectlinks(int nr)
allqueue(REDRAWDATASELECT, 0);
allqueue(REDRAWOOPS, 0);
BIF_undo_push("Select linked");
+ countall();
}
}
diff --git a/source/blender/src/editsound.c b/source/blender/src/editsound.c
index 1cb7ec276cb..05eb094a7c2 100644
--- a/source/blender/src/editsound.c
+++ b/source/blender/src/editsound.c
@@ -148,7 +148,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
first= 0;
CFRA= cfra;
update_for_newframe();
- force_draw_plus(SPACE_VIEW3D, 1);
+ force_draw_all(0);
}
else PIL_sleep_ms(30);
diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c
index 4fbf92d646e..19e2e4b6245 100644
--- a/source/blender/src/interface.c
+++ b/source/blender/src/interface.c
@@ -5405,7 +5405,9 @@ uiBlock *uiNewBlock(ListBase *lb, char *name, short dt, short font, short win)
int getsizex, getsizey;
bwin_getsize(win, &getsizex, &getsizey);
- block->aspect= 2.0/( (getsizex)*block->winmat[0][0]);
+ /* TODO - investigate why block->winmat[0][0] is negative
+ * in the image view when viewRedrawForce is called */
+ block->aspect= 2.0/fabs( (getsizex)*block->winmat[0][0]);
}
uiSetCurFont(block, font);
diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c
index 2d8b0c81175..fb2bfe5b605 100644
--- a/source/blender/src/poselib.c
+++ b/source/blender/src/poselib.c
@@ -756,6 +756,13 @@ static void poselib_keytag_pose (tPoseLib_PreviewData *pld)
*/
static void poselib_preview_get_next (tPoseLib_PreviewData *pld, int step)
{
+ /* check if we no longer have search-string, but don't have any marker */
+ if (pld->marker == NULL) {
+ if ((step) && (pld->searchstr[0] == 0))
+ pld->marker= pld->act->markers.first;
+ }
+
+ /* the following operations assume that there is a starting point and direction */
if ((pld->marker) && (step)) {
/* search-string dictates a special approach */
if (pld->searchstr[0]) {
@@ -1262,9 +1269,14 @@ void poselib_preview_poses (Object *ob, short apply_active)
/* get search-string */
index= pld.search_cursor;
- memcpy(&tempstr[0], &pld.searchstr[0], index);
- tempstr[index]= '|';
- memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index);
+ if (IN_RANGE(index, 0, 64)) {
+ memcpy(&tempstr[0], &pld.searchstr[0], index);
+ tempstr[index]= '|';
+ memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index);
+ }
+ else {
+ strncpy(tempstr, pld.searchstr, 64);
+ }
/* get marker name */
if (pld.marker)
diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c
index 046d14c990d..f47f14a605c 100644
--- a/source/blender/src/resources.c
+++ b/source/blender/src/resources.c
@@ -52,6 +52,7 @@
#include "BIF_interface_icons.h"
#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
#include "blendef.h" // CLAMP
#include "datatoc.h"
@@ -784,6 +785,33 @@ char *BIF_ThemeColorsPup(int spacetype)
return cp;
}
+char *BIF_ThemeColorSetsPup (short inc_custom)
+{
+ DynStr *pupds= BLI_dynstr_new();
+ char *str;
+ char buf[48];
+ int i;
+
+ /* add title first (and the "default" entry) */
+ BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|");
+
+ /* loop through set indices, adding them */
+ for (i=1; i<21; i++) {
+ sprintf(buf, "%d - Theme Color Set%%x%d|", i, i);
+ BLI_dynstr_append(pupds, buf);
+ }
+
+ /* add the 'custom' entry */
+ if (inc_custom)
+ BLI_dynstr_append(pupds, "Custom Set %x-1");
+
+ /* convert to normal MEM_malloc'd string */
+ str= BLI_dynstr_get_cstring(pupds);
+ BLI_dynstr_free(pupds);
+
+ return str;
+}
+
void BIF_SetTheme(ScrArea *sa)
{
if(sa==NULL) { // called for safety, when delete themes
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 3b8bb4c3929..58420604c83 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -4844,9 +4844,9 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if( cfra!=CFRA || first ) {
first= 0;
-
+
CFRA= cfra;
- force_draw(0);
+ force_draw_all(0);
update_for_newframe(); /* for audio scrubbing */
}
else PIL_sleep_ms(30);
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 10e49cdd218..562d9a4934d 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -3623,7 +3623,7 @@ void special_aftertrans_update(TransInfo *t)
}
}
}
- else if (t->spacetype == SPACE_ACTION) {
+ if (t->spacetype == SPACE_ACTION) {
void *data;
short datatype;
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 4af5ac4d5d2..b3a3a47152a 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -332,6 +332,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
ketsjiengine->SetPythonDictionary(dictionaryobject);
initRasterizer(rasterizer, canvas);
PyObject *gameLogic = initGameLogic(startscene);
+ PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module.
initGameKeys();
initPythonConstraintBinding();
@@ -399,7 +400,14 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
exitstring = ketsjiengine->GetExitString();
// when exiting the mainloop
- dictionaryClearByHand(gameLogic);
+
+ // Clears the dictionary by hand:
+ // This prevents, extra references to global variables
+ // inside the GameLogic dictionary when the python interpreter is finalized.
+ // which allows the scene to safely delete them :)
+ // see: (space.c)->start_game
+ PyDict_Clear(PyModule_GetDict(gameLogic));
+
ketsjiengine->StopEngine();
exitGamePythonScripting();
networkdevice->Disconnect();
@@ -591,6 +599,7 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area,
ketsjiengine->SetPythonDictionary(dictionaryobject);
initRasterizer(rasterizer, canvas);
PyObject *gameLogic = initGameLogic(startscene);
+ PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module
initGameKeys();
initPythonConstraintBinding();
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index 73d2870720a..220d174d464 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -483,9 +483,9 @@ void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
-void KX_BlenderRenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag)
+void KX_BlenderRenderTools::Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
{
- m_filtermanager.EnableFilter(filtermode, pass, text, texture_flag);
+ m_filtermanager.EnableFilter(propNames, gameObj, filtermode, pass, text);
}
void KX_BlenderRenderTools::Render2DFilters(RAS_ICanvas* canvas)
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
index 7748e31156d..8abce1b8c3e 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
@@ -101,7 +101,7 @@ public:
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
- virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag);
+ virtual void Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
virtual void Render2DFilters(RAS_ICanvas* canvas);
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index f3e22cd297a..1f1ac6da119 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1847,7 +1847,10 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
int aspect_width;
int aspect_height;
vector<MT_Vector3> inivel,iniang;
-
+ set<Group*> grouplist; // list of groups to be converted
+ set<Object*> allblobj; // all objects converted
+ set<Object*> groupobj; // objects from groups (never in active layer)
+
if (alwaysUseExpandFraming) {
frame_type = RAS_FrameSettings::e_frame_extend;
aspect_width = canvas->GetWidth();
@@ -1919,6 +1922,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
for (SETLOOPER(blenderscene, base))
{
Object* blenderobject = base->object;
+ allblobj.insert(blenderobject);
+
KX_GameObject* gameobj = gameobject_from_blenderobject(
base->object,
kxscene,
@@ -2046,7 +2051,9 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->NodeUpdateGS(0,true);
gameobj->Bucketize();
-
+
+ if (gameobj->IsDupliGroup())
+ grouplist.insert(blenderobject->dup_group);
}
else
{
@@ -2073,6 +2080,188 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
+ if (!grouplist.empty())
+ {
+ // now convert the group referenced by dupli group object
+ // keep track of all groups already converted
+ set<Group*> allgrouplist = grouplist;
+ set<Group*> tempglist;
+ // recurse
+ while (!grouplist.empty())
+ {
+ set<Group*>::iterator git;
+ tempglist.clear();
+ tempglist.swap(grouplist);
+ for (git=tempglist.begin(); git!=tempglist.end(); git++)
+ {
+ Group* group = *git;
+ GroupObject* go;
+ for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
+ {
+ Object* blenderobject = go->ob;
+ if (converter->FindGameObject(blenderobject) == NULL)
+ {
+ allblobj.insert(blenderobject);
+ groupobj.insert(blenderobject);
+ KX_GameObject* gameobj = gameobject_from_blenderobject(
+ blenderobject,
+ kxscene,
+ rendertools,
+ converter,
+ blenderscene);
+
+ // this code is copied from above except that
+ // object from groups are never is active layer
+ bool isInActiveLayer = false;
+ bool addobj=true;
+
+ if (converter->addInitFromFrame)
+ if (!isInActiveLayer)
+ addobj=false;
+
+ if (gameobj&&addobj)
+ {
+ MT_Point3 posPrev;
+ MT_Matrix3x3 angor;
+ if (converter->addInitFromFrame)
+ blenderscene->r.cfra=blenderscene->r.sfra;
+
+ MT_Point3 pos = MT_Point3(
+ blenderobject->loc[0]+blenderobject->dloc[0],
+ blenderobject->loc[1]+blenderobject->dloc[1],
+ blenderobject->loc[2]+blenderobject->dloc[2]
+ );
+ MT_Vector3 eulxyz = MT_Vector3(
+ blenderobject->rot[0],
+ blenderobject->rot[1],
+ blenderobject->rot[2]
+ );
+ MT_Vector3 scale = MT_Vector3(
+ blenderobject->size[0],
+ blenderobject->size[1],
+ blenderobject->size[2]
+ );
+ if (converter->addInitFromFrame){//rcruiz
+ float eulxyzPrev[3];
+ blenderscene->r.cfra=blenderscene->r.sfra-1;
+ update_for_newframe();
+ MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
+ blenderobject->loc[1]+blenderobject->dloc[1],
+ blenderobject->loc[2]+blenderobject->dloc[2]
+ );
+ eulxyzPrev[0]=blenderobject->rot[0];
+ eulxyzPrev[1]=blenderobject->rot[1];
+ eulxyzPrev[2]=blenderobject->rot[2];
+
+ double fps = (double) blenderscene->r.frs_sec/
+ (double) blenderscene->r.frs_sec_base;
+
+ tmp.scale(fps, fps, fps);
+ inivel.push_back(tmp);
+ tmp=eulxyz-eulxyzPrev;
+ tmp.scale(fps, fps, fps);
+ iniang.push_back(tmp);
+ blenderscene->r.cfra=blenderscene->r.sfra;
+ update_for_newframe();
+ }
+
+ gameobj->NodeSetLocalPosition(pos);
+ gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
+ gameobj->NodeSetLocalScale(scale);
+ gameobj->NodeUpdateGS(0,true);
+
+ BL_ConvertIpos(blenderobject,gameobj,converter);
+ // TODO: expand to multiple ipos per mesh
+ Material *mat = give_current_material(blenderobject, 1);
+ if(mat) BL_ConvertMaterialIpos(mat, gameobj, converter);
+
+ sumolist->Add(gameobj->AddRef());
+
+ BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
+
+
+ gameobj->SetName(blenderobject->id.name);
+
+ // templist to find Root Parents (object with no parents)
+ templist->Add(gameobj->AddRef());
+
+ // update children/parent hierarchy
+ if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
+ {
+ // blender has an additional 'parentinverse' offset in each object
+ SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
+
+ // define a normal parent relationship for this node.
+ KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
+ parentinversenode->SetParentRelation(parent_relation);
+
+ parentChildLink pclink;
+ pclink.m_blenderchild = blenderobject;
+ pclink.m_gamechildnode = parentinversenode;
+ vec_parent_child.push_back(pclink);
+
+ float* fl = (float*) blenderobject->parentinv;
+ MT_Transform parinvtrans(fl);
+ parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
+ parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
+
+ parentinversenode->AddChild(gameobj->GetSGNode());
+ }
+
+ // needed for python scripting
+ logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
+
+ // needed for dynamic object morphing
+ logicmgr->RegisterGameObj(gameobj, blenderobject);
+ for (int i = 0; i < gameobj->GetMeshCount(); i++)
+ logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
+
+ converter->RegisterGameObject(gameobj, blenderobject);
+ // this was put in rapidly, needs to be looked at more closely
+ // only draw/use objects in active 'blender' layers
+
+ logicbrick_conversionlist->Add(gameobj->AddRef());
+
+ if (converter->addInitFromFrame){
+ posPrev=gameobj->NodeGetWorldPosition();
+ angor=gameobj->NodeGetWorldOrientation();
+ }
+ if (isInActiveLayer)
+ {
+ objectlist->Add(gameobj->AddRef());
+ //tf.Add(gameobj->GetSGNode());
+
+ gameobj->NodeUpdateGS(0,true);
+ gameobj->Bucketize();
+
+ }
+ else
+ {
+ //we must store this object otherwise it will be deleted
+ //at the end of this function if it is not a root object
+ inactivelist->Add(gameobj->AddRef());
+
+ }
+ if (gameobj->IsDupliGroup())
+ {
+ // check that the group is not already converted
+ if (allgrouplist.insert(blenderobject->dup_group).second)
+ grouplist.insert(blenderobject->dup_group);
+ }
+ if (converter->addInitFromFrame){
+ gameobj->NodeSetLocalPosition(posPrev);
+ gameobj->NodeSetLocalOrientation(angor);
+ }
+
+ }
+ if (gameobj)
+ gameobj->Release();
+ }
+ }
+ }
+ }
+ }
+
if (blenderscene->camera) {
KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
@@ -2081,15 +2270,18 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
// Set up armatures
- for(SETLOOPER(blenderscene, base)){
- if (base->object->type==OB_MESH){
- Mesh *me = (Mesh*)base->object->data;
+ set<Object*>::iterator oit;
+ for(oit=allblobj.begin(); oit!=allblobj.end(); oit++)
+ {
+ Object* blenderobj = *oit;
+ if (blenderobj->type==OB_MESH){
+ Mesh *me = (Mesh*)blenderobj->data;
if (me->dvert){
- KX_GameObject *obj = converter->FindGameObject(base->object);
+ KX_GameObject *obj = converter->FindGameObject(blenderobj);
- if (base->object->parent && base->object->parent->type==OB_ARMATURE && base->object->partype==PARSKEL){
- KX_GameObject *par = converter->FindGameObject(base->object->parent);
+ if (obj && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE && blenderobj->partype==PARSKEL){
+ KX_GameObject *par = converter->FindGameObject(blenderobj->parent);
if (par)
((BL_SkinDeformer*)(((BL_DeformableGameObject*)obj)->m_pDeformer))->SetArmature((BL_ArmatureObject*) par);
}
@@ -2174,7 +2366,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
{
meshobj = gameobj->GetMesh(0);
}
- BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter,processCompoundChildren);
+ int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
+ BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
}
processCompoundChildren = true;
@@ -2189,7 +2382,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
{
meshobj = gameobj->GetMesh(0);
}
- BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter,processCompoundChildren);
+ int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
+ BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
}
@@ -2311,22 +2505,25 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
- bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
- BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, activeLayerBitInfo,isInActiveLayer,rendertools,converter);
+ int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
+ bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
+ BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, layerMask,isInActiveLayer,rendertools,converter);
}
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
- bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
- BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,activeLayerBitInfo,isInActiveLayer,converter);
+ int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
+ bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
+ BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,layerMask,isInActiveLayer,converter);
}
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
- bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
- BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter);
+ int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
+ bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
+ BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter);
}
// apply the initial state to controllers
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
@@ -2344,5 +2541,19 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// Calculate the scene btree -
// too slow - commented out.
//kxscene->SetNodeTree(tf.MakeTree());
+
+ // instantiate dupli group, we will loop trough the object
+ // that are in active layers. Note that duplicating group
+ // has the effect of adding objects at the end of objectlist.
+ // Only loop through the first part of the list.
+ int objcount = objectlist->GetCount();
+ for (i=0;i<objcount;i++)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) objectlist->GetValue(i);
+ if (gameobj->IsDupliGroup())
+ {
+ kxscene->DupliGroupRecurse(gameobj, 0);
+ }
+ }
}
diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h
index 57a404ad72b..315ad18c42c 100644
--- a/source/gameengine/Converter/BL_DeformableGameObject.h
+++ b/source/gameengine/Converter/BL_DeformableGameObject.h
@@ -60,6 +60,7 @@ public:
{
if (m_pDeformer)
m_pDeformer->Relink (map);
+ KX_GameObject::Relink(map);
};
void ProcessReplica(KX_GameObject* replica);
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp
index eb5c1467ea5..b2e54539b19 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.cpp
+++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp
@@ -109,6 +109,13 @@ bool BL_ShapeDeformer::ExecuteShapeDrivers(void)
vector<IpoCurve*>::iterator it;
void *poin;
int type;
+ // the shape drivers use the bone matrix as input. Must
+ // update the matrix now
+ Object* par_arma = m_armobj->GetArmatureObject();
+ m_armobj->ApplyPose();
+ where_is_pose( par_arma );
+ PoseApplied(true);
+
for (it=m_shapeDrivers.begin(); it!=m_shapeDrivers.end(); it++) {
// no need to set a specific time: this curve has a driver
IpoCurve *icu = *it;
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index d3442fe5298..f96c40c098f 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -66,7 +66,8 @@ BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
m_armobj(arma),
m_lastArmaUpdate(-1),
m_defbase(&bmeshobj->defbase),
- m_releaseobject(false)
+ m_releaseobject(false),
+ m_poseApplied(false)
{
Mat4CpyMat4(m_obmat, bmeshobj->obmat);
};
@@ -98,32 +99,28 @@ BL_SkinDeformer::~BL_SkinDeformer()
m_armobj->Release();
}
-bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *)
+bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
{
size_t i, j;
- if (!Update())
- // no need to update the cache
- return false;
+ // update the vertex in m_transverts
+ Update();
- // Update all materials at once, so we can do the above update test
- // without ending up with some materials not updated
- for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial();
- mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
- RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial();
+ // The vertex cache can only be updated for this deformer:
+ // Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
+ // share the same mesh (=the same cache). As the rendering is done per polymaterial
+ // cycling through the objects, the entire mesh cache cannot be updated in one shot.
+ vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat);
- vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat);
+ // For each array
+ for (i=0; i<vertexarrays.size(); i++) {
+ KX_VertexArray& vertexarray = (*vertexarrays[i]);
- // For each array
- for (i=0; i<vertexarrays.size(); i++) {
- KX_VertexArray& vertexarray = (*vertexarrays[i]);
-
- // For each vertex
- // copy the untransformed data from the original mvert
- for (j=0; j<vertexarray.size(); j++) {
- RAS_TexVert& v = vertexarray[j];
- v.SetXYZ(m_transverts[v.getOrigIndex()]);
- }
+ // For each vertex
+ // copy the untransformed data from the original mvert
+ for (j=0; j<vertexarray.size(); j++) {
+ RAS_TexVert& v = vertexarray[j];
+ v.SetXYZ(m_transverts[v.getOrigIndex()]);
}
}
@@ -153,9 +150,11 @@ bool BL_SkinDeformer::Update(void)
/* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
/* but it requires the blender object pointer... */
-
Object* par_arma = m_armobj->GetArmatureObject();
- where_is_pose( par_arma );
+ if (!PoseApplied()){
+ m_armobj->ApplyPose();
+ where_is_pose( par_arma );
+ }
/* store verts locally */
VerifyStorage();
@@ -180,7 +179,8 @@ bool BL_SkinDeformer::Update(void)
/* Update the current frame */
m_lastArmaUpdate=m_armobj->GetLastFrame();
-
+ /* reset for next frame */
+ PoseApplied(false);
/* indicate that the m_transverts and normals are up to date */
return true;
}
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
index f35db8273c4..d3fc5ae2a81 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.h
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -81,10 +81,13 @@ public:
virtual ~BL_SkinDeformer();
bool Update (void);
bool Apply (class RAS_IPolyMaterial *polymat);
+ bool PoseApplied()
+ { return m_poseApplied; }
+ void PoseApplied(bool applied)
+ { m_poseApplied = applied; }
bool PoseUpdated(void)
{
if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()) {
- m_armobj->ApplyPose();
return true;
}
return false;
@@ -102,6 +105,7 @@ protected:
ListBase* m_defbase;
float m_obmat[4][4]; // the reference matrix for skeleton deform
bool m_releaseobject;
+ bool m_poseApplied;
};
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 1f87e9d9ac7..8739fb109fd 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -503,7 +503,7 @@ void BL_ConvertActuators(char* maggiename,
case ACT_PROPERTY:
{
bPropertyActuator* propact = (bPropertyActuator*) bact->data;
- CValue* destinationObj = NULL;
+ SCA_IObject* destinationObj = NULL;
/*
here the destinationobject is searched. problem with multiple scenes: other scenes
@@ -539,7 +539,7 @@ void BL_ConvertActuators(char* maggiename,
// does the 'original' for replication exists, and
// is it in a non-active layer ?
- CValue* originalval = NULL;
+ SCA_IObject* originalval = NULL;
if (editobact->ob && !(editobact->ob->lay & activeLayerBitInfo))
originalval = converter->FindGameObject(editobact->ob);
@@ -1000,7 +1000,7 @@ void BL_ConvertActuators(char* maggiename,
}
tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag,
- _2dfilter->float_arg,_2dfilter->int_arg,_2dfilter->texture_flag,ketsjiEngine->GetRasterizer(),rendertools);
+ _2dfilter->float_arg,_2dfilter->int_arg,ketsjiEngine->GetRasterizer(),rendertools);
if (_2dfilter->text)
{
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index f0195d5df82..48136eb9dc3 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -405,7 +405,20 @@ bool CValue::RemoveProperty(const STR_String & inName)
return false;
}
-
+//
+// Get Property Names
+//
+vector<STR_String> CValue::GetPropertyNames()
+{
+ vector<STR_String> result;
+ if(!m_pNamedPropertyArray) return result;
+ for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
+ !(it == m_pNamedPropertyArray->end());it++)
+ {
+ result.push_back((*it).first);
+ }
+ return result;
+}
//
// Clear all properties
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index 561e5521d60..bcf231cf4f0 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -286,6 +286,7 @@ public:
STR_String GetPropertyText(const STR_String & inName,const STR_String& deftext=""); // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
float GetPropertyNumber(const STR_String& inName,float defnumber);
virtual bool RemoveProperty(const STR_String & inName); // Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
+ virtual vector<STR_String> GetPropertyNames();
virtual void ClearProperties(); // Clear all properties
virtual void SetPropertiesModified(bool inModified); // Set all properties' modified flag to <inModified>
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index 56249bb52ec..96a770a553f 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -7,7 +7,6 @@
#endif
#include <iostream>
-
SCA_2DFilterActuator::~SCA_2DFilterActuator()
{
}
@@ -18,7 +17,6 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
short flag,
float float_arg,
int int_arg,
- short texture_flag,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools,
PyTypeObject* T)
@@ -26,11 +24,15 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
m_type(type),
m_flag(flag),
m_int_arg(int_arg),
- m_texture_flag(texture_flag),
m_float_arg(float_arg),
m_rasterizer(rasterizer),
m_rendertools(rendertools)
{
+ m_gameObj = NULL;
+ if(gameobj){
+ m_propNames = gameobj->GetPropertyNames();
+ m_gameObj = gameobj;
+ }
}
void SCA_2DFilterActuator::SetShaderText(STR_String text)
@@ -52,8 +54,6 @@ CValue* SCA_2DFilterActuator::GetReplica()
bool SCA_2DFilterActuator::Update()
{
- bool result = false;
-
bool bNegativeEvent = IsNegativeEvent();
RemoveAllEvents();
@@ -74,7 +74,7 @@ bool SCA_2DFilterActuator::Update()
}
else if(m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
{
- m_rendertools->Update2DFilter(m_type, m_int_arg, m_shaderText, m_texture_flag);
+ m_rendertools->Update2DFilter(m_propNames, m_gameObj, m_type, m_int_arg, m_shaderText);
}
return true;
}
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
index 451a7b9491a..7ec07cf5b19 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -5,18 +5,17 @@
#include "RAS_IRenderTools.h"
#include "SCA_IActuator.h"
-
class SCA_2DFilterActuator : public SCA_IActuator
{
Py_Header;
private:
-
+ vector<STR_String> m_propNames;
+ void * m_gameObj;
RAS_2DFilterManager::RAS_2DFILTER_MODE m_type;
short m_flag;
float m_float_arg;
int m_int_arg;
- short m_texture_flag;
STR_String m_shaderText;
RAS_IRasterizer* m_rasterizer;
RAS_IRenderTools* m_rendertools;
@@ -29,7 +28,6 @@ public:
short flag,
float float_arg,
int int_arg,
- short texture_flag,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools,
PyTypeObject* T=&Type
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
index f6efd485adb..e73358bc1e8 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -82,7 +82,10 @@ void SCA_ILogicBrick::ReParent(SCA_IObject* parent)
m_gameobj = parent;
}
-
+void SCA_ILogicBrick::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ // nothing to do
+}
CValue* SCA_ILogicBrick::Calc(VALUE_OPERATOR op, CValue *val)
{
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
index 80bc6ae3b86..c28711ac0f6 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.h
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -32,6 +32,8 @@
#include "Value.h"
#include "SCA_IObject.h"
#include "BoolValue.h"
+#include "GEN_Map.h"
+#include "GEN_HashedPtr.h"
class SCA_ILogicBrick : public CValue
{
@@ -59,6 +61,7 @@ public:
SCA_IObject* GetParent();
virtual void ReParent(SCA_IObject* parent);
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
// act as a BoolValue (with value IsPositiveTrigger)
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index c5bb4a41552..25b4af696ea 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -306,7 +306,7 @@ const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist)
}
#endif
-void SCA_IObject::Suspend(void)
+void SCA_IObject::Suspend()
{
if ((!m_ignore_activity_culling)
&& (!m_suspended)) {
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
index ebe1cd51863..7062f2cef6a 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
@@ -42,7 +42,7 @@
/* Native functions */
/* ------------------------------------------------------------------------- */
-SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,CValue* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T )
+SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T )
: SCA_IActuator(gameobj,T),
m_type(acttype),
m_propname(propname),
@@ -51,14 +51,14 @@ SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,CValue* sourceOb
{
// protect ourselves against someone else deleting the source object
// don't protect against ourselves: it would create a dead lock
- if (m_sourceObj && m_sourceObj != GetParent())
- m_sourceObj->AddRef();
+ if (m_sourceObj)
+ m_sourceObj->RegisterActuator(this);
}
SCA_PropertyActuator::~SCA_PropertyActuator()
{
- if (m_sourceObj && m_sourceObj != GetParent())
- m_sourceObj->Release();
+ if (m_sourceObj)
+ m_sourceObj->UnregisterActuator(this);
}
bool SCA_PropertyActuator::Update()
@@ -185,10 +185,31 @@ void SCA_PropertyActuator::ProcessReplica()
// no need to check for self reference like in the constructor:
// the replica will always have a different parent
if (m_sourceObj)
- m_sourceObj->AddRef();
+ m_sourceObj->RegisterActuator(this);
SCA_IActuator::ProcessReplica();
}
+bool SCA_PropertyActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == m_sourceObj)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_sourceObj = NULL;
+ return true;
+ }
+ return false;
+}
+
+void SCA_PropertyActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_sourceObj];
+ if (h_obj) {
+ if (m_sourceObj)
+ m_sourceObj->UnregisterActuator(this);
+ m_sourceObj = (SCA_IObject*)(*h_obj);
+ m_sourceObj->RegisterActuator(this);
+ }
+}
/* ------------------------------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h
index f8305901c51..1e435684572 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.h
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h
@@ -52,7 +52,7 @@ class SCA_PropertyActuator : public SCA_IActuator
int m_type;
STR_String m_propname;
STR_String m_exprtxt;
- CValue* m_sourceObj; // for copy property actuator
+ SCA_IObject* m_sourceObj; // for copy property actuator
public:
@@ -60,7 +60,7 @@ public:
SCA_PropertyActuator(
SCA_IObject* gameobj,
- CValue* sourceObj,
+ SCA_IObject* sourceObj,
const STR_String& propname,
const STR_String& expr,
int acttype,
@@ -74,7 +74,9 @@ public:
GetReplica(
);
- void ProcessReplica();
+ virtual void ProcessReplica();
+ virtual bool UnlinkObject(SCA_IObject* clientobj);
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool
Update();
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index 76386079bdf..01ae4072335 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -116,7 +116,7 @@ CValue* SCA_PythonController::GetReplica()
void SCA_PythonController::SetScriptText(const STR_String& text)
{
- m_scriptText = "import GameLogic\n" + text;
+ m_scriptText = text;
m_bModified = true;
}
@@ -354,8 +354,10 @@ SCA_PythonController::PyGetSensor(PyObject* self, PyObject* value)
return sensor->AddRef();
}
}
-
- PyErr_SetString(PyExc_AttributeError, "Unable to find requested sensor");
+
+ char emsg[96];
+ PyOS_snprintf( emsg, sizeof( emsg ), "Unable to find requested sensor \"%s\"", scriptArg );
+ PyErr_SetString(PyExc_AttributeError, emsg);
return NULL;
}
@@ -382,8 +384,10 @@ SCA_PythonController::PyGetActuator(PyObject* self, PyObject* value)
return actua->AddRef();
}
}
-
- PyErr_SetString(PyExc_AttributeError, "Unable to find requested actuator");
+
+ char emsg[96];
+ PyOS_snprintf( emsg, sizeof( emsg ), "Unable to find requested actuator \"%s\"", scriptArg );
+ PyErr_SetString(PyExc_AttributeError, emsg);
return NULL;
}
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index a5017574873..8b828393c67 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -602,9 +602,9 @@ void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
-void GPC_RenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag)
+void GPC_RenderTools::Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
{
- m_filtermanager.EnableFilter(filtermode, pass, text, texture_flag);
+ m_filtermanager.EnableFilter(propNames, gameObj, filtermode, pass, text);
}
void GPC_RenderTools::Render2DFilters(RAS_ICanvas* canvas)
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
index cb7193f3513..8fae3d2b305 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
@@ -142,7 +142,7 @@ public:
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
- virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag);
+ virtual void Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
virtual void Render2DFilters(RAS_ICanvas* canvas);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index d6908b53d40..b5ebffb9378 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -644,7 +644,7 @@ bool GPG_Application::startEngine(void)
PyObject* dictionaryobject = initGamePlayerPythonScripting("Ketsji", psl_Lowest);
m_ketsjiengine->SetPythonDictionary(dictionaryobject);
initRasterizer(m_rasterizer, m_canvas);
- PyObject *gameLogic = initGameLogic(startscene);
+ PyDict_SetItemString(dictionaryobject, "GameLogic", initGameLogic(startscene)); // Same as importing the module
initGameKeys();
initPythonConstraintBinding();
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 70443ced7a9..e25deaf05a9 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -13,11 +13,13 @@
#include "KX_ClientObjectInfo.h"
#include "PHY_IPhysicsEnvironment.h"
+#include "CcdPhysicsEnvironment.h"
KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna)
: KX_IPhysicsController(dyna,(PHY_IPhysicsController*)this),
-CcdPhysicsController(ci)
+CcdPhysicsController(ci),
+m_savedCollisionFlags(0)
{
}
@@ -161,14 +163,34 @@ void KX_BulletPhysicsController::setRigidBody(bool rigid)
{
}
-void KX_BulletPhysicsController::SuspendDynamics()
+void KX_BulletPhysicsController::SuspendDynamics(bool ghost)
{
- GetRigidBody()->setActivationState(DISABLE_SIMULATION);
-
+ btRigidBody *body = GetRigidBody();
+ if (body->getActivationState() != DISABLE_SIMULATION)
+ {
+ btBroadphaseProxy* handle = body->getBroadphaseHandle();
+ m_savedCollisionFlags = body->getCollisionFlags();
+ m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
+ m_savedCollisionFilterMask = handle->m_collisionFilterMask;
+ body->setActivationState(DISABLE_SIMULATION);
+ GetPhysicsEnvironment()->updateCcdPhysicsController(this,
+ btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
+ btBroadphaseProxy::StaticFilter,
+ btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
+ }
}
+
void KX_BulletPhysicsController::RestoreDynamics()
{
- GetRigidBody()->forceActivationState(ACTIVE_TAG);
+ btRigidBody *body = GetRigidBody();
+ if (body->getActivationState() == DISABLE_SIMULATION)
+ {
+ GetRigidBody()->forceActivationState(ACTIVE_TAG);
+ GetPhysicsEnvironment()->updateCcdPhysicsController(this,
+ m_savedCollisionFlags,
+ m_savedCollisionFilterGroup,
+ m_savedCollisionFilterMask);
+ }
}
SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
index 0853755dffa..3d7c7e5b030 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h
@@ -7,7 +7,10 @@
class KX_BulletPhysicsController : public KX_IPhysicsController ,public CcdPhysicsController
{
-
+private:
+ int m_savedCollisionFlags;
+ short int m_savedCollisionFilterGroup;
+ short int m_savedCollisionFilterMask;
public:
KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna);
@@ -39,7 +42,7 @@ public:
virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
- virtual void SuspendDynamics();
+ virtual void SuspendDynamics(bool ghost);
virtual void RestoreDynamics();
virtual SG_Controller* GetReplica(class SG_Node* destnode);
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index 27f4870de10..0a97b6f0a2f 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -49,7 +49,7 @@ STR_String KX_CameraActuator::Y_AXIS_STRING = "y";
KX_CameraActuator::KX_CameraActuator(
SCA_IObject* gameobj,
- CValue *obj,
+ SCA_IObject *obj,
MT_Scalar hght,
MT_Scalar minhght,
MT_Scalar maxhght,
@@ -63,11 +63,14 @@ KX_CameraActuator::KX_CameraActuator(
m_maxHeight (maxhght),
m_x (xytog)
{
+ if (m_ob)
+ m_ob->RegisterActuator(this);
}
KX_CameraActuator::~KX_CameraActuator()
{
- //nothing to do
+ if (m_ob)
+ m_ob->UnregisterActuator(this);
}
CValue*
@@ -81,9 +84,36 @@ GetReplica(
return replica;
};
+void KX_CameraActuator::ProcessReplica()
+{
+ if (m_ob)
+ m_ob->RegisterActuator(this);
+ SCA_IActuator::ProcessReplica();
+}
+bool KX_CameraActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == m_ob)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_ob = NULL;
+ return true;
+ }
+ return false;
+}
+void KX_CameraActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_ob];
+ if (h_obj) {
+ if (m_ob)
+ m_ob->UnregisterActuator(this);
+ m_ob = (SCA_IObject*)(*h_obj);
+ m_ob->RegisterActuator(this);
+ }
+}
+
/* three functions copied from blender arith... don't know if there's an equivalent */
static float Kx_Normalize(float *n)
@@ -181,8 +211,14 @@ static void Kx_VecUpMat3(float *vec, float mat[][3], short axis)
bool KX_CameraActuator::Update(double curtime, bool frame)
{
- bool result = true;
+ /* wondering... is it really neccesary/desirable to suppress negative */
+ /* events here? */
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+ if (bNegativeEvent || !m_ob)
+ return false;
+
KX_GameObject *obj = (KX_GameObject*) GetParent();
MT_Point3 from = obj->NodeGetWorldPosition();
MT_Matrix3x3 frommat = obj->NodeGetWorldOrientation();
@@ -195,13 +231,6 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
float mindistsq, maxdistsq, distsq;
float mat[3][3];
- /* wondering... is it really neccesary/desirable to suppress negative */
- /* events here? */
- bool bNegativeEvent = IsNegativeEvent();
- RemoveAllEvents();
-
- if (bNegativeEvent) return false;
-
/* The rules: */
/* CONSTRAINT 1: not implemented */
/* CONSTRAINT 2: can camera see actor? */
@@ -315,7 +344,7 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
actormat[2][0]= mat[0][2]; actormat[2][1]= mat[1][2]; actormat[2][2]= mat[2][2];
obj->NodeSetLocalOrientation(actormat);
- return result;
+ return true;
}
CValue *KX_CameraActuator::findObject(char *obName)
@@ -404,7 +433,11 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* self,
PyObject* gameobj;
if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj))
{
- m_ob = (CValue*)gameobj;
+ if (m_ob)
+ m_ob->UnregisterActuator(this);
+ m_ob = (SCA_IObject*)gameobj;
+ if (m_ob)
+ m_ob->RegisterActuator(this);
Py_Return;
}
PyErr_Clear();
@@ -412,10 +445,13 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* self,
char* objectname;
if (PyArg_ParseTuple(args, "s", &objectname))
{
- CValue *object = (CValue*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
+ SCA_IObject *object = (SCA_IObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
if(object)
{
+ if (m_ob != NULL)
+ m_ob->UnregisterActuator(this);
m_ob = object;
+ m_ob->RegisterActuator(this);
Py_Return;
}
}
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h
index eb007e403ec..488b36922b0 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.h
+++ b/source/gameengine/Ketsji/KX_CameraActuator.h
@@ -49,7 +49,7 @@ class KX_CameraActuator : public SCA_IActuator
Py_Header;
private :
/** Object that will be tracked. */
- CValue *m_ob;
+ SCA_IObject *m_ob;
/** height (float), */
//const MT_Scalar m_height;
@@ -87,7 +87,7 @@ private :
SCA_IObject *gameobj,
//const CValue *ob,
- CValue *ob,
+ SCA_IObject *ob,
MT_Scalar hght,
MT_Scalar minhght,
MT_Scalar maxhght,
@@ -103,6 +103,7 @@ private :
/** Methods Inherited from CValue */
CValue* GetReplica();
+ virtual void ProcessReplica();
/** Methods inherited from SCA_IActuator */
@@ -110,7 +111,10 @@ private :
double curtime,
bool frame
);
+ virtual bool UnlinkObject(SCA_IObject* clientobj);
+ /** Methods inherited from SCA_ILogicBrick */
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 2ac4f909077..1845fdd7b50 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -61,6 +61,8 @@ typedef unsigned long uint_ptr;
#include "KX_RayCast.h"
#include "KX_PythonInit.h"
#include "KX_PyMath.h"
+#include "SCA_IActuator.h"
+#include "SCA_ISensor.h"
// This file defines relationships between parents and children
// in the game engine.
@@ -238,6 +240,10 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
if (rootlist->RemoveValue(this))
// the object was in parent list, decrement ref count as it's now removed
Release();
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->SuspendDynamics(true);
+ }
}
}
@@ -258,6 +264,10 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
if (!rootlist->SearchValue(this))
// object was not in root list, add it now and increment ref count
rootlist->Add(AddRef());
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->RestoreDynamics();
+ }
}
}
@@ -832,7 +842,7 @@ void KX_GameObject::Resume(void)
}
}
-void KX_GameObject::Suspend(void)
+void KX_GameObject::Suspend()
{
if ((!m_ignore_activity_culling)
&& (!m_suspended)) {
@@ -1660,6 +1670,20 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
* --------------------------------------------------------------------- */
void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter)
{
- /* intentionally empty ? */
+ // we will relink the sensors and actuators that use object references
+ // if the object is part of the replicated hierarchy, use the new
+ // object reference instead
+ SCA_SensorList& sensorlist = GetSensors();
+ SCA_SensorList::iterator sit;
+ for (sit=sensorlist.begin(); sit != sensorlist.end(); sit++)
+ {
+ (*sit)->Relink(map_parameter);
+ }
+ SCA_ActuatorList& actuatorlist = GetActuators();
+ SCA_ActuatorList::iterator ait;
+ for (ait=actuatorlist.begin(); ait != actuatorlist.end(); ait++)
+ {
+ (*ait)->Relink(map_parameter);
+ }
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index ddbf863aa1a..eba154e1094 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -47,6 +47,7 @@
#include "KX_Scene.h"
#include "KX_KetsjiEngine.h" /* for m_anim_framerate */
#include "KX_IPhysicsController.h" /* for suspend/resume */
+#include "DNA_object_types.h"
#define KX_OB_DYNAMIC 1
@@ -392,6 +393,13 @@ public:
m_pBlenderObject = obj;
}
+ bool IsDupliGroup()
+ {
+ return (m_pBlenderObject &&
+ (m_pBlenderObject->transflag & OB_DUPLIGROUP) &&
+ m_pBlenderObject->dup_group != NULL) ? true : false;
+ }
+
/**
* Set the Scene graph node for this game object.
* warning - it is your responsibility to make sure
diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h
index 2ec66a883eb..bc4cc185a04 100644
--- a/source/gameengine/Ketsji/KX_IPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_IPhysicsController.h
@@ -78,7 +78,7 @@ public:
virtual MT_Vector3 getReactionForce()=0;
virtual void setRigidBody(bool rigid)=0;
- virtual void SuspendDynamics()=0;
+ virtual void SuspendDynamics(bool ghost=false)=0;
virtual void RestoreDynamics()=0;
virtual SG_Controller* GetReplica(class SG_Node* destnode)=0;
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 20187a193ba..db099d56b55 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -231,7 +231,10 @@ void KX_KetsjiEngine::SetRasterizer(RAS_IRasterizer* rasterizer)
}
-
+/*
+ * At the moment the GameLogic module is imported into 'pythondictionary' after this function is called.
+ * if this function ever changes to assign a copy, make sure the game logic module is imported into this dictionary before hand.
+ */
void KX_KetsjiEngine::SetPythonDictionary(PyObject* pythondictionary)
{
MT_assert(pythondictionary);
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index d69871275b9..89699d80031 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -135,9 +135,6 @@ CValue* KX_NearSensor::GetReplica()
void KX_NearSensor::ReParent(SCA_IObject* parent)
{
-
- SCA_ISensor::ReParent(parent);
-
m_client_info->m_gameobject = static_cast<KX_GameObject*>(parent);
m_client_info->m_sensors.push_back(this);
@@ -151,6 +148,7 @@ void KX_NearSensor::ReParent(SCA_IObject* parent)
*/
((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
SynchronizeTransform();
+ SCA_ISensor::ReParent(parent);
}
diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp b/source/gameengine/Ketsji/KX_OdePhysicsController.cpp
index 4e45ce484e3..8b0a6dafc22 100644
--- a/source/gameengine/Ketsji/KX_OdePhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_OdePhysicsController.cpp
@@ -177,7 +177,7 @@ void KX_OdePhysicsController::setRigidBody(bool rigid)
}
-void KX_OdePhysicsController::SuspendDynamics()
+void KX_OdePhysicsController::SuspendDynamics(bool)
{
ODEPhysicsController::SuspendDynamics();
}
diff --git a/source/gameengine/Ketsji/KX_OdePhysicsController.h b/source/gameengine/Ketsji/KX_OdePhysicsController.h
index 07a0bee9775..c96c71c81f9 100644
--- a/source/gameengine/Ketsji/KX_OdePhysicsController.h
+++ b/source/gameengine/Ketsji/KX_OdePhysicsController.h
@@ -74,7 +74,7 @@ public:
virtual MT_Vector3 getReactionForce();
virtual void setRigidBody(bool rigid);
- virtual void SuspendDynamics();
+ virtual void SuspendDynamics(bool);
virtual void RestoreDynamics();
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp
index 8b379bcd44f..fd1b56838e2 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp
@@ -46,19 +46,22 @@
KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj,
int mode,
- CValue *ob,
+ SCA_IObject *ob,
PyTypeObject* T)
: SCA_IActuator(gameobj, T),
m_mode(mode),
m_ob(ob)
{
+ if (m_ob)
+ m_ob->RegisterActuator(this);
}
KX_ParentActuator::~KX_ParentActuator()
{
- /* intentionally empty */
+ if (m_ob)
+ m_ob->UnregisterActuator(this);
}
@@ -73,6 +76,36 @@ CValue* KX_ParentActuator::GetReplica()
return replica;
}
+void KX_ParentActuator::ProcessReplica()
+{
+ if (m_ob)
+ m_ob->RegisterActuator(this);
+ SCA_IActuator::ProcessReplica();
+}
+
+
+bool KX_ParentActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == m_ob)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_ob = NULL;
+ return true;
+ }
+ return false;
+}
+
+void KX_ParentActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_ob];
+ if (h_obj) {
+ if (m_ob)
+ m_ob->UnregisterActuator(this);
+ m_ob = (SCA_IObject*)(*h_obj);
+ m_ob->RegisterActuator(this);
+ }
+}
+
bool KX_ParentActuator::Update()
@@ -87,7 +120,8 @@ bool KX_ParentActuator::Update()
KX_Scene *scene = PHY_GetActiveScene();
switch (m_mode) {
case KX_PARENT_SET:
- obj->SetParent(scene, (KX_GameObject*)m_ob);
+ if (m_ob)
+ obj->SetParent(scene, (KX_GameObject*)m_ob);
break;
case KX_PARENT_REMOVE:
obj->RemoveParent(scene);
@@ -148,7 +182,11 @@ PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* args, PyObjec
PyObject* gameobj;
if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj))
{
- m_ob = (CValue*)gameobj;
+ if (m_ob != NULL)
+ m_ob->UnregisterActuator(this);
+ m_ob = (SCA_IObject*)gameobj;
+ if (m_ob)
+ m_ob->RegisterActuator(this);
Py_Return;
}
PyErr_Clear();
@@ -156,10 +194,13 @@ PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* args, PyObjec
char* objectname;
if (PyArg_ParseTuple(args, "s", &objectname))
{
- CValue *object = (CValue*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
+ SCA_IObject *object = (SCA_IObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
if(object)
{
+ if (m_ob != NULL)
+ m_ob->UnregisterActuator(this);
m_ob = object;
+ m_ob->RegisterActuator(this);
Py_Return;
}
}
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h
index 86dcd4e6c12..93b07cd424b 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.h
+++ b/source/gameengine/Ketsji/KX_ParentActuator.h
@@ -47,7 +47,7 @@ class KX_ParentActuator : public SCA_IActuator
int m_mode;
/** Object to set as parent */
- CValue *m_ob;
+ SCA_IObject *m_ob;
@@ -62,12 +62,15 @@ class KX_ParentActuator : public SCA_IActuator
KX_ParentActuator(class SCA_IObject* gameobj,
int mode,
- CValue *ob,
+ SCA_IObject *ob,
PyTypeObject* T=&Type);
virtual ~KX_ParentActuator();
virtual bool Update();
virtual CValue* GetReplica();
+ virtual void ProcessReplica();
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
+ virtual bool UnlinkObject(SCA_IObject* clientobj);
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 433e0636833..61ed8b6a8e4 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -828,20 +828,9 @@ PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook
Py_FatalError("can't initialize module GameLogic");
}
- return d;
+ return m;
}
-void dictionaryClearByHand(PyObject *dict)
-{
- // Clears the dictionary by hand:
- // This prevents, extra references to global variables
- // inside the GameLogic dictionary when the python interpreter is finalized.
- // which allows the scene to safely delete them :)
- // see: (space.c)->start_game
- if(dict) PyDict_Clear(dict);
-}
-
-
// Python Sandbox code
// override builtin functions import() and open()
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
index c7d8f1b78bc..41cf7fd67b3 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.h
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -47,7 +47,6 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
void exitGamePlayerPythonScripting();
PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level);
void exitGamePythonScripting();
-void dictionaryClearByHand(PyObject *dict);
void PHY_SetActiveScene(class KX_Scene* scene);
class KX_Scene* PHY_GetActiveScene();
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index 987e0b946b2..bf2ba18f490 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -80,10 +80,7 @@ CValue* KX_RadarSensor::GetReplica()
{
KX_RadarSensor* replica = new KX_RadarSensor(*this);
replica->m_colliders = new CListValue();
- replica->m_bCollision = false;
- replica->m_bTriggered= false;
- replica->m_hitObject = NULL;
- replica->m_bLastTriggered = false;
+ replica->Init();
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
@@ -92,6 +89,10 @@ CValue* KX_RadarSensor::GetReplica()
if (replica->m_physCtrl)
{
replica->m_physCtrl = replica->m_physCtrl->GetReplica();
+ if (replica->m_physCtrl)
+ {
+ replica->m_physCtrl->setNewClientInfo(replica->m_client_info);
+ }
}
//todo: make sure replication works fine!
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index 76ce086ab97..e36891b56f4 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -48,7 +48,7 @@
/* ------------------------------------------------------------------------- */
KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
- CValue* original,
+ SCA_IObject *original,
int time,
SCA_IScene* scene,
const MT_Vector3& linvel,
@@ -61,6 +61,9 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
m_linear_velocity(linvel),
m_localFlag(local)
{
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
+
m_lastCreatedObject = NULL;
m_timeProp = time;
}
@@ -69,6 +72,8 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
KX_SCA_AddObjectActuator::~KX_SCA_AddObjectActuator()
{
+ if (m_OriginalObject)
+ m_OriginalObject->UnregisterActuator(this);
if (m_lastCreatedObject)
m_lastCreatedObject->Release();
}
@@ -108,12 +113,40 @@ CValue* KX_SCA_AddObjectActuator::GetReplica()
// this will copy properties and so on...
replica->ProcessReplica();
- replica->m_lastCreatedObject=NULL;
CValue::AddDataToReplica(replica);
return replica;
}
+void KX_SCA_AddObjectActuator::ProcessReplica()
+{
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
+ m_lastCreatedObject=NULL;
+ SCA_IActuator::ProcessReplica();
+}
+
+bool KX_SCA_AddObjectActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == m_OriginalObject)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_OriginalObject = NULL;
+ return true;
+ }
+ return false;
+}
+
+void KX_SCA_AddObjectActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_OriginalObject];
+ if (h_obj) {
+ if (m_OriginalObject)
+ m_OriginalObject->UnregisterActuator(this);
+ m_OriginalObject = (SCA_IObject*)(*h_obj);
+ m_OriginalObject->RegisterActuator(this);
+ }
+}
/* ------------------------------------------------------------------------- */
@@ -181,7 +214,11 @@ PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self,
PyObject* gameobj;
if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj))
{
- m_OriginalObject = (CValue*)gameobj;
+ if (m_OriginalObject != NULL)
+ m_OriginalObject->UnregisterActuator(this);
+ m_OriginalObject = (SCA_IObject*)gameobj;
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
Py_Return;
}
PyErr_Clear();
@@ -189,8 +226,11 @@ PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self,
char* objectname;
if (PyArg_ParseTuple(args, "s", &objectname))
{
- m_OriginalObject= (CValue*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));;
-
+ if (m_OriginalObject != NULL)
+ m_OriginalObject->UnregisterActuator(this);
+ m_OriginalObject = (SCA_IObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));;
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
Py_Return;
}
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index 2126a646303..1359f39278d 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -53,7 +53,7 @@ class KX_SCA_AddObjectActuator : public SCA_IActuator
int m_timeProp;
/// Original object reference (object to replicate)
- CValue* m_OriginalObject;
+ SCA_IObject* m_OriginalObject;
/// Object will be added to the following scene
SCA_IScene* m_scene;
@@ -75,7 +75,7 @@ public:
KX_SCA_AddObjectActuator(
SCA_IObject *gameobj,
- CValue* original,
+ SCA_IObject *original,
int time,
SCA_IScene* scene,
const MT_Vector3& linvel,
@@ -89,6 +89,15 @@ public:
GetReplica(
) ;
+ virtual void
+ ProcessReplica();
+
+ virtual bool
+ UnlinkObject(SCA_IObject* clientobj);
+
+ virtual void
+ Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
+
virtual bool
Update();
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 065800379d8..1bdd4002805 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -66,6 +66,8 @@
#include "SG_Controller.h"
#include "SG_IObject.h"
#include "SG_Tree.h"
+#include "DNA_group_types.h"
+#include "BKE_anim.h"
#include "KX_SG_NodeRelationships.h"
@@ -429,6 +431,11 @@ void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gam
KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CValue* gameobj)
{
+ // for group duplication, limit the duplication of the hierarchy to the
+ // objects that are part of the group.
+ if (!IsObjectInGroup(gameobj))
+ return NULL;
+
KX_GameObject* orgobj = (KX_GameObject*)gameobj;
KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica();
m_map_gameobject_to_replica.insert(orgobj, newobj);
@@ -506,6 +513,11 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
// hierarchy that's because first ALL bricks must exist in the new
// replica of the hierarchy in order to make cross-links work properly
// !
+// It is VERY important that the order of sensors and actuators in
+// the replicated object is preserved: it is is used to reconnect the logic.
+// This method is more robust then using the bricks name in case of complex
+// group replication. The replication of logic bricks is done in
+// SCA_IObject::ReParentLogic(), make sure it preserves the order of the bricks.
void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
{
// also relink the controller to sensors/actuators
@@ -528,37 +540,38 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++)
{
SCA_ISensor* oldsensor = (*its);
- STR_String name = oldsensor->GetName();
- //find this name in the list
- SCA_ISensor* newsensor = newobj->FindSensor(name);
+ SCA_IObject* oldsensorobj = oldsensor->GetParent();
+ SCA_IObject* newsensorobj = NULL;
- if (newsensor)
+ // the original owner of the sensor has been replicated?
+ void **h_obj = m_map_gameobject_to_replica[oldsensorobj];
+ if (h_obj)
+ newsensorobj = (SCA_IObject*)(*h_obj);
+ if (!newsensorobj)
{
- // relink this newsensor to the controller
- m_logicmgr->RegisterToSensor(cont,newsensor);
+ // no, then the sensor points outside the hierachy, keep it the same
+ if (m_objectlist->SearchValue(oldsensorobj))
+ // only replicate links that points to active objects
+ m_logicmgr->RegisterToSensor(cont,oldsensor);
}
else
{
- // it can be linked somewhere in the hierarchy or...
- for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
- !(git==m_logicHierarchicalGameObjects.end());++git)
- {
- newsensor = (*git)->FindSensor(name);
- if (newsensor)
- break;
- }
+ // yes, then the new sensor has the same position
+ SCA_SensorList& sensorlist = oldsensorobj->GetSensors();
+ SCA_SensorList::iterator sit;
+ SCA_ISensor* newsensor = NULL;
+ int sensorpos;
- if (newsensor)
- {
- // relink this newsensor to the controller somewhere else within this
- // hierarchy
- m_logicmgr->RegisterToSensor(cont,newsensor);
- }
- else
+ for (sensorpos=0, sit=sensorlist.begin(); sit!=sensorlist.end(); sit++, sensorpos++)
{
- // must be an external sensor, so...
- m_logicmgr->RegisterToSensor(cont,oldsensor);
+ if ((*sit) == oldsensor)
+ {
+ newsensor = newsensorobj->GetSensors().at(sensorpos);
+ break;
+ }
}
+ assert(newsensor != NULL);
+ m_logicmgr->RegisterToSensor(cont,newsensor);
}
}
@@ -566,38 +579,40 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++)
{
SCA_IActuator* oldactuator = (*ita);
- STR_String name = oldactuator->GetName();
- //find this name in the list
- SCA_IActuator* newactuator = newobj->FindActuator(name);
- if (newactuator)
+ SCA_IObject* oldactuatorobj = oldactuator->GetParent();
+ SCA_IObject* newactuatorobj = NULL;
+
+ // the original owner of the sensor has been replicated?
+ void **h_obj = m_map_gameobject_to_replica[oldactuatorobj];
+ if (h_obj)
+ newactuatorobj = (SCA_IObject*)(*h_obj);
+
+ if (!newactuatorobj)
{
- // relink this newsensor to the controller
- m_logicmgr->RegisterToActuator(cont,newactuator);
- newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
+ // no, then the sensor points outside the hierachy, keep it the same
+ if (m_objectlist->SearchValue(oldactuatorobj))
+ // only replicate links that points to active objects
+ m_logicmgr->RegisterToActuator(cont,oldactuator);
}
else
{
- // it can be linked somewhere in the hierarchy or...
- for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin();
- !(git==m_logicHierarchicalGameObjects.end());++git)
- {
- newactuator= (*git)->FindActuator(name);
- if (newactuator)
- break;
- }
+ // yes, then the new sensor has the same position
+ SCA_ActuatorList& actuatorlist = oldactuatorobj->GetActuators();
+ SCA_ActuatorList::iterator ait;
+ SCA_IActuator* newactuator = NULL;
+ int actuatorpos;
- if (newactuator)
+ for (actuatorpos=0, ait=actuatorlist.begin(); ait!=actuatorlist.end(); ait++, actuatorpos++)
{
- // relink this actuator to the controller somewhere else within this
- // hierarchy
- m_logicmgr->RegisterToActuator(cont,newactuator);
- newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
- }
- else
- {
- // must be an external actuator, so...
- m_logicmgr->RegisterToActuator(cont,oldactuator);
+ if ((*ait) == oldactuator)
+ {
+ newactuator = newactuatorobj->GetActuators().at(actuatorpos);
+ break;
+ }
}
+ assert(newactuator != NULL);
+ m_logicmgr->RegisterToActuator(cont,newactuator);
+ newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
}
}
}
@@ -605,6 +620,146 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
newobj->ResetState();
}
+void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
+{
+ KX_GameObject* groupobj = (KX_GameObject*) obj;
+ KX_GameObject* replica;
+ KX_GameObject* gameobj;
+ Object* blgroupobj = groupobj->GetBlenderObject();
+ Group* group;
+ GroupObject *go;
+ vector<KX_GameObject*> duplilist;
+
+ if (!groupobj->IsDupliGroup() ||
+ level>MAX_DUPLI_RECUR)
+ return;
+
+ // we will add one group at a time
+ m_logicHierarchicalGameObjects.clear();
+ m_map_gameobject_to_replica.clear();
+ m_ueberExecutionPriority++;
+ // for groups will do something special:
+ // we will force the creation of objects to those in the group only
+ // Again, this is match what Blender is doing (it doesn't care of parent relationship)
+ m_groupGameObjects.clear();
+
+ group = blgroupobj->dup_group;
+ for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
+ {
+ Object* blenderobj = go->ob;
+ if (blgroupobj == blenderobj)
+ // this check is also in group_duplilist()
+ continue;
+ gameobj = m_sceneConverter->FindGameObject(blenderobj);
+ if (gameobj == NULL)
+ {
+ // this object has not been converted!!!
+ // Should not happen as dupli group are created automatically
+ continue;
+ }
+ if (blenderobj->lay & group->layer==0)
+ {
+ // object is not visible in the 3D view, will not be instantiated
+ continue;
+ }
+ m_groupGameObjects.insert(gameobj);
+ }
+
+ set<CValue*>::iterator oit;
+ for (oit=m_groupGameObjects.begin(); oit != m_groupGameObjects.end(); oit++)
+ {
+ gameobj = (KX_GameObject*)(*oit);
+ if (gameobj->GetParent() != NULL)
+ {
+ // this object is not a top parent. Either it is the child of another
+ // object in the group and it will be added automatically when the parent
+ // is added. Or it is the child of an object outside the group and the group
+ // is inconsistent, skip it anyway
+ continue;
+ }
+ replica = (KX_GameObject*) AddNodeReplicaObject(NULL,gameobj);
+ // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame)
+ m_parentlist->Add(replica->AddRef());
+
+ // recurse replication into children nodes
+ NodeList& children = gameobj->GetSGNode()->GetSGChildren();
+
+ replica->GetSGNode()->ClearSGChildren();
+ for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
+ {
+ SG_Node* orgnode = (*childit);
+ SG_Node* childreplicanode = orgnode->GetSGReplica();
+ if (childreplicanode)
+ replica->GetSGNode()->AddChild(childreplicanode);
+ }
+ // don't replicate logic now: we assume that the objects in the group can have
+ // logic relationship, even outside parent relationship
+ // In order to match 3D view, the position of groupobj is used as a
+ // transformation matrix instead of the new position. This means that
+ // the group reference point is 0,0,0
+
+ // get the rootnode's scale
+ MT_Vector3 newscale = groupobj->NodeGetWorldScaling();
+ // set the replica's relative scale with the rootnode's scale
+ replica->NodeSetRelativeScale(newscale);
+
+ MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation();
+ replica->NodeSetLocalOrientation(newori);
+
+ MT_Point3 newpos = groupobj->NodeGetWorldPosition() +
+ newscale*(groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldPosition());
+ replica->NodeSetLocalPosition(newpos);
+
+ if (replica->GetPhysicsController())
+ {
+ replica->GetPhysicsController()->setPosition(newpos);
+ replica->GetPhysicsController()->setOrientation(newori.getRotation());
+ replica->GetPhysicsController()->setScaling(newscale);
+ }
+
+ replica->GetSGNode()->UpdateWorldData(0);
+ replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox());
+ replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius());
+ // done with replica
+ replica->Release();
+ }
+
+ // 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)
+ {
+ // this will also relink the actuator to objects within the hierarchy
+ (*git)->Relink(&m_map_gameobject_to_replica);
+ // add the object in the layer of the parent
+ (*git)->SetLayer(groupobj->GetLayer());
+ }
+
+ // replicate crosslinks etc. between logic bricks
+ for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
+ {
+ ReplicateLogic((*git));
+ }
+
+ // 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())
+ // can't instantiate group immediately as it destroys m_logicHierarchicalGameObjects
+ duplilist.push_back((*git));
+ }
+
+ for (git = duplilist.begin(); !(git == duplilist.end()); ++git)
+ {
+ DupliGroupRecurse((*git), level+1);
+ }
+}
SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
@@ -614,6 +769,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
m_logicHierarchicalGameObjects.clear();
m_map_gameobject_to_replica.clear();
+ m_groupGameObjects.clear();
// todo: place a timebomb in the object, for temporarily objects :)
// lifespan of zero means 'this object lives forever'
@@ -647,24 +803,26 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
{
SG_Node* orgnode = (*childit);
SG_Node* childreplicanode = orgnode->GetSGReplica();
- replica->GetSGNode()->AddChild(childreplicanode);
+ if (childreplicanode)
+ replica->GetSGNode()->AddChild(childreplicanode);
}
- // relink any pointers as necessary, sort of a temporary solution
+ // now replicate logic
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)
+ {
+ // 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());
}
- // now replicate logic
- for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
- {
- (*git)->ReParentLogic();
- }
-
// replicate crosslinks etc. between logic bricks
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
{
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 28dee1b5893..80a2abe287a 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -216,6 +216,16 @@ protected:
*/
std::vector<KX_GameObject*> m_logicHierarchicalGameObjects;
+ /**
+ * This temporary variable will contain the list of
+ * object that can be added during group instantiation.
+ * objects outside this list will not be added (can
+ * happen with children that are outside the group).
+ * Used in AddReplicaObject. If the list is empty, it
+ * means don't care.
+ */
+ std::set<CValue*> m_groupGameObjects;
+
/**
* Pointer to system variable passed in in constructor
* only used in constructor so we do not need to keep it
@@ -291,6 +301,12 @@ public:
* Update all transforms according to the scenegraph.
*/
void UpdateParents(double curtime);
+ void DupliGroupRecurse(CValue* gameobj, int level);
+ bool IsObjectInGroup(CValue* gameobj)
+ {
+ return (m_groupGameObjects.empty() ||
+ m_groupGameObjects.find(gameobj) != m_groupGameObjects.end());
+ }
SCA_IObject* AddReplicaObject(CValue* gameobj,
CValue* locationobj,
int lifespan=0);
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp
index 8f7cffd506f..d6164dc812a 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp
@@ -58,13 +58,16 @@ KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj,
m_KetsjiEngine=ketsjiEngine;
m_camera = camera;
m_nextSceneName = nextSceneName;
+ if (m_camera)
+ m_camera->RegisterActuator(this);
} /* End of constructor */
KX_SceneActuator::~KX_SceneActuator()
{
- // there's nothing to be done here, really....
+ if (m_camera)
+ m_camera->UnregisterActuator(this);
} /* end of destructor */
@@ -79,6 +82,34 @@ CValue* KX_SceneActuator::GetReplica()
return replica;
}
+void KX_SceneActuator::ProcessReplica()
+{
+ if (m_camera)
+ m_camera->RegisterActuator(this);
+ SCA_IActuator::ProcessReplica();
+}
+
+bool KX_SceneActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == (SCA_IObject*)m_camera)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_camera = NULL;
+ return true;
+ }
+ return false;
+}
+
+void KX_SceneActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_camera];
+ if (h_obj) {
+ if (m_camera)
+ m_camera->UnregisterActuator(this);
+ m_camera = (KX_Camera*)(*h_obj);
+ m_camera->RegisterActuator(this);
+ }
+}
bool KX_SceneActuator::Update()
@@ -332,7 +363,11 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self,
PyObject *cam;
if (PyArg_ParseTuple(args, "O!", &KX_Camera::Type, &cam))
{
+ if (m_camera)
+ m_camera->UnregisterActuator(this);
m_camera = (KX_Camera*) cam;
+ if (m_camera)
+ m_camera->RegisterActuator(this);
Py_Return;
}
PyErr_Clear();
@@ -345,7 +380,13 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self,
}
KX_Camera *camOb = FindCamera(camName);
- if (camOb) m_camera = camOb;
+ if (camOb)
+ {
+ if (m_camera)
+ m_camera->UnregisterActuator(this);
+ m_camera = camOb;
+ m_camera->RegisterActuator(this);
+ }
Py_Return;
}
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h
index cfc79b93f8e..55aaf629d7c 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.h
+++ b/source/gameengine/Ketsji/KX_SceneActuator.h
@@ -82,6 +82,9 @@ class KX_SceneActuator : public SCA_IActuator
virtual ~KX_SceneActuator();
virtual CValue* GetReplica();
+ virtual void ProcessReplica();
+ virtual bool UnlinkObject(SCA_IObject* clientobj);
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool Update();
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index 949156571a7..34a3baec093 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -291,7 +291,8 @@ PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObje
char* name = objectname.Ptr();
if (!name) {
- Py_Return; /* internal error */
+ PyErr_SetString(PyExc_RuntimeError, "Unable to get sound filename");
+ return NULL;
} else
return PyString_FromString(name);
}
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
index 6ea5461dbaa..ffb078b346e 100644
--- a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp
@@ -101,7 +101,7 @@ void KX_SumoPhysicsController::SetSumoTransform(bool nondynaonly)
}
-void KX_SumoPhysicsController::SuspendDynamics()
+void KX_SumoPhysicsController::SuspendDynamics(bool)
{
SumoPhysicsController::SuspendDynamics();
}
diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
index 8c061ae4056..33666036c0d 100644
--- a/source/gameengine/Ketsji/KX_SumoPhysicsController.h
+++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h
@@ -76,7 +76,7 @@ public:
void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
- void SuspendDynamics();
+ void SuspendDynamics(bool);
void RestoreDynamics();
virtual void getOrientation(MT_Quaternion& orn);
virtual void setOrientation(const MT_Quaternion& orn);
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index 731a610c2eb..c580aa4d4e5 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -210,6 +210,18 @@ bool KX_TrackToActuator::UnlinkObject(SCA_IObject* clientobj)
return false;
}
+void KX_TrackToActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
+{
+ void **h_obj = (*obj_map)[m_object];
+ if (h_obj) {
+ if (m_object)
+ m_object->UnregisterActuator(this);
+ m_object = (SCA_IObject*)(*h_obj);
+ m_object->RegisterActuator(this);
+ }
+}
+
+
bool KX_TrackToActuator::Update(double curtime, bool frame)
{
bool result = false;
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h
index a03aa115baa..1d1cf46d21b 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.h
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.h
@@ -68,6 +68,7 @@ class KX_TrackToActuator : public SCA_IActuator
virtual void ProcessReplica();
virtual bool UnlinkObject(SCA_IObject* clientobj);
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool Update(double curtime, bool frame);
/* Python part */
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index c9d346e316d..7f5457121ea 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -466,6 +466,16 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
}
+void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
+{
+ // this function is used when the collisionning group of a controller is changed
+ // remove and add the collistioning object
+ btRigidBody* body = ctrl->GetRigidBody();
+
+ m_dynamicsWorld->removeCollisionObject(body);
+ body->setCollisionFlags(newCollisionFlags);
+ m_dynamicsWorld->addCollisionObject(body, newCollisionGroup, newCollisionMask);
+}
void CcdPhysicsEnvironment::beginFrame()
{
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 9f14cf6cbef..dff17517b85 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -183,6 +183,8 @@ protected:
void removeCcdPhysicsController(CcdPhysicsController* ctrl);
+ void updateCcdPhysicsController(CcdPhysicsController* ctrl, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
+
btBroadphaseInterface* getBroadphase();
diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt
index 18a755afefd..6d53ee53471 100644
--- a/source/gameengine/Rasterizer/CMakeLists.txt
+++ b/source/gameengine/Rasterizer/CMakeLists.txt
@@ -32,6 +32,8 @@ SET(INC
../../../intern/string
../../../intern/moto/include
../../../extern/glew/include
+ ../Expressions
+ ${PYTHON_INC}
)
BLENDERLIB(bf_rasterizer "${SRC}" "${INC}")
diff --git a/source/gameengine/Rasterizer/Makefile b/source/gameengine/Rasterizer/Makefile
index 1ca3e3b0283..e3b1f274ee5 100644
--- a/source/gameengine/Rasterizer/Makefile
+++ b/source/gameengine/Rasterizer/Makefile
@@ -41,6 +41,9 @@ CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I../../kernel/gen_system
CPPFLAGS += -I../BlenderRoutines
+CPPFLAGS += -I../Expressions
+
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
ifeq ($(OS),darwin)
CPPFLAGS += -fpascal-strings
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index 23153fcd86c..958fead33ce 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -52,6 +52,7 @@
#include <config.h>
#endif
+#include "Value.h"
RAS_2DFilterManager::RAS_2DFilterManager():
texturewidth(-1), textureheight(-1),
@@ -73,12 +74,14 @@ numberoffilters(0)
m_filters[passindex] = 0;
m_enabled[passindex] = 0;
texflag[passindex] = 0;
+ m_gameObjects[passindex] = NULL;
}
texname[0] = texname[1] = texname[2] = -1;
}
RAS_2DFilterManager::~RAS_2DFilterManager()
{
+ FreeTextures();
}
unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource)
@@ -150,6 +153,27 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode)
}
return 0;
}
+void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames)
+{
+ texflag[passindex] = 0;
+ if(glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1)
+ {
+ texflag[passindex] |= 0x1;
+ }
+ if(glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture") != -1)
+ {
+ texflag[passindex] |= 0x2;
+ }
+
+ if(m_gameObjects[passindex])
+ {
+ int objProperties = propNames.size();
+ int i;
+ for(i=0; i<objProperties; i++)
+ if(glGetUniformLocationARB(m_filters[passindex], propNames[i]) != -1)
+ m_properties[passindex].push_back(propNames[i]);
+ }
+}
void RAS_2DFilterManager::StartShaderProgram(int passindex)
{
@@ -177,7 +201,7 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
}
/* send luminance texture to glsl program if it needs */
- if(texflag[passindex] & 0x1){
+ if(texflag[passindex] & 0x2){
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture");
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
@@ -203,6 +227,17 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
{
glUniform1fARB(uniformLoc,textureheight);
}
+
+ int i, objProperties = m_properties[passindex].size();
+ for(i=0; i<objProperties; i++)
+ {
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], m_properties[passindex][i]);
+ if(uniformLoc != -1)
+ {
+ float value = ((CValue*)m_gameObjects[passindex])->GetPropertyNumber(m_properties[passindex][i], 0.0);
+ glUniform1fARB(uniformLoc,value);
+ }
+ }
}
void RAS_2DFilterManager::EndShaderProgram()
@@ -210,14 +245,21 @@ void RAS_2DFilterManager::EndShaderProgram()
glUseProgramObjectARB(0);
}
-void RAS_2DFilterManager::SetupTexture()
+void RAS_2DFilterManager::FreeTextures()
{
- if(texname[0]!=-1 || texname[1]!=-1)
- {
- glDeleteTextures(2, (GLuint*)texname);
- }
- glGenTextures(3, (GLuint*)texname);
+ if(texname[0]!=-1)
+ glDeleteTextures(1, (GLuint*)&texname[0]);
+ if(texname[1]!=-1)
+ glDeleteTextures(1, (GLuint*)&texname[1]);
+ if(texname[2]!=-1)
+ glDeleteTextures(1, (GLuint*)&texname[2]);
+}
+void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
+{
+ FreeTextures();
+
+ glGenTextures(1, (GLuint*)&texname[0]);
glBindTexture(GL_TEXTURE_2D, texname[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturewidth, textureheight, 0, GL_RGB,
GL_UNSIGNED_BYTE, 0);
@@ -226,23 +268,29 @@ void RAS_2DFilterManager::SetupTexture()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glBindTexture(GL_TEXTURE_2D, texname[1]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight, 0, GL_DEPTH_COMPONENT,
- GL_FLOAT,NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
+ if(depth){
+ glGenTextures(1, (GLuint*)&texname[1]);
+ glBindTexture(GL_TEXTURE_2D, texname[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight,
+ 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
GL_NONE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
- glBindTexture(GL_TEXTURE_2D, texname[2]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight, 0, GL_LUMINANCE,
- GL_UNSIGNED_BYTE, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
+
+ if(luminance){
+ glGenTextures(1, (GLuint*)&texname[2]);
+ glBindTexture(GL_TEXTURE_2D, texname[2]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight,
+ 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
}
void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height)
@@ -273,62 +321,72 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height)
textureoffsets[(((i*3)+j)*2)+1] = (-1.0f * yInc) + ((GLfloat)j * yInc);
}
}
-
- SetupTexture();
}
void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
{
+ bool need_depth=false;
+ bool need_luminance=false;
+ int num_filters = 0;
+
+ int passindex;
+
if(!isshadersupported)
return;
+ for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
+ {
+ if(m_filters[passindex] && m_enabled[passindex]){
+ num_filters ++;
+ if(texflag[passindex] & 0x1)
+ need_depth = true;
+ if(texflag[passindex] & 0x2)
+ need_luminance = true;
+ if(need_depth && need_luminance)
+ break;
+ }
+ }
+
+ if(num_filters <= 0)
+ return;
+
if(canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight())
{
UpdateOffsetMatrix(canvas->GetWidth(), canvas->GetHeight());
+ SetupTextures(need_depth, need_luminance);
}
GLuint viewport[4]={0};
- int passindex;
- bool first = true;
+ if(need_depth){
+ glActiveTextureARB(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, texname[1]);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0);
+ }
+
+ if(need_luminance){
+ glActiveTextureARB(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, texname[2]);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0);
+ }
+
+ glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
+ glViewport(0, 0, texturewidth, textureheight);
+
+ glDisable(GL_DEPTH_TEST);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
{
if(m_filters[passindex] && m_enabled[passindex])
{
- if(first)
- {
- /* this pass needs depth texture*/
- if(texflag[passindex] & 0x1){
- glActiveTextureARB(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texname[1]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0);
- }
-
- /* this pass needs luminance texture*/
- if(texflag[passindex] & 0x2){
- glActiveTextureARB(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, texname[2]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0);
- }
-
- glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
- glViewport(0, 0, texturewidth, textureheight);
-
- glDisable(GL_DEPTH_TEST);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- first = false;
- }
-
StartShaderProgram(passindex);
-
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0);
-
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
@@ -341,15 +399,12 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
}
- if(!first)
- {
- glEnable(GL_DEPTH_TEST);
- glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
- EndShaderProgram();
- }
+ glEnable(GL_DEPTH_TEST);
+ glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
+ EndShaderProgram();
}
-void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag)
+void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text)
{
if(!isshadersupported)
return;
@@ -374,16 +429,19 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str
glDeleteObjectARB(m_filters[pass]);
m_enabled[pass] = 0;
m_filters[pass] = 0;
+ m_gameObjects[pass] = NULL;
+ m_properties[pass].clear();
texflag[pass] = 0;
return;
}
if(mode == RAS_2DFILTER_CUSTOMFILTER)
{
- texflag[pass] = tflag;
if(m_filters[pass])
glDeleteObjectARB(m_filters[pass]);
m_filters[pass] = CreateShaderProgram(text.Ptr());
+ m_gameObjects[pass] = gameObj;
+ AnalyseShader(pass, propNames);
m_enabled[pass] = 1;
return;
}
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
index faf7c652388..9d8326b96de 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
@@ -28,8 +28,6 @@
#ifndef __RAS_I2DFILTER
#define __RAS_I2DFILTER
-
-
#define MAX_RENDER_PASS 100
class RAS_2DFilterManager
@@ -37,9 +35,15 @@ class RAS_2DFilterManager
private:
unsigned int CreateShaderProgram(char* shadersource);
unsigned int CreateShaderProgram(int filtermode);
+ void AnalyseShader(int passindex, vector<STR_String>& propNames);
void StartShaderProgram(int passindex);
void EndShaderProgram();
+ void SetupTextures(bool depth, bool luminance);
+ void FreeTextures();
+
+ void UpdateOffsetMatrix(int width, int height);
+
float textureoffsets[18];
float view[4];
/* texname[0] contains render to texture, texname[1] contains depth texture, texname[2] contains luminance texture*/
@@ -54,6 +58,13 @@ private:
short texflag[MAX_RENDER_PASS];
bool isshadersupported;
+
+ unsigned int m_filters[MAX_RENDER_PASS];
+ short m_enabled[MAX_RENDER_PASS];
+
+ // stores object properties to send to shaders in each pass
+ vector<STR_String> m_properties[MAX_RENDER_PASS];
+ void* m_gameObjects[MAX_RENDER_PASS];
public:
enum RAS_2DFILTER_MODE {
RAS_2DFILTER_ENABLED = -2,
@@ -74,19 +85,12 @@ public:
RAS_2DFILTER_NUMBER_OF_FILTERS
};
- unsigned int m_filters[MAX_RENDER_PASS];
- short m_enabled[MAX_RENDER_PASS];
-
RAS_2DFilterManager();
~RAS_2DFilterManager();
- void SetupTexture();
-
- void UpdateOffsetMatrix(int width, int height);
-
void RenderFilters(RAS_ICanvas* canvas);
- void EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag);
+ void EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text);
};
#endif
diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h
index 781f90d4124..54a663ba111 100644
--- a/source/gameengine/Rasterizer/RAS_IRenderTools.h
+++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h
@@ -185,7 +185,7 @@ public:
virtual
void
- Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short textureflag)=0;
+ Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)=0;
virtual
void
diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript
index f077833b850..e6bc657ed6d 100644
--- a/source/gameengine/Rasterizer/SConscript
+++ b/source/gameengine/Rasterizer/SConscript
@@ -7,7 +7,8 @@ if env['WITH_BF_GLEXT'] == 1:
env['CPPFLAGS'].append('-DWITH_GLEXT')
-incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include'
+incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions'
+incs += ' ' + env['BF_PYTHON_INC']
if env['OURPLATFORM']=='win32-vc':
cflags = []
diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp
index c347bbc6d9a..d0bdac5c8f0 100644
--- a/source/gameengine/SceneGraph/SG_IObject.cpp
+++ b/source/gameengine/SceneGraph/SG_IObject.cpp
@@ -104,7 +104,7 @@ SetSGClientObject(
}
- void
+ bool
SG_IObject::
ActivateReplicationCallback(
SG_IObject *replica
@@ -112,8 +112,10 @@ ActivateReplicationCallback(
if (m_callbacks.m_replicafunc)
{
// Call client provided replication func
- m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo);
+ if (m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo) == NULL)
+ return false;
}
+ return true;
};
void
diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h
index 438ab48c556..7f6bdfbbb1c 100644
--- a/source/gameengine/SceneGraph/SG_IObject.h
+++ b/source/gameengine/SceneGraph/SG_IObject.h
@@ -202,7 +202,7 @@ public:
protected :
- void
+ bool
ActivateReplicationCallback(
SG_IObject *replica
);
diff --git a/source/gameengine/SceneGraph/SG_Node.cpp b/source/gameengine/SceneGraph/SG_Node.cpp
index 4e90d7c4653..8de7ac83477 100644
--- a/source/gameengine/SceneGraph/SG_Node.cpp
+++ b/source/gameengine/SceneGraph/SG_Node.cpp
@@ -68,7 +68,7 @@ SG_Node* SG_Node::GetSGReplica()
SG_Node* replica = new SG_Node(*this);
if (replica == NULL) return NULL;
- ProcessSGReplica(replica);
+ ProcessSGReplica(&replica);
return replica;
}
@@ -76,25 +76,42 @@ SG_Node* SG_Node::GetSGReplica()
void
SG_Node::
ProcessSGReplica(
- SG_Node* replica
+ SG_Node** replica
){
// Apply the replication call back function.
- ActivateReplicationCallback(replica);
+ if (!ActivateReplicationCallback(*replica))
+ {
+ delete (*replica);
+ *replica = NULL;
+ return;
+ }
// clear the replica node of it's parent.
- static_cast<SG_Node*>(replica)->m_SGparent = NULL;
+ static_cast<SG_Node*>(*replica)->m_SGparent = NULL;
if (m_children.begin() != m_children.end())
{
// if this node has children, the replica has too, so clear and clone children
- replica->ClearSGChildren();
+ (*replica)->ClearSGChildren();
NodeList::iterator childit;
for (childit = m_children.begin();childit!=m_children.end();++childit)
{
- replica->AddChild((*childit)->GetSGReplica());
+ SG_Node* childnode = (*childit)->GetSGReplica();
+ if (childnode)
+ (*replica)->AddChild(childnode);
}
}
+ // Nodes without children and without client object are
+ // not worth to keep, they will just take up CPU
+ // This can happen in partial replication of hierarchy
+ // during group duplication.
+ if ((*replica)->m_children.empty() &&
+ (*replica)->GetSGClientObject() == NULL)
+ {
+ delete (*replica);
+ *replica = NULL;
+ }
}
diff --git a/source/gameengine/SceneGraph/SG_Node.h b/source/gameengine/SceneGraph/SG_Node.h
index f86e3046d93..ffaaad861e2 100644
--- a/source/gameengine/SceneGraph/SG_Node.h
+++ b/source/gameengine/SceneGraph/SG_Node.h
@@ -205,7 +205,7 @@ private:
void
ProcessSGReplica(
- SG_Node* replica
+ SG_Node** replica
);
/**