BGE: Occlusion culling and other performance improvements.
Added occlusion culling capability in the BGE. More info: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.49/Game_Engine#BGE_Scenegraph_improvement MSVC, scons, cmake, Makefile updated. Other minor performance improvements: - The rasterizer was computing the openGL model matrix of the objects too many times - DBVT view frustrum culling was not properly culling behind the near plane: Large objects behind the camera were sent to the GPU - Remove all references to mesh split/join feature as it is not yet functional
This commit is contained in:
parent
6f12e584a9
commit
0b8661ab4d
@ -81,6 +81,7 @@
|
|||||||
AdditionalLibraryDirectories="..\..\..\lib\windows\sdl\lib;..\..\..\lib\windows\ode\lib;..\..\..\lib\windows\zlib\lib;..\..\..\lib\windows\png\lib;..\..\..\lib\windows\jpeg\lib;..\..\..\lib\windows\gettext\lib;..\..\..\lib\windows\python\lib\lib25_vs2008;..\..\..\lib\windows\freetype\lib;..\..\..\lib\windows\tiff\lib;..\..\..\lib\windows\pthreads\lib;..\..\..\lib\windows\openal\lib;..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\build\msvc_9\libs\intern;..\..\..\build\msvc_9\libs\extern;..\..\..\lib\windows\ffmpeg\lib"
|
AdditionalLibraryDirectories="..\..\..\lib\windows\sdl\lib;..\..\..\lib\windows\ode\lib;..\..\..\lib\windows\zlib\lib;..\..\..\lib\windows\png\lib;..\..\..\lib\windows\jpeg\lib;..\..\..\lib\windows\gettext\lib;..\..\..\lib\windows\python\lib\lib25_vs2008;..\..\..\lib\windows\freetype\lib;..\..\..\lib\windows\tiff\lib;..\..\..\lib\windows\pthreads\lib;..\..\..\lib\windows\openal\lib;..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\build\msvc_9\libs\intern;..\..\..\build\msvc_9\libs\extern;..\..\..\lib\windows\ffmpeg\lib"
|
||||||
IgnoreAllDefaultLibraries="false"
|
IgnoreAllDefaultLibraries="false"
|
||||||
IgnoreDefaultLibraryNames="msvcprt.lib;glut32.lib;libc.lib;libcd.lib;libcpd.lib;libcp.lib;libcmtd.lib;odbc32.lib;odbccp32.lib"
|
IgnoreDefaultLibraryNames="msvcprt.lib;glut32.lib;libc.lib;libcd.lib;libcpd.lib;libcp.lib;libcmtd.lib;odbc32.lib;odbccp32.lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
ProgramDatabaseFile="..\..\..\build\msvc_9\libs\blender.pdb"
|
ProgramDatabaseFile="..\..\..\build\msvc_9\libs\blender.pdb"
|
||||||
SubSystem="1"
|
SubSystem="1"
|
||||||
RandomizedBaseAddress="1"
|
RandomizedBaseAddress="1"
|
||||||
@ -167,7 +168,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386
"
|
AdditionalOptions="/MACHINE:I386
"
|
||||||
AdditionalDependencies="SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib openal_static.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half.lib Iex.lib Imath.lib IlmImf.lib IlmThread.lib avcodec-52.lib avformat-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib"
|
AdditionalDependencies="SDL.lib freetype2ST.lib gnu_gettext.lib qtmlClient.lib openal_static.lib ws2_32.lib dxguid.lib opengl32.lib libjpeg.lib glu32.lib vfw32.lib winmm.lib libpng_st.lib zlib.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib libtiff.lib Half_d.lib Iex_d.lib Imath_d.lib IlmImf_d.lib IlmThread_d.lib avcodec-52.lib avformat-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib"
|
||||||
ShowProgress="0"
|
ShowProgress="0"
|
||||||
OutputFile="..\..\bin\debug\blender.exe"
|
OutputFile="..\..\bin\debug\blender.exe"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386
"
|
AdditionalOptions="/MACHINE:I386
"
|
||||||
AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib"
|
AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half_d.lib Iex_d.lib IlmImf_d.lib IlmThread_d.lib Imath_d.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib"
|
||||||
ShowProgress="0"
|
ShowProgress="0"
|
||||||
OutputFile="..\..\..\..\bin\debug\blenderplayer.exe"
|
OutputFile="..\..\..\..\bin\debug\blenderplayer.exe"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
AdditionalIncludeDirectories="..\..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\gameengine\Ketsji;..\..\..\..\..\source\gameengine\Expressions;..\..\..\..\..\source\gameengine\GameLogic;..\..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
MinimalRebuild="false"
|
MinimalRebuild="false"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@ -110,7 +110,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
AdditionalIncludeDirectories="..\..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\gameengine\Ketsji;..\..\..\..\..\source\gameengine\Expressions;..\..\..\..\..\source\gameengine\GameLogic;..\..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@ -176,7 +176,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
AdditionalIncludeDirectories="..\..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\gameengine\Ketsji;..\..\..\..\..\source\gameengine\Expressions;..\..\..\..\..\source\gameengine\GameLogic;..\..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||||
RuntimeLibrary="0"
|
RuntimeLibrary="0"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
@ -243,7 +243,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
AdditionalIncludeDirectories="..\..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\gameengine\Ketsji;..\..\..\..\..\source\gameengine\Expressions;..\..\..\..\..\source\gameengine\GameLogic;..\..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
MinimalRebuild="false"
|
MinimalRebuild="false"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@ -312,7 +312,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
AdditionalIncludeDirectories="..\..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\gameengine\Ketsji;..\..\..\..\..\source\gameengine\Expressions;..\..\..\..\..\source\gameengine\GameLogic;..\..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||||
MinimalRebuild="false"
|
MinimalRebuild="false"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
@ -380,7 +380,7 @@
|
|||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories="..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
AdditionalIncludeDirectories="..\..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\source\gameengine\Physics\common;..\..\..\..\..\source\gameengine\Physics\Bullet;..\..\..\..\..\source\gameengine\Rasterizer;..\..\..\..\..\source\gameengine\Ketsji;..\..\..\..\..\source\gameengine\Expressions;..\..\..\..\..\source\gameengine\GameLogic;..\..\..\..\..\source\gameengine\SceneGraph;..\..\..\..\..\source\kernel\gen_system;..\..\..\..\..\source\blender\makesdna"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||||
RuntimeLibrary="2"
|
RuntimeLibrary="2"
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
|
@ -106,7 +106,8 @@ World *add_world(char *name)
|
|||||||
wrld->ao_approx_error= 0.25f;
|
wrld->ao_approx_error= 0.25f;
|
||||||
|
|
||||||
wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default
|
wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default
|
||||||
wrld->mode = WO_DBVT_CAMERA_CULLING; // DBVT culling by default
|
wrld->mode = WO_DBVT_CULLING; // DBVT culling by default
|
||||||
|
wrld->occlusionRes = 128;
|
||||||
wrld->preview = NULL;
|
wrld->preview = NULL;
|
||||||
|
|
||||||
return wrld;
|
return wrld;
|
||||||
|
@ -8057,7 +8057,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||||||
}
|
}
|
||||||
/* DBVT culling by default */
|
/* DBVT culling by default */
|
||||||
for(wrld=main->world.first; wrld; wrld= wrld->id.next) {
|
for(wrld=main->world.first; wrld; wrld= wrld->id.next) {
|
||||||
wrld->mode |= WO_DBVT_CAMERA_CULLING;
|
wrld->mode |= WO_DBVT_CULLING;
|
||||||
|
wrld->occlusionRes = 128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,8 @@ typedef struct bGameActuator {
|
|||||||
|
|
||||||
typedef struct bVisibilityActuator {
|
typedef struct bVisibilityActuator {
|
||||||
/** bit 0: Is this object visible?
|
/** bit 0: Is this object visible?
|
||||||
** bit 1: Apply recursively */
|
** bit 1: Apply recursively
|
||||||
|
** bit 2: Is this object an occluder? */
|
||||||
int flag;
|
int flag;
|
||||||
} bVisibilityActuator;
|
} bVisibilityActuator;
|
||||||
|
|
||||||
@ -458,6 +459,7 @@ typedef struct FreeCamera {
|
|||||||
/* Set means the object will become invisible */
|
/* Set means the object will become invisible */
|
||||||
#define ACT_VISIBILITY_INVISIBLE (1 << 0)
|
#define ACT_VISIBILITY_INVISIBLE (1 << 0)
|
||||||
#define ACT_VISIBILITY_RECURSIVE (1 << 1)
|
#define ACT_VISIBILITY_RECURSIVE (1 << 1)
|
||||||
|
#define ACT_VISIBILITY_OCCLUSION (1 << 2)
|
||||||
|
|
||||||
/* twodfilter->type */
|
/* twodfilter->type */
|
||||||
#define ACT_2DFILTER_ENABLED -2
|
#define ACT_2DFILTER_ENABLED -2
|
||||||
|
@ -437,6 +437,7 @@ extern Object workob;
|
|||||||
|
|
||||||
#define OB_COLLISION 65536
|
#define OB_COLLISION 65536
|
||||||
#define OB_SOFT_BODY 0x20000
|
#define OB_SOFT_BODY 0x20000
|
||||||
|
#define OB_OCCLUDER 0x40000
|
||||||
|
|
||||||
/* ob->gameflag2 */
|
/* ob->gameflag2 */
|
||||||
#define OB_NEVER_DO_ACTIVITY_CULLING 1
|
#define OB_NEVER_DO_ACTIVITY_CULLING 1
|
||||||
@ -455,6 +456,7 @@ extern Object workob;
|
|||||||
#define OB_BODY_TYPE_DYNAMIC 2
|
#define OB_BODY_TYPE_DYNAMIC 2
|
||||||
#define OB_BODY_TYPE_RIGID 3
|
#define OB_BODY_TYPE_RIGID 3
|
||||||
#define OB_BODY_TYPE_SOFT 4
|
#define OB_BODY_TYPE_SOFT 4
|
||||||
|
#define OB_BODY_TYPE_OCCLUDER 5
|
||||||
|
|
||||||
/* ob->scavisflag */
|
/* ob->scavisflag */
|
||||||
#define OB_VIS_SENS 1
|
#define OB_VIS_SENS 1
|
||||||
|
@ -88,7 +88,8 @@ typedef struct World {
|
|||||||
* bit 5: (gameengine) : enable Bullet DBVT tree for view frustrum culling
|
* bit 5: (gameengine) : enable Bullet DBVT tree for view frustrum culling
|
||||||
*/
|
*/
|
||||||
short mode;
|
short mode;
|
||||||
int physicsEngine; /* here it's aligned */
|
short occlusionRes; /* resolution of occlusion Z buffer in pixel */
|
||||||
|
short physicsEngine; /* here it's aligned */
|
||||||
|
|
||||||
float misi, miststa, mistdist, misthi;
|
float misi, miststa, mistdist, misthi;
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ typedef struct World {
|
|||||||
#define WO_DOF 4
|
#define WO_DOF 4
|
||||||
#define WO_ACTIVITY_CULLING 8
|
#define WO_ACTIVITY_CULLING 8
|
||||||
#define WO_AMB_OCC 16
|
#define WO_AMB_OCC 16
|
||||||
#define WO_DBVT_CAMERA_CULLING 32
|
#define WO_DBVT_CULLING 32
|
||||||
|
|
||||||
/* aomix */
|
/* aomix */
|
||||||
#define WO_AOADD 0
|
#define WO_AOADD 0
|
||||||
|
@ -3561,7 +3561,7 @@ static int Object_setRBMass( BPy_Object * self, PyObject * args )
|
|||||||
|
|
||||||
/* this is too low level, possible to add helper methods */
|
/* this is too low level, possible to add helper methods */
|
||||||
|
|
||||||
#define GAMEFLAG_MASK ( OB_COLLISION | OB_DYNAMIC | OB_CHILD | OB_ACTOR | OB_DO_FH | \
|
#define GAMEFLAG_MASK ( OB_OCCLUDER | OB_COLLISION | OB_DYNAMIC | OB_CHILD | OB_ACTOR | OB_DO_FH | \
|
||||||
OB_ROT_FH | OB_ANISOTROPIC_FRICTION | OB_GHOST | OB_RIGID_BODY | OB_SOFT_BODY | \
|
OB_ROT_FH | OB_ANISOTROPIC_FRICTION | OB_GHOST | OB_RIGID_BODY | OB_SOFT_BODY | \
|
||||||
OB_BOUNDS | OB_COLLISION_RESPONSE | OB_SECTOR | OB_PROP | \
|
OB_BOUNDS | OB_COLLISION_RESPONSE | OB_SECTOR | OB_PROP | \
|
||||||
OB_MAINACTOR )
|
OB_MAINACTOR )
|
||||||
@ -5542,6 +5542,7 @@ static PyObject *M_Object_RBFlagsDict( void )
|
|||||||
|
|
||||||
if( M ) {
|
if( M ) {
|
||||||
BPy_constant *d = ( BPy_constant * ) M;
|
BPy_constant *d = ( BPy_constant * ) M;
|
||||||
|
PyConstant_Insert( d, "OCCLUDER", PyInt_FromLong( OB_OCCLUDER ) );
|
||||||
PyConstant_Insert( d, "COLLISION", PyInt_FromLong( OB_COLLISION ) );
|
PyConstant_Insert( d, "COLLISION", PyInt_FromLong( OB_COLLISION ) );
|
||||||
PyConstant_Insert( d, "DYNAMIC", PyInt_FromLong( OB_DYNAMIC ) );
|
PyConstant_Insert( d, "DYNAMIC", PyInt_FromLong( OB_DYNAMIC ) );
|
||||||
PyConstant_Insert( d, "CHILD", PyInt_FromLong( OB_CHILD ) );
|
PyConstant_Insert( d, "CHILD", PyInt_FromLong( OB_CHILD ) );
|
||||||
|
@ -2455,18 +2455,18 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
|
|||||||
xco + 10, yco - 20, (width - 20)/3, 19, &visAct->flag,
|
xco + 10, yco - 20, (width - 20)/3, 19, &visAct->flag,
|
||||||
0.0, 0.0, 0, 0,
|
0.0, 0.0, 0, 0,
|
||||||
"Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)");
|
"Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)");
|
||||||
uiDefButBitI(block, TOG, ACT_VISIBILITY_INVISIBLE, B_REDR,
|
uiDefButBitI(block, TOG, ACT_VISIBILITY_OCCLUSION, B_REDR,
|
||||||
"Invisible",
|
"Occlusion",
|
||||||
xco + 10 + ((width - 20)/3), yco - 20, (width - 20)/3, 19, &visAct->flag,
|
xco + 10 + ((width - 20)/3), yco - 20, (width - 20)/3, 19, &visAct->flag,
|
||||||
0.0, 0.0, 0, 0,
|
0.0, 0.0, 0, 0,
|
||||||
"Set the object invisible. Initialized from the objects render restriction toggle (access in the outliner)");
|
"Set the object to occlude objects behind it. Initialized from the object type in physics button");
|
||||||
uiBlockEndAlign(block);
|
uiBlockEndAlign(block);
|
||||||
|
|
||||||
uiDefButBitI(block, TOG, ACT_VISIBILITY_RECURSIVE, B_NOP,
|
uiDefButBitI(block, TOG, ACT_VISIBILITY_RECURSIVE, B_NOP,
|
||||||
"Children",
|
"Children",
|
||||||
xco + 10 + (((width - 20)/3)*2)+10, yco - 20, ((width - 20)/3)-10, 19, &visAct->flag,
|
xco + 10 + (((width - 20)/3)*2)+10, yco - 20, ((width - 20)/3)-10, 19, &visAct->flag,
|
||||||
0.0, 0.0, 0, 0,
|
0.0, 0.0, 0, 0,
|
||||||
"Sets all the children of this object to the same visibility recursively");
|
"Sets all the children of this object to the same visibility/occlusion recursively");
|
||||||
|
|
||||||
yco-= ysize;
|
yco-= ysize;
|
||||||
|
|
||||||
@ -3033,25 +3033,29 @@ static void check_body_type(void *arg1_but, void *arg2_object)
|
|||||||
Object *ob = arg2_object;
|
Object *ob = arg2_object;
|
||||||
|
|
||||||
switch (ob->body_type) {
|
switch (ob->body_type) {
|
||||||
|
case OB_BODY_TYPE_OCCLUDER:
|
||||||
|
ob->gameflag |= OB_OCCLUDER;
|
||||||
|
ob->gameflag &= ~(OB_COLLISION|OB_DYNAMIC);
|
||||||
|
break;
|
||||||
case OB_BODY_TYPE_NO_COLLISION:
|
case OB_BODY_TYPE_NO_COLLISION:
|
||||||
ob->gameflag &= ~OB_COLLISION;
|
ob->gameflag &= ~(OB_COLLISION|OB_OCCLUDER|OB_DYNAMIC);
|
||||||
break;
|
break;
|
||||||
case OB_BODY_TYPE_STATIC:
|
case OB_BODY_TYPE_STATIC:
|
||||||
ob->gameflag |= OB_COLLISION;
|
ob->gameflag |= OB_COLLISION;
|
||||||
ob->gameflag &= ~(OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY);
|
ob->gameflag &= ~(OB_DYNAMIC|OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER);
|
||||||
break;
|
break;
|
||||||
case OB_BODY_TYPE_DYNAMIC:
|
case OB_BODY_TYPE_DYNAMIC:
|
||||||
ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_ACTOR;
|
ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_ACTOR;
|
||||||
ob->gameflag &= ~(OB_RIGID_BODY|OB_SOFT_BODY);
|
ob->gameflag &= ~(OB_RIGID_BODY|OB_SOFT_BODY|OB_OCCLUDER);
|
||||||
break;
|
break;
|
||||||
case OB_BODY_TYPE_RIGID:
|
case OB_BODY_TYPE_RIGID:
|
||||||
ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_RIGID_BODY|OB_ACTOR;
|
ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_RIGID_BODY|OB_ACTOR;
|
||||||
ob->gameflag &= ~(OB_SOFT_BODY);
|
ob->gameflag &= ~(OB_SOFT_BODY|OB_OCCLUDER);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case OB_BODY_TYPE_SOFT:
|
case OB_BODY_TYPE_SOFT:
|
||||||
ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_SOFT_BODY|OB_ACTOR;
|
ob->gameflag |= OB_COLLISION|OB_DYNAMIC|OB_SOFT_BODY|OB_ACTOR;
|
||||||
ob->gameflag &= ~(OB_RIGID_BODY);
|
ob->gameflag &= ~(OB_RIGID_BODY|OB_OCCLUDER);
|
||||||
|
|
||||||
/* assume triangle mesh, if no bounds chosen for soft body */
|
/* assume triangle mesh, if no bounds chosen for soft body */
|
||||||
if ((ob->gameflag & OB_BOUNDS) && (ob->boundtype<OB_BOUND_POLYH))
|
if ((ob->gameflag & OB_BOUNDS) && (ob->boundtype<OB_BOUND_POLYH))
|
||||||
@ -3216,7 +3220,7 @@ static void buttons_bullet(uiBlock *block, Object *ob)
|
|||||||
|
|
||||||
/* determine the body_type setting based on flags */
|
/* determine the body_type setting based on flags */
|
||||||
if (!(ob->gameflag & OB_COLLISION))
|
if (!(ob->gameflag & OB_COLLISION))
|
||||||
ob->body_type = OB_BODY_TYPE_NO_COLLISION;
|
ob->body_type = (ob->gameflag & OB_OCCLUDER) ? OB_BODY_TYPE_OCCLUDER : OB_BODY_TYPE_NO_COLLISION;
|
||||||
else if (!(ob->gameflag & OB_DYNAMIC))
|
else if (!(ob->gameflag & OB_DYNAMIC))
|
||||||
ob->body_type = OB_BODY_TYPE_STATIC;
|
ob->body_type = OB_BODY_TYPE_STATIC;
|
||||||
else if (!(ob->gameflag & (OB_RIGID_BODY|OB_SOFT_BODY)))
|
else if (!(ob->gameflag & (OB_RIGID_BODY|OB_SOFT_BODY)))
|
||||||
@ -3234,7 +3238,7 @@ static void buttons_bullet(uiBlock *block, Object *ob)
|
|||||||
|
|
||||||
//only enable game soft body if Blender Soft Body exists
|
//only enable game soft body if Blender Soft Body exists
|
||||||
but = uiDefButS(block, MENU, REDRAWVIEW3D,
|
but = uiDefButS(block, MENU, REDRAWVIEW3D,
|
||||||
"Object type%t|No collision%x0|Static%x1|Dynamic%x2|Rigid body%x3|Soft body%x4",
|
"Object type%t|Occluder%x5|No collision%x0|Static%x1|Dynamic%x2|Rigid body%x3|Soft body%x4",
|
||||||
10, 205, 100, 19, &ob->body_type, 0, 0, 0, 0, "Selects the type of physical representation");
|
10, 205, 100, 19, &ob->body_type, 0, 0, 0, 0, "Selects the type of physical representation");
|
||||||
uiButSetFunc(but, check_body_type, but, ob);
|
uiButSetFunc(but, check_body_type, but, ob);
|
||||||
|
|
||||||
|
@ -2181,7 +2181,7 @@ static void world_panel_mistaph(World *wrld)
|
|||||||
uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
|
uiSetButLock(wrld->id.lib!=0, ERROR_LIBDATA_MESSAGE);
|
||||||
|
|
||||||
#if GAMEBLENDER == 1
|
#if GAMEBLENDER == 1
|
||||||
uiDefButI(block, MENU, B_REDR,
|
uiDefButS(block, MENU, B_REDR,
|
||||||
#ifdef USE_ODE
|
#ifdef USE_ODE
|
||||||
"Physics %t|None %x0|Sumo %x2|Ode %x4 |Bullet %x5",
|
"Physics %t|None %x0|Sumo %x2|Ode %x4 |Bullet %x5",
|
||||||
#else
|
#else
|
||||||
@ -2198,8 +2198,12 @@ static void world_panel_mistaph(World *wrld)
|
|||||||
|
|
||||||
/* Gravitation for the game worlds */
|
/* Gravitation for the game worlds */
|
||||||
uiDefButF(block, NUMSLI,0, "Grav ", 150,180,150,19, &(wrld->gravity), 0.0, 25.0, 0, 0, "Sets the gravitation constant of the game world");
|
uiDefButF(block, NUMSLI,0, "Grav ", 150,180,150,19, &(wrld->gravity), 0.0, 25.0, 0, 0, "Sets the gravitation constant of the game world");
|
||||||
if (wrld->physicsEngine == WOPHY_BULLET)
|
if (wrld->physicsEngine == WOPHY_BULLET) {
|
||||||
uiDefButBitS(block, TOG, WO_DBVT_CAMERA_CULLING, 0, "DBVT culling", 10,160,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles use of optimized Bullet DBVT tree for camera culling");
|
uiDefButBitS(block, TOG, WO_DBVT_CULLING, B_REDR, "DBVT culling", 10,160,140,19, &wrld->mode, 0, 0, 0, 0, "Toggles use of optimized Bullet DBVT tree for view frustrum and occlusion culling");
|
||||||
|
if (wrld->mode & WO_DBVT_CULLING)
|
||||||
|
uiDefButS(block, NUM, B_REDR, "Occlu Res:",
|
||||||
|
150, 160, 150, 19, &wrld->occlusionRes, 128.0, 1024.0, 0, 0, "Sets the size of the occlusion buffer in pixel, use higher value for better precsion (slower)");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uiBlockSetCol(block, TH_BUT_SETTING1);
|
uiBlockSetCol(block, TH_BUT_SETTING1);
|
||||||
|
@ -843,6 +843,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
|
|||||||
|
|
||||||
{
|
{
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
|
bool twoside = false;
|
||||||
RAS_IPolyMaterial* polymat = NULL;
|
RAS_IPolyMaterial* polymat = NULL;
|
||||||
BL_Material *bl_mat = NULL;
|
BL_Material *bl_mat = NULL;
|
||||||
|
|
||||||
@ -859,6 +860,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
|
|||||||
|
|
||||||
visible = ((bl_mat->ras_mode & POLY_VIS)!=0);
|
visible = ((bl_mat->ras_mode & POLY_VIS)!=0);
|
||||||
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
|
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
|
||||||
|
twoside = ((bl_mat->mode & TF_TWOSIDE)!=0);
|
||||||
|
|
||||||
/* vertex colors and uv's were stored in bl_mat temporarily */
|
/* vertex colors and uv's were stored in bl_mat temporarily */
|
||||||
bl_mat->GetConversionRGB(rgb);
|
bl_mat->GetConversionRGB(rgb);
|
||||||
@ -899,6 +901,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
|
|||||||
mode = tface->mode;
|
mode = tface->mode;
|
||||||
|
|
||||||
visible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
|
visible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
|
||||||
|
twoside = ((tface->mode & TF_TWOSIDE)!=0);
|
||||||
|
|
||||||
uv0.setValue(tface->uv[0]);
|
uv0.setValue(tface->uv[0]);
|
||||||
uv1.setValue(tface->uv[1]);
|
uv1.setValue(tface->uv[1]);
|
||||||
@ -999,6 +1002,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
|
|||||||
|
|
||||||
poly->SetVisible(visible);
|
poly->SetVisible(visible);
|
||||||
poly->SetCollider(collider);
|
poly->SetCollider(collider);
|
||||||
|
poly->SetTwoside(twoside);
|
||||||
//poly->SetEdgeCode(mface->edcode);
|
//poly->SetEdgeCode(mface->edcode);
|
||||||
|
|
||||||
meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
|
meshobj->AddVertex(poly,0,pt0,uv0,uv20,tan0,rgb0,no0,flat,mface->v1);
|
||||||
@ -1677,6 +1681,7 @@ static KX_GameObject *gameobject_from_blenderobject(
|
|||||||
bool ignoreActivityCulling =
|
bool ignoreActivityCulling =
|
||||||
((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
|
((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
|
||||||
gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
|
gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
|
||||||
|
gameobj->SetOccluder((ob->gameflag & OB_OCCLUDER) != 0, false);
|
||||||
|
|
||||||
// two options exists for deform: shape keys and armature
|
// two options exists for deform: shape keys and armature
|
||||||
// only support relative shape key
|
// only support relative shape key
|
||||||
@ -1894,12 +1899,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
|||||||
if (blenderscene->world) {
|
if (blenderscene->world) {
|
||||||
kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
|
kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
|
||||||
kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
|
kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
|
||||||
kxscene->SetDbvtCameraCulling((blenderscene->world->mode & WO_DBVT_CAMERA_CULLING) != 0);
|
kxscene->SetDbvtCulling((blenderscene->world->mode & WO_DBVT_CULLING) != 0);
|
||||||
} else {
|
} else {
|
||||||
kxscene->SetActivityCulling(false);
|
kxscene->SetActivityCulling(false);
|
||||||
kxscene->SetDbvtCameraCulling(false);
|
kxscene->SetDbvtCulling(false);
|
||||||
}
|
}
|
||||||
|
// no occlusion culling by default
|
||||||
|
kxscene->SetDbvtOcclusionRes(0);
|
||||||
|
|
||||||
int activeLayerBitInfo = blenderscene->lay;
|
int activeLayerBitInfo = blenderscene->lay;
|
||||||
|
|
||||||
// templist to find Root Parents (object with no parents)
|
// templist to find Root Parents (object with no parents)
|
||||||
@ -2452,8 +2459,9 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create graphic controller for culling
|
// create graphic controller for culling
|
||||||
if (kxscene->GetDbvtCameraCulling())
|
if (kxscene->GetDbvtCulling())
|
||||||
{
|
{
|
||||||
|
bool occlusion = false;
|
||||||
for (i=0; i<sumolist->GetCount();i++)
|
for (i=0; i<sumolist->GetCount();i++)
|
||||||
{
|
{
|
||||||
KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
|
KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
|
||||||
@ -2464,8 +2472,12 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
|||||||
// box[0] is the min, box[1] is the max
|
// box[0] is the min, box[1] is the max
|
||||||
bool isactive = objectlist->SearchValue(gameobj);
|
bool isactive = objectlist->SearchValue(gameobj);
|
||||||
BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine);
|
BL_CreateGraphicObjectNew(gameobj,box[0],box[1],kxscene,isactive,physics_engine);
|
||||||
|
if (gameobj->GetOccluder())
|
||||||
|
occlusion = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (occlusion)
|
||||||
|
kxscene->SetDbvtOcclusionRes(blenderscene->world->occlusionRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
//set ini linearVel and int angularVel //rcruiz
|
//set ini linearVel and int angularVel //rcruiz
|
||||||
|
@ -283,7 +283,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
|
|||||||
case WOPHY_BULLET:
|
case WOPHY_BULLET:
|
||||||
{
|
{
|
||||||
physics_engine = UseBullet;
|
physics_engine = UseBullet;
|
||||||
useDbvtCulling = (blenderscene->world->mode & WO_DBVT_CAMERA_CULLING) != 0;
|
useDbvtCulling = (blenderscene->world->mode & WO_DBVT_CULLING) != 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1008,9 +1008,10 @@ void BL_ConvertActuators(char* maggiename,
|
|||||||
bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
|
bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
|
||||||
KX_VisibilityActuator * tmp_vis_act = NULL;
|
KX_VisibilityActuator * tmp_vis_act = NULL;
|
||||||
bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
|
bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
|
||||||
|
bool o = ((vis_act->flag & ACT_VISIBILITY_OCCLUSION) != 0);
|
||||||
bool recursive = ((vis_act->flag & ACT_VISIBILITY_RECURSIVE) != 0);
|
bool recursive = ((vis_act->flag & ACT_VISIBILITY_RECURSIVE) != 0);
|
||||||
|
|
||||||
tmp_vis_act = new KX_VisibilityActuator(gameobj, !v, recursive);
|
tmp_vis_act = new KX_VisibilityActuator(gameobj, !v, o, recursive);
|
||||||
|
|
||||||
baseact = tmp_vis_act;
|
baseact = tmp_vis_act;
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ KX_GameObject::KX_GameObject(
|
|||||||
m_bIsNegativeScaling(false),
|
m_bIsNegativeScaling(false),
|
||||||
m_bVisible(true),
|
m_bVisible(true),
|
||||||
m_bCulled(true),
|
m_bCulled(true),
|
||||||
|
m_bOccluder(false),
|
||||||
m_pPhysicsController1(NULL),
|
m_pPhysicsController1(NULL),
|
||||||
m_pGraphicController(NULL),
|
m_pGraphicController(NULL),
|
||||||
m_pPhysicsEnvironment(NULL),
|
m_pPhysicsEnvironment(NULL),
|
||||||
@ -146,7 +147,12 @@ KX_GameObject::~KX_GameObject()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KX_GameObject* KX_GameObject::GetClientObject(KX_ClientObjectInfo* info)
|
||||||
|
{
|
||||||
|
if (!info)
|
||||||
|
return NULL;
|
||||||
|
return info->m_gameobject;
|
||||||
|
}
|
||||||
|
|
||||||
CValue* KX_GameObject:: Calc(VALUE_OPERATOR op, CValue *val)
|
CValue* KX_GameObject:: Calc(VALUE_OPERATOR op, CValue *val)
|
||||||
{
|
{
|
||||||
@ -435,7 +441,7 @@ static void UpdateBuckets_recursive(SG_Node* node)
|
|||||||
|
|
||||||
void KX_GameObject::UpdateBuckets( bool recursive )
|
void KX_GameObject::UpdateBuckets( bool recursive )
|
||||||
{
|
{
|
||||||
double* fl = GetOpenGLMatrix();
|
double* fl = GetOpenGLMatrixPtr()->getPointer();
|
||||||
|
|
||||||
for (size_t i=0;i<m_meshes.size();i++)
|
for (size_t i=0;i<m_meshes.size();i++)
|
||||||
m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
|
m_meshes[i]->UpdateBuckets(this, fl, m_bUseObjectColor, m_objectColor, m_bVisible, m_bCulled);
|
||||||
@ -597,23 +603,34 @@ KX_GameObject::SetVisible(
|
|||||||
setVisible_recursive(m_pSGNode, v);
|
setVisible_recursive(m_pSGNode, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
static void setOccluder_recursive(SG_Node* node, bool v)
|
||||||
KX_GameObject::GetCulled(
|
|
||||||
void
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return m_bCulled;
|
NodeList& children = node->GetSGChildren();
|
||||||
|
|
||||||
|
for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
|
||||||
|
{
|
||||||
|
SG_Node* childnode = (*childit);
|
||||||
|
KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject());
|
||||||
|
if (clientgameobj != NULL) // This is a GameObject
|
||||||
|
clientgameobj->SetOccluder(v, false);
|
||||||
|
|
||||||
|
// if the childobj is NULL then this may be an inverse parent link
|
||||||
|
// so a non recursive search should still look down this node.
|
||||||
|
setOccluder_recursive(childnode, v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
KX_GameObject::SetCulled(
|
KX_GameObject::SetOccluder(
|
||||||
bool c
|
bool v,
|
||||||
|
bool recursive
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_bCulled = c;
|
m_bOccluder = v;
|
||||||
|
if (recursive)
|
||||||
|
setOccluder_recursive(m_pSGNode, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
KX_GameObject::SetLayer(
|
KX_GameObject::SetLayer(
|
||||||
int l
|
int l
|
||||||
@ -1036,6 +1053,7 @@ PyMethodDef KX_GameObject::Methods[] = {
|
|||||||
{"setCollisionMargin", (PyCFunction) KX_GameObject::sPySetCollisionMargin, METH_O},
|
{"setCollisionMargin", (PyCFunction) KX_GameObject::sPySetCollisionMargin, METH_O},
|
||||||
{"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
|
{"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
|
||||||
{"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
|
{"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
|
||||||
|
{"setOcclusion",(PyCFunction) KX_GameObject::sPySetOcclusion, METH_VARARGS},
|
||||||
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
|
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
|
||||||
{"getChildren", (PyCFunction)KX_GameObject::sPyGetChildren,METH_NOARGS},
|
{"getChildren", (PyCFunction)KX_GameObject::sPyGetChildren,METH_NOARGS},
|
||||||
{"getChildrenRecursive", (PyCFunction)KX_GameObject::sPyGetChildrenRecursive,METH_NOARGS},
|
{"getChildrenRecursive", (PyCFunction)KX_GameObject::sPyGetChildrenRecursive,METH_NOARGS},
|
||||||
@ -1069,6 +1087,7 @@ PyAttributeDef KX_GameObject::Attributes[] = {
|
|||||||
KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
|
KX_PYATTRIBUTE_RO_FUNCTION("parent", KX_GameObject, pyattr_get_parent),
|
||||||
KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass),
|
KX_PYATTRIBUTE_RW_FUNCTION("mass", KX_GameObject, pyattr_get_mass, pyattr_set_mass),
|
||||||
KX_PYATTRIBUTE_RW_FUNCTION("visible", KX_GameObject, pyattr_get_visible, pyattr_set_visible),
|
KX_PYATTRIBUTE_RW_FUNCTION("visible", KX_GameObject, pyattr_get_visible, pyattr_set_visible),
|
||||||
|
KX_PYATTRIBUTE_BOOL_RW ("occlusion", KX_GameObject, m_bOccluder),
|
||||||
KX_PYATTRIBUTE_RW_FUNCTION("position", KX_GameObject, pyattr_get_position, pyattr_set_position),
|
KX_PYATTRIBUTE_RW_FUNCTION("position", KX_GameObject, pyattr_get_position, pyattr_set_position),
|
||||||
KX_PYATTRIBUTE_RO_FUNCTION("localInertia", KX_GameObject, pyattr_get_localInertia),
|
KX_PYATTRIBUTE_RO_FUNCTION("localInertia", KX_GameObject, pyattr_get_localInertia),
|
||||||
KX_PYATTRIBUTE_RW_FUNCTION("orientation",KX_GameObject,pyattr_get_orientation,pyattr_set_orientation),
|
KX_PYATTRIBUTE_RW_FUNCTION("orientation",KX_GameObject,pyattr_get_orientation,pyattr_set_orientation),
|
||||||
@ -1746,6 +1765,16 @@ PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* args)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* KX_GameObject::PySetOcclusion(PyObject* self, PyObject* args)
|
||||||
|
{
|
||||||
|
int occlusion, recursive = 0;
|
||||||
|
if (!PyArg_ParseTuple(args,"i|i:setOcclusion",&occlusion, &recursive))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
SetOccluder(occlusion ? true:false, recursive ? true:false);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject* KX_GameObject::PyGetVisible(PyObject* self)
|
PyObject* KX_GameObject::PyGetVisible(PyObject* self)
|
||||||
{
|
{
|
||||||
ShowDeprecationWarning("getVisible()", "the visible property");
|
ShowDeprecationWarning("getVisible()", "the visible property");
|
||||||
|
@ -87,6 +87,7 @@ protected:
|
|||||||
// culled = while rendering, depending on camera
|
// culled = while rendering, depending on camera
|
||||||
bool m_bVisible;
|
bool m_bVisible;
|
||||||
bool m_bCulled;
|
bool m_bCulled;
|
||||||
|
bool m_bOccluder;
|
||||||
|
|
||||||
KX_IPhysicsController* m_pPhysicsController1;
|
KX_IPhysicsController* m_pPhysicsController1;
|
||||||
PHY_IGraphicController* m_pGraphicController;
|
PHY_IGraphicController* m_pGraphicController;
|
||||||
@ -103,6 +104,11 @@ protected:
|
|||||||
public:
|
public:
|
||||||
bool m_isDeformable;
|
bool m_isDeformable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for modules that can't include KX_ClientObjectInfo.h
|
||||||
|
*/
|
||||||
|
static KX_GameObject* GetClientObject(KX_ClientObjectInfo* info);
|
||||||
|
|
||||||
// Python attributes that wont convert into CValue
|
// Python attributes that wont convert into CValue
|
||||||
//
|
//
|
||||||
// there are 2 places attributes can be stored, in the CValue,
|
// there are 2 places attributes can be stored, in the CValue,
|
||||||
@ -118,11 +124,8 @@ public:
|
|||||||
// * if CValue conversion fails, use a PyObject in "m_attrlist"
|
// * if CValue conversion fails, use a PyObject in "m_attrlist"
|
||||||
// * when assigning a value, first see if it can be a CValue, if it can remove the "m_attrlist" and set the CValue
|
// * when assigning a value, first see if it can be a CValue, if it can remove the "m_attrlist" and set the CValue
|
||||||
//
|
//
|
||||||
|
|
||||||
PyObject* m_attrlist;
|
PyObject* m_attrlist;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual void /* This function should be virtual - derived classed override it */
|
virtual void /* This function should be virtual - derived classed override it */
|
||||||
Relink(
|
Relink(
|
||||||
GEN_Map<GEN_HashedPtr, void*> *map
|
GEN_Map<GEN_HashedPtr, void*> *map
|
||||||
@ -698,19 +701,36 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Was this object culled?
|
* Was this object culled?
|
||||||
*/
|
*/
|
||||||
bool
|
inline bool
|
||||||
GetCulled(
|
GetCulled(
|
||||||
void
|
void
|
||||||
);
|
) { return m_bCulled; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set culled flag of this object
|
* Set culled flag of this object
|
||||||
*/
|
*/
|
||||||
void
|
inline void
|
||||||
SetCulled(
|
SetCulled(
|
||||||
bool c
|
bool c
|
||||||
);
|
) { m_bCulled = c; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this object an occluder?
|
||||||
|
*/
|
||||||
|
inline bool
|
||||||
|
GetOccluder(
|
||||||
|
void
|
||||||
|
) { return m_bOccluder; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set occluder flag of this object
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SetOccluder(
|
||||||
|
bool v,
|
||||||
|
bool recursive
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the layer of the object (when it is added in another layer
|
* Change the layer of the object (when it is added in another layer
|
||||||
* than the original layer)
|
* than the original layer)
|
||||||
@ -908,6 +928,7 @@ public:
|
|||||||
KX_PYMETHOD_O(KX_GameObject,SetOrientation);
|
KX_PYMETHOD_O(KX_GameObject,SetOrientation);
|
||||||
KX_PYMETHOD_NOARGS(KX_GameObject,GetVisible);
|
KX_PYMETHOD_NOARGS(KX_GameObject,GetVisible);
|
||||||
KX_PYMETHOD_VARARGS(KX_GameObject,SetVisible);
|
KX_PYMETHOD_VARARGS(KX_GameObject,SetVisible);
|
||||||
|
KX_PYMETHOD_VARARGS(KX_GameObject,SetOcclusion);
|
||||||
KX_PYMETHOD_NOARGS(KX_GameObject,GetState);
|
KX_PYMETHOD_NOARGS(KX_GameObject,GetState);
|
||||||
KX_PYMETHOD_O(KX_GameObject,SetState);
|
KX_PYMETHOD_O(KX_GameObject,SetState);
|
||||||
KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
|
KX_PYMETHOD_VARARGS(KX_GameObject,AlignAxisToVect);
|
||||||
|
@ -294,8 +294,14 @@ void KX_KetsjiEngine::RenderDome()
|
|||||||
if (!BeginFrame())
|
if (!BeginFrame())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int n_renders=m_dome->GetNumberRenders();// usually 4 or 6
|
|
||||||
KX_SceneList::iterator sceneit;
|
KX_SceneList::iterator sceneit;
|
||||||
|
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
|
||||||
|
{
|
||||||
|
// do this only once per scene
|
||||||
|
(*sceneit)->UpdateMeshTransformations();
|
||||||
|
}
|
||||||
|
|
||||||
|
int n_renders=m_dome->GetNumberRenders();// usually 4 or 6
|
||||||
for (int i=0;i<n_renders;i++){
|
for (int i=0;i<n_renders;i++){
|
||||||
m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
|
m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER|RAS_ICanvas::DEPTH_BUFFER);
|
||||||
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
|
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
|
||||||
@ -311,7 +317,6 @@ void KX_KetsjiEngine::RenderDome()
|
|||||||
// shadow buffers
|
// shadow buffers
|
||||||
if (i == 0){
|
if (i == 0){
|
||||||
RenderShadowBuffers(scene);
|
RenderShadowBuffers(scene);
|
||||||
scene->UpdateMeshTransformations();//I need to run it somewherelse, otherwise Im overrunning it
|
|
||||||
}
|
}
|
||||||
// Avoid drawing the scene with the active camera twice when it's viewport is enabled
|
// Avoid drawing the scene with the active camera twice when it's viewport is enabled
|
||||||
if(cam && !cam->GetViewport())
|
if(cam && !cam->GetViewport())
|
||||||
@ -812,6 +817,9 @@ void KX_KetsjiEngine::Render()
|
|||||||
// pass the scene's worldsettings to the rasterizer
|
// pass the scene's worldsettings to the rasterizer
|
||||||
SetWorldSettings(scene->GetWorldInfo());
|
SetWorldSettings(scene->GetWorldInfo());
|
||||||
|
|
||||||
|
// do this only once per scene
|
||||||
|
scene->UpdateMeshTransformations();
|
||||||
|
|
||||||
// shadow buffers
|
// shadow buffers
|
||||||
RenderShadowBuffers(scene);
|
RenderShadowBuffers(scene);
|
||||||
|
|
||||||
@ -1140,7 +1148,6 @@ void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
|
|||||||
light->BindShadowBuffer(m_rasterizer, cam, camtrans);
|
light->BindShadowBuffer(m_rasterizer, cam, camtrans);
|
||||||
|
|
||||||
/* update scene */
|
/* update scene */
|
||||||
scene->UpdateMeshTransformations();
|
|
||||||
scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
|
scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
|
||||||
|
|
||||||
/* render */
|
/* render */
|
||||||
@ -1245,7 +1252,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
|
|||||||
cam->GetCameraLocation(), cam->GetCameraOrientation());
|
cam->GetCameraLocation(), cam->GetCameraOrientation());
|
||||||
cam->SetModelviewMatrix(viewmat);
|
cam->SetModelviewMatrix(viewmat);
|
||||||
|
|
||||||
//redundant, already done in
|
//redundant, already done in Render()
|
||||||
//scene->UpdateMeshTransformations();
|
//scene->UpdateMeshTransformations();
|
||||||
|
|
||||||
// The following actually reschedules all vertices to be
|
// The following actually reschedules all vertices to be
|
||||||
|
@ -138,6 +138,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
|
|||||||
m_suspendeddelta = 0.0;
|
m_suspendeddelta = 0.0;
|
||||||
|
|
||||||
m_dbvt_culling = false;
|
m_dbvt_culling = false;
|
||||||
|
m_dbvt_occlusion_res = 0;
|
||||||
m_activity_culling = false;
|
m_activity_culling = false;
|
||||||
m_suspend = false;
|
m_suspend = false;
|
||||||
m_isclearingZbuffer = true;
|
m_isclearingZbuffer = true;
|
||||||
@ -1352,17 +1353,18 @@ void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int
|
|||||||
if (m_dbvt_culling)
|
if (m_dbvt_culling)
|
||||||
{
|
{
|
||||||
// test culling through Bullet
|
// test culling through Bullet
|
||||||
PHY__Vector4 planes[5];
|
PHY__Vector4 planes[6];
|
||||||
// get the clip planes
|
// get the clip planes
|
||||||
MT_Vector4* cplanes = cam->GetNormalizedClipPlanes();
|
MT_Vector4* cplanes = cam->GetNormalizedClipPlanes();
|
||||||
// and convert
|
// and convert
|
||||||
planes[0].setValue(cplanes[0].getValue());
|
planes[0].setValue(cplanes[4].getValue()); // near
|
||||||
planes[1].setValue(cplanes[1].getValue());
|
planes[1].setValue(cplanes[5].getValue()); // far
|
||||||
planes[2].setValue(cplanes[2].getValue());
|
planes[2].setValue(cplanes[0].getValue()); // left
|
||||||
planes[3].setValue(cplanes[3].getValue());
|
planes[3].setValue(cplanes[1].getValue()); // right
|
||||||
planes[4].setValue(cplanes[5].getValue());
|
planes[4].setValue(cplanes[2].getValue()); // top
|
||||||
|
planes[5].setValue(cplanes[3].getValue()); // bottom
|
||||||
CullingInfo info(layer);
|
CullingInfo info(layer);
|
||||||
dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5);
|
dbvt_culling = m_physicsEnvironment->cullingTest(PhysicsCullingCallback,&info,planes,5,m_dbvt_occlusion_res);
|
||||||
}
|
}
|
||||||
if (!dbvt_culling) {
|
if (!dbvt_culling) {
|
||||||
// the physics engine couldn't help us, do it the hard way
|
// the physics engine couldn't help us, do it the hard way
|
||||||
|
@ -264,6 +264,11 @@ protected:
|
|||||||
*/
|
*/
|
||||||
bool m_dbvt_culling;
|
bool m_dbvt_culling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Occlusion culling resolution
|
||||||
|
*/
|
||||||
|
int m_dbvt_occlusion_res;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The framing settings used by this scene
|
* The framing settings used by this scene
|
||||||
*/
|
*/
|
||||||
@ -545,8 +550,10 @@ public:
|
|||||||
bool IsClearingZBuffer();
|
bool IsClearingZBuffer();
|
||||||
void EnableZBufferClearing(bool isclearingZbuffer);
|
void EnableZBufferClearing(bool isclearingZbuffer);
|
||||||
// use of DBVT tree for camera culling
|
// use of DBVT tree for camera culling
|
||||||
void SetDbvtCameraCulling(bool b) { m_dbvt_culling = b; };
|
void SetDbvtCulling(bool b) { m_dbvt_culling = b; };
|
||||||
bool GetDbvtCameraCulling() { return m_dbvt_culling; };
|
bool GetDbvtCulling() { return m_dbvt_culling; };
|
||||||
|
void SetDbvtOcclusionRes(int i) { m_dbvt_occlusion_res = i; };
|
||||||
|
int GetDbvtOcclusionRes() { return m_dbvt_occlusion_res; };
|
||||||
|
|
||||||
void SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter);
|
void SetSceneConverter(class KX_BlenderSceneConverter* sceneConverter);
|
||||||
|
|
||||||
|
@ -38,11 +38,13 @@
|
|||||||
KX_VisibilityActuator::KX_VisibilityActuator(
|
KX_VisibilityActuator::KX_VisibilityActuator(
|
||||||
SCA_IObject* gameobj,
|
SCA_IObject* gameobj,
|
||||||
bool visible,
|
bool visible,
|
||||||
|
bool occlusion,
|
||||||
bool recursive,
|
bool recursive,
|
||||||
PyTypeObject* T
|
PyTypeObject* T
|
||||||
)
|
)
|
||||||
: SCA_IActuator(gameobj,T),
|
: SCA_IActuator(gameobj,T),
|
||||||
m_visible(visible),
|
m_visible(visible),
|
||||||
|
m_occlusion(occlusion),
|
||||||
m_recursive(recursive)
|
m_recursive(recursive)
|
||||||
{
|
{
|
||||||
// intentionally empty
|
// intentionally empty
|
||||||
@ -78,6 +80,7 @@ KX_VisibilityActuator::Update()
|
|||||||
KX_GameObject *obj = (KX_GameObject*) GetParent();
|
KX_GameObject *obj = (KX_GameObject*) GetParent();
|
||||||
|
|
||||||
obj->SetVisible(m_visible, m_recursive);
|
obj->SetVisible(m_visible, m_recursive);
|
||||||
|
obj->SetOccluder(m_occlusion, m_recursive);
|
||||||
obj->UpdateBuckets(m_recursive);
|
obj->UpdateBuckets(m_recursive);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -130,6 +133,7 @@ KX_VisibilityActuator::Methods[] = {
|
|||||||
|
|
||||||
PyAttributeDef KX_VisibilityActuator::Attributes[] = {
|
PyAttributeDef KX_VisibilityActuator::Attributes[] = {
|
||||||
KX_PYATTRIBUTE_BOOL_RW("visibility", KX_VisibilityActuator, m_visible),
|
KX_PYATTRIBUTE_BOOL_RW("visibility", KX_VisibilityActuator, m_visible),
|
||||||
|
KX_PYATTRIBUTE_BOOL_RW("occlusion", KX_VisibilityActuator, m_occlusion),
|
||||||
KX_PYATTRIBUTE_BOOL_RW("recursion", KX_VisibilityActuator, m_recursive),
|
KX_PYATTRIBUTE_BOOL_RW("recursion", KX_VisibilityActuator, m_recursive),
|
||||||
{ NULL } //Sentinel
|
{ NULL } //Sentinel
|
||||||
};
|
};
|
||||||
|
@ -39,6 +39,7 @@ class KX_VisibilityActuator : public SCA_IActuator
|
|||||||
|
|
||||||
/** Make visible? */
|
/** Make visible? */
|
||||||
bool m_visible;
|
bool m_visible;
|
||||||
|
bool m_occlusion;
|
||||||
bool m_recursive;
|
bool m_recursive;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -46,6 +47,7 @@ class KX_VisibilityActuator : public SCA_IActuator
|
|||||||
KX_VisibilityActuator(
|
KX_VisibilityActuator(
|
||||||
SCA_IObject* gameobj,
|
SCA_IObject* gameobj,
|
||||||
bool visible,
|
bool visible,
|
||||||
|
bool occlusion,
|
||||||
bool recursive,
|
bool recursive,
|
||||||
PyTypeObject* T=&Type
|
PyTypeObject* T=&Type
|
||||||
);
|
);
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
|
|
||||||
virtual void removeConstraint(void * constraintid);
|
virtual void removeConstraint(void * constraintid);
|
||||||
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
|
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
|
||||||
virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes) { return false; }
|
virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes) { return false; }
|
||||||
|
|
||||||
|
|
||||||
//gamelogic callbacks
|
//gamelogic callbacks
|
||||||
|
@ -30,11 +30,18 @@ SET(INC
|
|||||||
.
|
.
|
||||||
../common
|
../common
|
||||||
../../../../extern/bullet2/src
|
../../../../extern/bullet2/src
|
||||||
|
../../../../extern/glew/include
|
||||||
../../../../intern/moto/include
|
../../../../intern/moto/include
|
||||||
../../../kernel/gen_system
|
../../../kernel/gen_system
|
||||||
../../../../intern/string
|
../../../../intern/string
|
||||||
|
../../../intern/SoundSystem
|
||||||
../../Rasterizer
|
../../Rasterizer
|
||||||
|
../../Ketsji
|
||||||
|
../../Expressions
|
||||||
|
../../GameLogic
|
||||||
|
../../SceneGraph
|
||||||
../../../../source/blender/makesdna
|
../../../../source/blender/makesdna
|
||||||
|
${PYTHON_INC}
|
||||||
)
|
)
|
||||||
|
|
||||||
BLENDERLIB(bf_bullet "${SRC}" "${INC}")
|
BLENDERLIB(bf_bullet "${SRC}" "${INC}")
|
||||||
|
@ -33,6 +33,10 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
|
|
||||||
#include "PHY_IMotionState.h"
|
#include "PHY_IMotionState.h"
|
||||||
|
#include "KX_GameObject.h"
|
||||||
|
#include "RAS_MeshObject.h"
|
||||||
|
#include "RAS_Polygon.h"
|
||||||
|
#include "RAS_TexVert.h"
|
||||||
|
|
||||||
#define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
|
#define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
|
||||||
|
|
||||||
@ -47,7 +51,9 @@ btRaycastVehicle::btVehicleTuning gTuning;
|
|||||||
|
|
||||||
#endif //NEW_BULLET_VEHICLE_SUPPORT
|
#endif //NEW_BULLET_VEHICLE_SUPPORT
|
||||||
#include "LinearMath/btAabbUtil2.h"
|
#include "LinearMath/btAabbUtil2.h"
|
||||||
|
#include "MT_Matrix4x4.h"
|
||||||
|
#include "MT_Vector3.h"
|
||||||
|
#include "GL/glew.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
void DrawRasterizerLine(const float* from,const float* to,int color);
|
void DrawRasterizerLine(const float* from,const float* to,int color);
|
||||||
@ -1189,17 +1195,492 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
|
|||||||
return result.m_controller;
|
return result.m_controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handles occlusion culling.
|
||||||
|
// The implementation is based on the CDTestFramework
|
||||||
|
struct OcclusionBuffer
|
||||||
|
{
|
||||||
|
struct WriteOCL
|
||||||
|
{
|
||||||
|
static inline bool Process(btScalar& q,btScalar v) { if(q<v) q=v;return(false); }
|
||||||
|
static inline void Occlusion(bool& flag) { flag = true; }
|
||||||
|
};
|
||||||
|
struct QueryOCL
|
||||||
|
{
|
||||||
|
static inline bool Process(btScalar& q,btScalar v) { return(q<=v); }
|
||||||
|
static inline void Occlusion(bool& flag) { }
|
||||||
|
};
|
||||||
|
btScalar* m_buffer;
|
||||||
|
size_t m_bufferSize;
|
||||||
|
bool m_initialized;
|
||||||
|
bool m_occlusion;
|
||||||
|
int m_sizes[2];
|
||||||
|
btScalar m_scales[2];
|
||||||
|
btScalar m_offsets[2];
|
||||||
|
btScalar m_wtc[16]; // world to clip transform
|
||||||
|
btScalar m_mtc[16]; // model to clip transform
|
||||||
|
// constructor: size=largest dimension of the buffer.
|
||||||
|
// Buffer size depends on aspect ratio
|
||||||
|
OcclusionBuffer()
|
||||||
|
{
|
||||||
|
m_initialized=false;
|
||||||
|
m_occlusion = false;
|
||||||
|
m_buffer == NULL;
|
||||||
|
m_bufferSize = 0;
|
||||||
|
}
|
||||||
|
// multiplication of column major matrices: m=m1*m2
|
||||||
|
template<typename T1, typename T2>
|
||||||
|
void CMmat4mul(btScalar* m, const T1* m1, const T2* m2)
|
||||||
|
{
|
||||||
|
m[ 0] = btScalar(m1[ 0]*m2[ 0]+m1[ 4]*m2[ 1]+m1[ 8]*m2[ 2]+m1[12]*m2[ 3]);
|
||||||
|
m[ 1] = btScalar(m1[ 1]*m2[ 0]+m1[ 5]*m2[ 1]+m1[ 9]*m2[ 2]+m1[13]*m2[ 3]);
|
||||||
|
m[ 2] = btScalar(m1[ 2]*m2[ 0]+m1[ 6]*m2[ 1]+m1[10]*m2[ 2]+m1[14]*m2[ 3]);
|
||||||
|
m[ 3] = btScalar(m1[ 3]*m2[ 0]+m1[ 7]*m2[ 1]+m1[11]*m2[ 2]+m1[15]*m2[ 3]);
|
||||||
|
|
||||||
|
m[ 4] = btScalar(m1[ 0]*m2[ 4]+m1[ 4]*m2[ 5]+m1[ 8]*m2[ 6]+m1[12]*m2[ 7]);
|
||||||
|
m[ 5] = btScalar(m1[ 1]*m2[ 4]+m1[ 5]*m2[ 5]+m1[ 9]*m2[ 6]+m1[13]*m2[ 7]);
|
||||||
|
m[ 6] = btScalar(m1[ 2]*m2[ 4]+m1[ 6]*m2[ 5]+m1[10]*m2[ 6]+m1[14]*m2[ 7]);
|
||||||
|
m[ 7] = btScalar(m1[ 3]*m2[ 4]+m1[ 7]*m2[ 5]+m1[11]*m2[ 6]+m1[15]*m2[ 7]);
|
||||||
|
|
||||||
|
m[ 8] = btScalar(m1[ 0]*m2[ 8]+m1[ 4]*m2[ 9]+m1[ 8]*m2[10]+m1[12]*m2[11]);
|
||||||
|
m[ 9] = btScalar(m1[ 1]*m2[ 8]+m1[ 5]*m2[ 9]+m1[ 9]*m2[10]+m1[13]*m2[11]);
|
||||||
|
m[10] = btScalar(m1[ 2]*m2[ 8]+m1[ 6]*m2[ 9]+m1[10]*m2[10]+m1[14]*m2[11]);
|
||||||
|
m[11] = btScalar(m1[ 3]*m2[ 8]+m1[ 7]*m2[ 9]+m1[11]*m2[10]+m1[15]*m2[11]);
|
||||||
|
|
||||||
|
m[12] = btScalar(m1[ 0]*m2[12]+m1[ 4]*m2[13]+m1[ 8]*m2[14]+m1[12]*m2[15]);
|
||||||
|
m[13] = btScalar(m1[ 1]*m2[12]+m1[ 5]*m2[13]+m1[ 9]*m2[14]+m1[13]*m2[15]);
|
||||||
|
m[14] = btScalar(m1[ 2]*m2[12]+m1[ 6]*m2[13]+m1[10]*m2[14]+m1[14]*m2[15]);
|
||||||
|
m[15] = btScalar(m1[ 3]*m2[12]+m1[ 7]*m2[13]+m1[11]*m2[14]+m1[15]*m2[15]);
|
||||||
|
}
|
||||||
|
void setup(int size)
|
||||||
|
{
|
||||||
|
m_initialized=false;
|
||||||
|
m_occlusion=false;
|
||||||
|
// compute the size of the buffer
|
||||||
|
GLint v[4];
|
||||||
|
GLdouble m[16],p[16];
|
||||||
|
int maxsize;
|
||||||
|
double ratio;
|
||||||
|
glGetIntegerv(GL_VIEWPORT,v);
|
||||||
|
maxsize = (v[2] > v[3]) ? v[2] : v[3];
|
||||||
|
assert(maxsize > 0);
|
||||||
|
ratio = 1.0/(2*maxsize);
|
||||||
|
// ensure even number
|
||||||
|
m_sizes[0] = 2*((int)(size*v[2]*ratio+0.5));
|
||||||
|
m_sizes[1] = 2*((int)(size*v[3]*ratio+0.5));
|
||||||
|
m_scales[0]=btScalar(m_sizes[0]/2);
|
||||||
|
m_scales[1]=btScalar(m_sizes[1]/2);
|
||||||
|
m_offsets[0]=m_scales[0]+0.5f;
|
||||||
|
m_offsets[1]=m_scales[1]+0.5f;
|
||||||
|
// prepare matrix
|
||||||
|
// at this time of the rendering, the modelview matrix is the
|
||||||
|
// world to camera transformation and the projection matrix is
|
||||||
|
// camera to clip transformation. combine both so that
|
||||||
|
glGetDoublev(GL_MODELVIEW_MATRIX,m);
|
||||||
|
glGetDoublev(GL_PROJECTION_MATRIX,p);
|
||||||
|
CMmat4mul(m_wtc,p,m);
|
||||||
|
}
|
||||||
|
void initialize()
|
||||||
|
{
|
||||||
|
size_t newsize = (m_sizes[0]*m_sizes[1])*sizeof(btScalar);
|
||||||
|
if (m_buffer)
|
||||||
|
{
|
||||||
|
// see if we can reuse
|
||||||
|
if (newsize > m_bufferSize)
|
||||||
|
{
|
||||||
|
free(m_buffer);
|
||||||
|
m_buffer = NULL;
|
||||||
|
m_bufferSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!m_buffer)
|
||||||
|
{
|
||||||
|
m_buffer = (btScalar*)calloc(1, newsize);
|
||||||
|
m_bufferSize = newsize;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// buffer exists already, just clears it
|
||||||
|
memset(m_buffer, 0, newsize);
|
||||||
|
}
|
||||||
|
// memory allocate must succeed
|
||||||
|
assert(m_buffer != NULL);
|
||||||
|
m_initialized = true;
|
||||||
|
m_occlusion = false;
|
||||||
|
}
|
||||||
|
void SetModelMatrix(double *fl)
|
||||||
|
{
|
||||||
|
CMmat4mul(m_mtc,m_wtc,fl);
|
||||||
|
if (!m_initialized)
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// transform a segment in world coordinate to clip coordinate
|
||||||
|
void transformW(const btVector3& x, btVector4& t)
|
||||||
|
{
|
||||||
|
t[0] = x[0]*m_wtc[0]+x[1]*m_wtc[4]+x[2]*m_wtc[8]+m_wtc[12];
|
||||||
|
t[1] = x[0]*m_wtc[1]+x[1]*m_wtc[5]+x[2]*m_wtc[9]+m_wtc[13];
|
||||||
|
t[2] = x[0]*m_wtc[2]+x[1]*m_wtc[6]+x[2]*m_wtc[10]+m_wtc[14];
|
||||||
|
t[3] = x[0]*m_wtc[3]+x[1]*m_wtc[7]+x[2]*m_wtc[11]+m_wtc[15];
|
||||||
|
}
|
||||||
|
void transformM(const float* x, btVector4& t)
|
||||||
|
{
|
||||||
|
t[0] = x[0]*m_mtc[0]+x[1]*m_mtc[4]+x[2]*m_mtc[8]+m_mtc[12];
|
||||||
|
t[1] = x[0]*m_mtc[1]+x[1]*m_mtc[5]+x[2]*m_mtc[9]+m_mtc[13];
|
||||||
|
t[2] = x[0]*m_mtc[2]+x[1]*m_mtc[6]+x[2]*m_mtc[10]+m_mtc[14];
|
||||||
|
t[3] = x[0]*m_mtc[3]+x[1]*m_mtc[7]+x[2]*m_mtc[11]+m_mtc[15];
|
||||||
|
}
|
||||||
|
// convert polygon to device coordinates
|
||||||
|
static bool project(btVector4* p,int n)
|
||||||
|
{
|
||||||
|
for(int i=0;i<n;++i)
|
||||||
|
{
|
||||||
|
const btScalar iw=1/p[i][3];
|
||||||
|
p[i][2]=1/p[i][3];
|
||||||
|
p[i][0]*=p[i][2];
|
||||||
|
p[i][1]*=p[i][2];
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
// pi: closed polygon in clip coordinate, NP = number of segments
|
||||||
|
// po: same polygon with clipped segments removed
|
||||||
|
template <const int NP>
|
||||||
|
static int clip(const btVector4* pi,btVector4* po)
|
||||||
|
{
|
||||||
|
btScalar s[2*NP];
|
||||||
|
btVector4 pn[2*NP], *p;
|
||||||
|
int i, j, m, n, ni;
|
||||||
|
// deal with near clipping
|
||||||
|
for(i=0, m=0;i<NP;++i)
|
||||||
|
{
|
||||||
|
s[i]=pi[i][2]+pi[i][3];
|
||||||
|
if(s[i]<0) m+=1<<i;
|
||||||
|
}
|
||||||
|
if(m==((1<<NP)-1))
|
||||||
|
return(0);
|
||||||
|
if(m!=0)
|
||||||
|
{
|
||||||
|
for(i=NP-1,j=0,n=0;j<NP;i=j++)
|
||||||
|
{
|
||||||
|
const btVector4& a=pi[i];
|
||||||
|
const btVector4& b=pi[j];
|
||||||
|
const btScalar t=s[i]/(a[3]+a[2]-b[3]-b[2]);
|
||||||
|
if((t>0)&&(t<1))
|
||||||
|
{
|
||||||
|
pn[n][0] = a[0]+(b[0]-a[0])*t;
|
||||||
|
pn[n][1] = a[1]+(b[1]-a[1])*t;
|
||||||
|
pn[n][2] = a[2]+(b[2]-a[2])*t;
|
||||||
|
pn[n][3] = a[3]+(b[3]-a[3])*t;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
if(s[j]>0) pn[n++]=b;
|
||||||
|
}
|
||||||
|
// ready to test far clipping, start from the modified polygon
|
||||||
|
pi = pn;
|
||||||
|
ni = n;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// no clipping on the near plane, keep same vector
|
||||||
|
ni = NP;
|
||||||
|
}
|
||||||
|
// now deal with far clipping
|
||||||
|
for(i=0, m=0;i<ni;++i)
|
||||||
|
{
|
||||||
|
s[i]=pi[i][2]-pi[i][3];
|
||||||
|
if(s[i]>0) m+=1<<i;
|
||||||
|
}
|
||||||
|
if(m==((1<<ni)-1))
|
||||||
|
return(0);
|
||||||
|
if(m!=0)
|
||||||
|
{
|
||||||
|
for(i=ni-1,j=0,n=0;j<ni;i=j++)
|
||||||
|
{
|
||||||
|
const btVector4& a=pi[i];
|
||||||
|
const btVector4& b=pi[j];
|
||||||
|
const btScalar t=s[i]/(a[2]-a[3]-b[2]+b[3]);
|
||||||
|
if((t>0)&&(t<1))
|
||||||
|
{
|
||||||
|
po[n][0] = a[0]+(b[0]-a[0])*t;
|
||||||
|
po[n][1] = a[1]+(b[1]-a[1])*t;
|
||||||
|
po[n][2] = a[2]+(b[2]-a[2])*t;
|
||||||
|
po[n][3] = a[3]+(b[3]-a[3])*t;
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
if(s[j]<0) po[n++]=b;
|
||||||
|
}
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
for(int i=0;i<ni;++i) po[i]=pi[i];
|
||||||
|
return(ni);
|
||||||
|
}
|
||||||
|
// write or check a triangle to buffer. a,b,c in device coordinates (-1,+1)
|
||||||
|
template <typename POLICY>
|
||||||
|
inline bool draw( const btVector4& a,
|
||||||
|
const btVector4& b,
|
||||||
|
const btVector4& c,
|
||||||
|
const float face,
|
||||||
|
const btScalar minarea)
|
||||||
|
{
|
||||||
|
const btScalar a2=cross(b-a,c-a)[2];
|
||||||
|
if((face*a2)<0.f || btFabs(a2)<minarea)
|
||||||
|
return false;
|
||||||
|
// further down we are normally going to write to the Zbuffer, mark it so
|
||||||
|
POLICY::Occlusion(m_occlusion);
|
||||||
|
|
||||||
|
int x[3], y[3], ib=1, ic=2;
|
||||||
|
btScalar z[3];
|
||||||
|
x[0]=(int)(a.x()*m_scales[0]+m_offsets[0]);
|
||||||
|
y[0]=(int)(a.y()*m_scales[1]+m_offsets[1]);
|
||||||
|
z[0]=a.z();
|
||||||
|
if (a2 < 0.f)
|
||||||
|
{
|
||||||
|
// negative aire is possible with double face => must
|
||||||
|
// change the order of b and c otherwise the algorithm doesn't work
|
||||||
|
ib=2;
|
||||||
|
ic=1;
|
||||||
|
}
|
||||||
|
x[ib]=(int)(b.x()*m_scales[0]+m_offsets[0]);
|
||||||
|
x[ic]=(int)(c.x()*m_scales[0]+m_offsets[0]);
|
||||||
|
y[ib]=(int)(b.y()*m_scales[1]+m_offsets[1]);
|
||||||
|
y[ic]=(int)(c.y()*m_scales[1]+m_offsets[1]);
|
||||||
|
z[ib]=b.z();
|
||||||
|
z[ic]=c.z();
|
||||||
|
const int mix=btMax(0,btMin(x[0],btMin(x[1],x[2])));
|
||||||
|
const int mxx=btMin(m_sizes[0],1+btMax(x[0],btMax(x[1],x[2])));
|
||||||
|
const int miy=btMax(0,btMin(y[0],btMin(y[1],y[2])));
|
||||||
|
const int mxy=btMin(m_sizes[1],1+btMax(y[0],btMax(y[1],y[2])));
|
||||||
|
const int width=mxx-mix;
|
||||||
|
const int height=mxy-miy;
|
||||||
|
if ((width*height) <= 1)
|
||||||
|
{
|
||||||
|
// degenerated in at most one single pixel
|
||||||
|
btScalar* scan=&m_buffer[miy*m_sizes[0]+mix];
|
||||||
|
// use for loop to detect the case where width or height == 0
|
||||||
|
for(int iy=miy;iy<mxy;++iy)
|
||||||
|
{
|
||||||
|
for(int ix=mix;ix<mxx;++ix)
|
||||||
|
{
|
||||||
|
if(POLICY::Process(*scan,z[0]))
|
||||||
|
return(true);
|
||||||
|
if(POLICY::Process(*scan,z[1]))
|
||||||
|
return(true);
|
||||||
|
if(POLICY::Process(*scan,z[2]))
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (width == 1)
|
||||||
|
{
|
||||||
|
// Degenerated in at least 2 vertical lines
|
||||||
|
// The algorithm below doesn't work when face has a single pixel width
|
||||||
|
// We cannot use general formulas because the plane is degenerated.
|
||||||
|
// We have to interpolate along the 3 edges that overlaps and process each pixel.
|
||||||
|
// sort the y coord to make formula simpler
|
||||||
|
int ytmp;
|
||||||
|
btScalar ztmp;
|
||||||
|
if (y[0] > y[1]) { ytmp=y[1];y[1]=y[0];y[0]=ytmp;ztmp=z[1];z[1]=z[0];z[0]=ztmp; }
|
||||||
|
if (y[0] > y[2]) { ytmp=y[2];y[2]=y[0];y[0]=ytmp;ztmp=z[2];z[2]=z[0];z[0]=ztmp; }
|
||||||
|
if (y[1] > y[2]) { ytmp=y[2];y[2]=y[1];y[1]=ytmp;ztmp=z[2];z[2]=z[1];z[1]=ztmp; }
|
||||||
|
int dy[]={ y[0]-y[1],
|
||||||
|
y[1]-y[2],
|
||||||
|
y[2]-y[0]};
|
||||||
|
btScalar dzy[3];
|
||||||
|
dzy[0] = (dy[0]) ? (z[0]-z[1])/dy[0] : btScalar(0.f);
|
||||||
|
dzy[1] = (dy[1]) ? (z[1]-z[2])/dy[1] : btScalar(0.f);
|
||||||
|
dzy[2] = (dy[2]) ? (z[2]-z[0])/dy[2] : btScalar(0.f);
|
||||||
|
btScalar v[3] = { dzy[0]*(miy-y[0])+z[0],
|
||||||
|
dzy[1]*(miy-y[1])+z[1],
|
||||||
|
dzy[2]*(miy-y[2])+z[2] };
|
||||||
|
dy[0] = y[1]-y[0];
|
||||||
|
dy[1] = y[0]-y[1];
|
||||||
|
dy[2] = y[2]-y[0];
|
||||||
|
btScalar* scan=&m_buffer[miy*m_sizes[0]+mix];
|
||||||
|
for(int iy=miy;iy<mxy;++iy)
|
||||||
|
{
|
||||||
|
if(dy[0] >= 0 && POLICY::Process(*scan,v[0]))
|
||||||
|
return(true);
|
||||||
|
if(dy[1] >= 0 && POLICY::Process(*scan,v[1]))
|
||||||
|
return(true);
|
||||||
|
if(dy[2] >= 0 && POLICY::Process(*scan,v[2]))
|
||||||
|
return(true);
|
||||||
|
scan+=m_sizes[0];
|
||||||
|
v[0] += dzy[0]; v[1] += dzy[1]; v[2] += dzy[2];
|
||||||
|
dy[0]--; dy[1]++, dy[2]--;
|
||||||
|
}
|
||||||
|
} else if (height == 1)
|
||||||
|
{
|
||||||
|
// Degenerated in at least 2 horizontal lines
|
||||||
|
// The algorithm below doesn't work when face has a single pixel width
|
||||||
|
// We cannot use general formulas because the plane is degenerated.
|
||||||
|
// We have to interpolate along the 3 edges that overlaps and process each pixel.
|
||||||
|
int xtmp;
|
||||||
|
btScalar ztmp;
|
||||||
|
if (x[0] > x[1]) { xtmp=x[1];x[1]=x[0];x[0]=xtmp;ztmp=z[1];z[1]=z[0];z[0]=ztmp; }
|
||||||
|
if (x[0] > x[2]) { xtmp=x[2];x[2]=x[0];x[0]=xtmp;ztmp=z[2];z[2]=z[0];z[0]=ztmp; }
|
||||||
|
if (x[1] > x[2]) { xtmp=x[2];x[2]=x[1];x[1]=xtmp;ztmp=z[2];z[2]=z[1];z[1]=ztmp; }
|
||||||
|
int dx[]={ x[0]-x[1],
|
||||||
|
x[1]-x[2],
|
||||||
|
x[2]-x[0]};
|
||||||
|
btScalar dzx[3];
|
||||||
|
dzx[0] = (dx[0]) ? (z[0]-z[1])/dx[0] : btScalar(0.f);
|
||||||
|
dzx[1] = (dx[1]) ? (z[1]-z[2])/dx[1] : btScalar(0.f);
|
||||||
|
dzx[2] = (dx[2]) ? (z[2]-z[0])/dx[2] : btScalar(0.f);
|
||||||
|
btScalar v[3] = { dzx[0]*(mix-x[0])+z[0],
|
||||||
|
dzx[1]*(mix-x[1])+z[1],
|
||||||
|
dzx[2]*(mix-x[2])+z[2] };
|
||||||
|
dx[0] = x[1]-x[0];
|
||||||
|
dx[1] = x[0]-x[1];
|
||||||
|
dx[2] = x[2]-x[0];
|
||||||
|
btScalar* scan=&m_buffer[miy*m_sizes[0]+mix];
|
||||||
|
for(int ix=mix;ix<mxx;++ix)
|
||||||
|
{
|
||||||
|
if(dx[0] >= 0 && POLICY::Process(*scan,v[0]))
|
||||||
|
return(true);
|
||||||
|
if(dx[1] >= 0 && POLICY::Process(*scan,v[1]))
|
||||||
|
return(true);
|
||||||
|
if(dx[2] >= 0 && POLICY::Process(*scan,v[2]))
|
||||||
|
return(true);
|
||||||
|
scan++;
|
||||||
|
v[0] += dzx[0]; v[1] += dzx[1]; v[2] += dzx[2];
|
||||||
|
dx[0]--; dx[1]++, dx[2]--;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// general case
|
||||||
|
const int dx[]={ y[0]-y[1],
|
||||||
|
y[1]-y[2],
|
||||||
|
y[2]-y[0]};
|
||||||
|
const int dy[]={ x[1]-x[0]-dx[0]*width,
|
||||||
|
x[2]-x[1]-dx[1]*width,
|
||||||
|
x[0]-x[2]-dx[2]*width};
|
||||||
|
const int a=x[2]*y[0]+x[0]*y[1]-x[2]*y[1]-x[0]*y[2]+x[1]*y[2]-x[1]*y[0];
|
||||||
|
const btScalar ia=1/(btScalar)a;
|
||||||
|
const btScalar dzx=ia*(y[2]*(z[1]-z[0])+y[1]*(z[0]-z[2])+y[0]*(z[2]-z[1]));
|
||||||
|
const btScalar dzy=ia*(x[2]*(z[0]-z[1])+x[0]*(z[1]-z[2])+x[1]*(z[2]-z[0]))-(dzx*width);
|
||||||
|
int c[]={ miy*x[1]+mix*y[0]-x[1]*y[0]-mix*y[1]+x[0]*y[1]-miy*x[0],
|
||||||
|
miy*x[2]+mix*y[1]-x[2]*y[1]-mix*y[2]+x[1]*y[2]-miy*x[1],
|
||||||
|
miy*x[0]+mix*y[2]-x[0]*y[2]-mix*y[0]+x[2]*y[0]-miy*x[2]};
|
||||||
|
btScalar v=ia*((z[2]*c[0])+(z[0]*c[1])+(z[1]*c[2]));
|
||||||
|
btScalar* scan=&m_buffer[miy*m_sizes[0]];
|
||||||
|
for(int iy=miy;iy<mxy;++iy)
|
||||||
|
{
|
||||||
|
for(int ix=mix;ix<mxx;++ix)
|
||||||
|
{
|
||||||
|
if((c[0]>=0)&&(c[1]>=0)&&(c[2]>=0))
|
||||||
|
{
|
||||||
|
if(POLICY::Process(scan[ix],v))
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
c[0]+=dx[0];c[1]+=dx[1];c[2]+=dx[2];v+=dzx;
|
||||||
|
}
|
||||||
|
c[0]+=dy[0];c[1]+=dy[1];c[2]+=dy[2];v+=dzy;
|
||||||
|
scan+=m_sizes[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
// clip than write or check a polygon
|
||||||
|
template <const int NP,typename POLICY>
|
||||||
|
inline bool clipDraw( const btVector4* p,
|
||||||
|
const float face,
|
||||||
|
btScalar minarea)
|
||||||
|
{
|
||||||
|
btVector4 o[NP*2];
|
||||||
|
int n=clip<NP>(p,o);
|
||||||
|
bool earlyexit=false;
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
project(o,n);
|
||||||
|
for(int i=2;i<n && !earlyexit;++i)
|
||||||
|
{
|
||||||
|
earlyexit|=draw<POLICY>(o[0],o[i-1],o[i],face,minarea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(earlyexit);
|
||||||
|
}
|
||||||
|
// add a triangle (in model coordinate)
|
||||||
|
// face = 0.f if face is double side,
|
||||||
|
// = 1.f if face is single sided and scale is positive
|
||||||
|
// = -1.f if face is single sided and scale is negative
|
||||||
|
void appendOccluderM(const float* a,
|
||||||
|
const float* b,
|
||||||
|
const float* c,
|
||||||
|
const float face)
|
||||||
|
{
|
||||||
|
btVector4 p[3];
|
||||||
|
transformM(a,p[0]);
|
||||||
|
transformM(b,p[1]);
|
||||||
|
transformM(c,p[2]);
|
||||||
|
clipDraw<3,WriteOCL>(p,face,btScalar(0.f));
|
||||||
|
}
|
||||||
|
// add a quad (in model coordinate)
|
||||||
|
void appendOccluderM(const float* a,
|
||||||
|
const float* b,
|
||||||
|
const float* c,
|
||||||
|
const float* d,
|
||||||
|
const float face)
|
||||||
|
{
|
||||||
|
btVector4 p[4];
|
||||||
|
transformM(a,p[0]);
|
||||||
|
transformM(b,p[1]);
|
||||||
|
transformM(c,p[2]);
|
||||||
|
transformM(d,p[3]);
|
||||||
|
clipDraw<4,WriteOCL>(p,face,btScalar(0.f));
|
||||||
|
}
|
||||||
|
// query occluder for a box (c=center, e=extend) in world coordinate
|
||||||
|
inline bool queryOccluderW( const btVector3& c,
|
||||||
|
const btVector3& e)
|
||||||
|
{
|
||||||
|
if (!m_occlusion)
|
||||||
|
// no occlusion yet, no need to check
|
||||||
|
return true;
|
||||||
|
btVector4 x[8];
|
||||||
|
transformW(btVector3(c[0]-e[0],c[1]-e[1],c[2]-e[2]),x[0]);
|
||||||
|
transformW(btVector3(c[0]+e[0],c[1]-e[1],c[2]-e[2]),x[1]);
|
||||||
|
transformW(btVector3(c[0]+e[0],c[1]+e[1],c[2]-e[2]),x[2]);
|
||||||
|
transformW(btVector3(c[0]-e[0],c[1]+e[1],c[2]-e[2]),x[3]);
|
||||||
|
transformW(btVector3(c[0]-e[0],c[1]-e[1],c[2]+e[2]),x[4]);
|
||||||
|
transformW(btVector3(c[0]+e[0],c[1]-e[1],c[2]+e[2]),x[5]);
|
||||||
|
transformW(btVector3(c[0]+e[0],c[1]+e[1],c[2]+e[2]),x[6]);
|
||||||
|
transformW(btVector3(c[0]-e[0],c[1]+e[1],c[2]+e[2]),x[7]);
|
||||||
|
for(int i=0;i<8;++i)
|
||||||
|
{
|
||||||
|
// the box is clipped, it's probably a large box, don't waste our time to check
|
||||||
|
if((x[i][2]+x[i][3])<=0) return(true);
|
||||||
|
}
|
||||||
|
static const int d[]={ 1,0,3,2,
|
||||||
|
4,5,6,7,
|
||||||
|
4,7,3,0,
|
||||||
|
6,5,1,2,
|
||||||
|
7,6,2,3,
|
||||||
|
5,4,0,1};
|
||||||
|
for(int i=0;i<(sizeof(d)/sizeof(d[0]));)
|
||||||
|
{
|
||||||
|
const btVector4 p[]={ x[d[i++]],
|
||||||
|
x[d[i++]],
|
||||||
|
x[d[i++]],
|
||||||
|
x[d[i++]]};
|
||||||
|
if(clipDraw<4,QueryOCL>(p,1.f,0.f))
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DbvtCullingCallback : btDbvt::ICollide
|
struct DbvtCullingCallback : btDbvt::ICollide
|
||||||
{
|
{
|
||||||
PHY_CullingCallback m_clientCallback;
|
PHY_CullingCallback m_clientCallback;
|
||||||
void* m_userData;
|
void* m_userData;
|
||||||
|
OcclusionBuffer *m_ocb;
|
||||||
|
|
||||||
DbvtCullingCallback(PHY_CullingCallback clientCallback, void* userData)
|
DbvtCullingCallback(PHY_CullingCallback clientCallback, void* userData)
|
||||||
{
|
{
|
||||||
m_clientCallback = clientCallback;
|
m_clientCallback = clientCallback;
|
||||||
m_userData = userData;
|
m_userData = userData;
|
||||||
|
m_ocb = NULL;
|
||||||
|
}
|
||||||
|
bool Descent(const btDbvtNode* node)
|
||||||
|
{
|
||||||
|
return(m_ocb->queryOccluderW(node->volume.Center(),node->volume.Extents()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process(const btDbvtNode* node,btScalar depth)
|
void Process(const btDbvtNode* node,btScalar depth)
|
||||||
{
|
{
|
||||||
Process(node);
|
Process(node);
|
||||||
@ -1210,31 +1691,83 @@ struct DbvtCullingCallback : btDbvt::ICollide
|
|||||||
// the client object is a graphic controller
|
// the client object is a graphic controller
|
||||||
CcdGraphicController* ctrl = static_cast<CcdGraphicController*>(proxy->m_clientObject);
|
CcdGraphicController* ctrl = static_cast<CcdGraphicController*>(proxy->m_clientObject);
|
||||||
KX_ClientObjectInfo* info = (KX_ClientObjectInfo*)ctrl->getNewClientInfo();
|
KX_ClientObjectInfo* info = (KX_ClientObjectInfo*)ctrl->getNewClientInfo();
|
||||||
|
if (m_ocb)
|
||||||
|
{
|
||||||
|
// means we are doing occlusion culling. Check if this object is an occluders
|
||||||
|
KX_GameObject* gameobj = KX_GameObject::GetClientObject(info);
|
||||||
|
if (gameobj && gameobj->GetOccluder())
|
||||||
|
{
|
||||||
|
double* fl = gameobj->GetOpenGLMatrixPtr()->getPointer();
|
||||||
|
// this will create the occlusion buffer if not already done
|
||||||
|
// and compute the transformation from model local space to clip space
|
||||||
|
m_ocb->SetModelMatrix(fl);
|
||||||
|
float face = (gameobj->IsNegativeScaling()) ? -1.0f : 1.0f;
|
||||||
|
// walk through the meshes and for each add to buffer
|
||||||
|
for (int i=0; i<gameobj->GetMeshCount(); i++)
|
||||||
|
{
|
||||||
|
RAS_MeshObject* meshobj = gameobj->GetMesh(i);
|
||||||
|
const float *v1, *v2, *v3, *v4;
|
||||||
|
|
||||||
|
int polycount = meshobj->NumPolygons();
|
||||||
|
for (int j=0; j<polycount; j++)
|
||||||
|
{
|
||||||
|
RAS_Polygon* poly = meshobj->GetPolygon(j);
|
||||||
|
switch (poly->VertexCount())
|
||||||
|
{
|
||||||
|
case 3:
|
||||||
|
v1 = poly->GetVertex(0)->getXYZ();
|
||||||
|
v2 = poly->GetVertex(1)->getXYZ();
|
||||||
|
v3 = poly->GetVertex(2)->getXYZ();
|
||||||
|
m_ocb->appendOccluderM(v1,v2,v3,((poly->IsTwoside())?0.f:face));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
v1 = poly->GetVertex(0)->getXYZ();
|
||||||
|
v2 = poly->GetVertex(1)->getXYZ();
|
||||||
|
v3 = poly->GetVertex(2)->getXYZ();
|
||||||
|
v4 = poly->GetVertex(3)->getXYZ();
|
||||||
|
m_ocb->appendOccluderM(v1,v2,v3,v4,((poly->IsTwoside())?0.f:face));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (info)
|
if (info)
|
||||||
(*m_clientCallback)(info, m_userData);
|
(*m_clientCallback)(info, m_userData);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes)
|
static OcclusionBuffer gOcb;
|
||||||
|
bool CcdPhysicsEnvironment::cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes)
|
||||||
{
|
{
|
||||||
if (!m_cullingTree)
|
if (!m_cullingTree)
|
||||||
return false;
|
return false;
|
||||||
DbvtCullingCallback dispatcher(callback, userData);
|
DbvtCullingCallback dispatcher(callback, userData);
|
||||||
btVector3 planes_n[5];
|
btVector3 planes_n[6];
|
||||||
btScalar planes_o[5];
|
btScalar planes_o[6];
|
||||||
if (nplanes > 5)
|
if (nplanes > 6)
|
||||||
nplanes = 5;
|
nplanes = 6;
|
||||||
for (int i=0; i<nplanes; i++)
|
for (int i=0; i<nplanes; i++)
|
||||||
{
|
{
|
||||||
planes_n[i].setValue(planes[i][0], planes[i][1], planes[i][2]);
|
planes_n[i].setValue(planes[i][0], planes[i][1], planes[i][2]);
|
||||||
planes_o[i] = planes[i][3];
|
planes_o[i] = planes[i][3];
|
||||||
}
|
}
|
||||||
btDbvt::collideKDOP(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,nplanes,dispatcher);
|
// if occlusionRes != 0 => occlusion culling
|
||||||
btDbvt::collideKDOP(m_cullingTree->m_sets[0].m_root,planes_n,planes_o,nplanes,dispatcher);
|
if (occlusionRes)
|
||||||
|
{
|
||||||
|
gOcb.setup(occlusionRes);
|
||||||
|
dispatcher.m_ocb = &gOcb;
|
||||||
|
// occlusion culling, the direction of the view is taken from the first plan which MUST be the near plane
|
||||||
|
btDbvt::collideOCL(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,planes_n[0],nplanes,dispatcher);
|
||||||
|
btDbvt::collideOCL(m_cullingTree->m_sets[0].m_root,planes_n,planes_o,planes_n[0],nplanes,dispatcher);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
btDbvt::collideKDOP(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,nplanes,dispatcher);
|
||||||
|
btDbvt::collideKDOP(m_cullingTree->m_sets[0].m_root,planes_n,planes_o,nplanes,dispatcher);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CcdPhysicsEnvironment::getNumContactPoints()
|
int CcdPhysicsEnvironment::getNumContactPoints()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -172,7 +172,7 @@ protected:
|
|||||||
btTypedConstraint* getConstraintById(int constraintId);
|
btTypedConstraint* getConstraintById(int constraintId);
|
||||||
|
|
||||||
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
|
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
|
||||||
virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes);
|
virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes);
|
||||||
|
|
||||||
|
|
||||||
//Methods for gamelogic collision/physics callbacks
|
//Methods for gamelogic collision/physics callbacks
|
||||||
|
@ -39,9 +39,16 @@ CPPFLAGS += -I$(NAN_BULLET2)/include
|
|||||||
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
|
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
|
||||||
CPPFLAGS += -I$(NAN_STRING)/include
|
CPPFLAGS += -I$(NAN_STRING)/include
|
||||||
CPPFLAGS += -I$(NAN_MOTO)/include
|
CPPFLAGS += -I$(NAN_MOTO)/include
|
||||||
|
CPPFLAGS += -I$(NAN_GLEW)/include
|
||||||
|
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
|
||||||
|
CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include
|
||||||
CPPFLAGS += -I../../../kernel/gen_system
|
CPPFLAGS += -I../../../kernel/gen_system
|
||||||
CPPFLAGS += -I../../Physics/common
|
CPPFLAGS += -I../../Physics/common
|
||||||
CPPFLAGS += -I../../Physics/Dummy
|
CPPFLAGS += -I../../Physics/Dummy
|
||||||
CPPFLAGS += -I../../Rasterizer
|
CPPFLAGS += -I../../Rasterizer
|
||||||
|
CPPFLAGS += -I../../Ketsji
|
||||||
|
CPPFLAGS += -I../../Expressions
|
||||||
|
CPPFLAGS += -I../../GameLogic
|
||||||
|
CPPFLAGS += -I../../SceneGraph
|
||||||
CPPFLAGS += -I../../../../source/blender/makesdna
|
CPPFLAGS += -I../../../../source/blender/makesdna
|
||||||
|
|
||||||
|
@ -3,9 +3,21 @@ Import ('env')
|
|||||||
|
|
||||||
sources = 'CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp CcdGraphicController.cpp'
|
sources = 'CcdPhysicsEnvironment.cpp CcdPhysicsController.cpp CcdGraphicController.cpp'
|
||||||
|
|
||||||
incs = '. ../common #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/blender/makesdna'
|
incs = '. ../common'
|
||||||
|
incs += ' #source/kernel/gen_system'
|
||||||
|
incs += ' #intern/string'
|
||||||
|
incs += ' #intern/moto/include'
|
||||||
|
incs += ' #extern/glew/include'
|
||||||
|
incs += ' #source/gameengine/Rasterizer'
|
||||||
|
incs += ' #source/gameengine/Ketsji'
|
||||||
|
incs += ' #source/gameengine/Expressions'
|
||||||
|
incs += ' #source/gameengine/GameLogic'
|
||||||
|
incs += ' #source/gameengine/SceneGraph'
|
||||||
|
incs += ' #source/blender/makesdna'
|
||||||
|
incs += ' #intern/SoundSystem'
|
||||||
|
|
||||||
incs += ' ' + env['BF_BULLET_INC']
|
incs += ' ' + env['BF_BULLET_INC']
|
||||||
|
incs += ' ' + env['BF_PYTHON_INC']
|
||||||
|
|
||||||
cxxflags = []
|
cxxflags = []
|
||||||
if env['OURPLATFORM']=='win32-vc':
|
if env['OURPLATFORM']=='win32-vc':
|
||||||
|
@ -70,7 +70,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
|
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
|
||||||
virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes) { return false; }
|
virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4* planes, int nplanes, int occlusionRes) { return false; }
|
||||||
|
|
||||||
|
|
||||||
//gamelogic callbacks
|
//gamelogic callbacks
|
||||||
|
@ -76,7 +76,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
|
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ);
|
||||||
virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes) { return false; }
|
virtual bool cullingTest(PHY_CullingCallback callback, void* userData, PHY__Vector4 *planes, int nplanes, int occlusionRes) { return false; }
|
||||||
|
|
||||||
|
|
||||||
//gamelogic callbacks
|
//gamelogic callbacks
|
||||||
|
@ -143,7 +143,9 @@ class PHY_IPhysicsEnvironment
|
|||||||
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ)=0;
|
virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ)=0;
|
||||||
|
|
||||||
//culling based on physical broad phase
|
//culling based on physical broad phase
|
||||||
virtual bool cullingTest(PHY_CullingCallback callback, void *userData, PHY__Vector4* planeNormals, int planeNumber) = 0;
|
// the plane number must be set as follow: near, far, left, right, top, botton
|
||||||
|
// the near plane must be the first one and must always be present, it is used to get the direction of the view
|
||||||
|
virtual bool cullingTest(PHY_CullingCallback callback, void *userData, PHY__Vector4* planeNormals, int planeNumber, int occlusionRes) = 0;
|
||||||
|
|
||||||
//Methods for gamelogic collision/physics callbacks
|
//Methods for gamelogic collision/physics callbacks
|
||||||
//todo:
|
//todo:
|
||||||
|
@ -25,6 +25,8 @@ class KX_GameObject: # (SCA_IObject)
|
|||||||
@ivar visible: visibility flag.
|
@ivar visible: visibility flag.
|
||||||
- note: Game logic will still run for invisible objects.
|
- note: Game logic will still run for invisible objects.
|
||||||
@type visible: boolean
|
@type visible: boolean
|
||||||
|
@ivar occlusion: occlusion capability flag.
|
||||||
|
@type occlusion: boolean
|
||||||
@ivar position: The object's position.
|
@ivar position: The object's position.
|
||||||
@type position: list [x, y, z]
|
@type position: list [x, y, z]
|
||||||
@ivar orientation: The object's orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector.
|
@ivar orientation: The object's orientation. 3x3 Matrix. You can also write a Quaternion or Euler vector.
|
||||||
@ -76,6 +78,14 @@ class KX_GameObject: # (SCA_IObject)
|
|||||||
@type recursive: boolean
|
@type recursive: boolean
|
||||||
@param recursive: optional argument to set all childrens visibility flag too.
|
@param recursive: optional argument to set all childrens visibility flag too.
|
||||||
"""
|
"""
|
||||||
|
def setOcclusion(occlusion, recursive):
|
||||||
|
"""
|
||||||
|
Sets the game object's occlusion capability.
|
||||||
|
|
||||||
|
@type visible: boolean
|
||||||
|
@type recursive: boolean
|
||||||
|
@param recursive: optional argument to set all childrens occlusion flag too.
|
||||||
|
"""
|
||||||
def getState():
|
def getState():
|
||||||
"""
|
"""
|
||||||
Gets the game object's state bitmask. (B{deprecated})
|
Gets the game object's state bitmask. (B{deprecated})
|
||||||
|
@ -7,7 +7,9 @@ class KX_VisibilityActuator(SCA_IActuator):
|
|||||||
Visibility Actuator.
|
Visibility Actuator.
|
||||||
@ivar visibility: whether the actuator makes its parent object visible or invisible
|
@ivar visibility: whether the actuator makes its parent object visible or invisible
|
||||||
@type visibility: boolean
|
@type visibility: boolean
|
||||||
@ivar recursion: whether the visibility/invisibility should be propagated to all children of the object
|
@ivar occlusion: whether the actuator makes its parent object an occluder or not
|
||||||
|
@type occlusion: boolean
|
||||||
|
@ivar recursion: whether the visibility/occlusion should be propagated to all children of the object
|
||||||
@type recursion: boolean
|
@type recursion: boolean
|
||||||
"""
|
"""
|
||||||
def set(visible):
|
def set(visible):
|
||||||
|
@ -62,10 +62,12 @@ RAS_MeshSlot::~RAS_MeshSlot()
|
|||||||
{
|
{
|
||||||
vector<RAS_DisplayArray*>::iterator it;
|
vector<RAS_DisplayArray*>::iterator it;
|
||||||
|
|
||||||
|
#ifdef USE_SPLIT
|
||||||
Split(true);
|
Split(true);
|
||||||
|
|
||||||
while(m_joinedSlots.size())
|
while(m_joinedSlots.size())
|
||||||
m_joinedSlots.front()->Split(true);
|
m_joinedSlots.front()->Split(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
|
for(it=m_displayArrays.begin(); it!=m_displayArrays.end(); it++) {
|
||||||
(*it)->m_users--;
|
(*it)->m_users--;
|
||||||
@ -428,11 +430,11 @@ bool RAS_MeshSlot::IsCulled()
|
|||||||
return true;
|
return true;
|
||||||
if(!m_bCulled)
|
if(!m_bCulled)
|
||||||
return false;
|
return false;
|
||||||
|
#ifdef USE_SPLIT
|
||||||
for(it=m_joinedSlots.begin(); it!=m_joinedSlots.end(); it++)
|
for(it=m_joinedSlots.begin(); it!=m_joinedSlots.end(); it++)
|
||||||
if(!(*it)->m_bCulled)
|
if(!(*it)->m_bCulled)
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +406,9 @@ void RAS_MeshObject::UpdateBuckets(void* clientobj,
|
|||||||
ms->m_bCulled = culled || !visible;
|
ms->m_bCulled = culled || !visible;
|
||||||
|
|
||||||
/* split if necessary */
|
/* split if necessary */
|
||||||
|
#ifdef USE_SPLIT
|
||||||
ms->Split();
|
ms->Split();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +97,17 @@ void RAS_Polygon::SetCollider(bool visible)
|
|||||||
else m_polyflags &= ~COLLIDER;
|
else m_polyflags &= ~COLLIDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RAS_Polygon::IsTwoside()
|
||||||
|
{
|
||||||
|
return (m_polyflags & TWOSIDE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RAS_Polygon::SetTwoside(bool twoside)
|
||||||
|
{
|
||||||
|
if(twoside) m_polyflags |= TWOSIDE;
|
||||||
|
else m_polyflags &= ~TWOSIDE;
|
||||||
|
}
|
||||||
|
|
||||||
RAS_MaterialBucket* RAS_Polygon::GetMaterial()
|
RAS_MaterialBucket* RAS_Polygon::GetMaterial()
|
||||||
{
|
{
|
||||||
return m_bucket;
|
return m_bucket;
|
||||||
|
@ -56,7 +56,8 @@ class RAS_Polygon
|
|||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
VISIBLE = 1,
|
VISIBLE = 1,
|
||||||
COLLIDER = 2
|
COLLIDER = 2,
|
||||||
|
TWOSIDE = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
RAS_Polygon(RAS_MaterialBucket* bucket, RAS_DisplayArray* darray, int numvert);
|
RAS_Polygon(RAS_MaterialBucket* bucket, RAS_DisplayArray* darray, int numvert);
|
||||||
@ -79,6 +80,9 @@ public:
|
|||||||
bool IsCollider();
|
bool IsCollider();
|
||||||
void SetCollider(bool collider);
|
void SetCollider(bool collider);
|
||||||
|
|
||||||
|
bool IsTwoside();
|
||||||
|
void SetTwoside(bool twoside);
|
||||||
|
|
||||||
RAS_MaterialBucket* GetMaterial();
|
RAS_MaterialBucket* GetMaterial();
|
||||||
RAS_DisplayArray* GetDisplayArray();
|
RAS_DisplayArray* GetDisplayArray();
|
||||||
};
|
};
|
||||||
|
@ -249,7 +249,7 @@ void ImageRender::Render()
|
|||||||
// restore the stereo mode now that the matrix is computed
|
// restore the stereo mode now that the matrix is computed
|
||||||
m_rasterizer->SetStereoMode(stereomode);
|
m_rasterizer->SetStereoMode(stereomode);
|
||||||
|
|
||||||
// do not update the mesh, we don't want to do it more than once per frame
|
// do not update the mesh transform, we don't want to do it more than once per frame
|
||||||
//m_scene->UpdateMeshTransformations();
|
//m_scene->UpdateMeshTransformations();
|
||||||
|
|
||||||
m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
|
m_scene->CalculateVisibleMeshes(m_rasterizer,m_camera);
|
||||||
|
Loading…
Reference in New Issue
Block a user