resolved conflict state with HEAD r14096

blenderbuttons still bad

not let this compile
This commit is contained in:
2008-03-13 23:54:02 +00:00
1174 changed files with 179989 additions and 80340 deletions

View File

@@ -65,8 +65,9 @@ OPTION(WITH_ELBEEM "Enable Elbeem (Fluid Simulation)" ON)
OPTION(WITH_QUICKTIME "Enable Quicktime Support" OFF)
OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" OFF)
OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF)
OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF)
OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
OPTION(YESIAMSTUPID "Enable execution on 64-bit platforms" OFF)
OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF)
IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
@@ -183,6 +184,13 @@ IF(UNIX)
SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++")
IF(WITH_OPENMP)
SET(LLIBS "${LLIBS} -lgomp ")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
ENDIF(WITH_OPENMP)
SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DXP_UNIX -Wno-char-subscripts")
SET(PLATFORM_LINKFLAGS "-pthread")
@@ -239,7 +247,11 @@ IF(WIN32)
SET(OPENEXR ${LIBDIR}/openexr)
SET(OPENEXR_INC ${OPENEXR}/include ${OPENEXR}/include/IlmImf ${OPENEXR}/include/Iex ${OPENEXR}/include/Imath)
SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread)
IF (MSVC80)
SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2005)
ELSE (MSVC80)
SET(OPENEXR_LIBPATH ${OPENEXR}/lib_msvc)
ENDIF(MSVC80)
SET(QUICKTIME ${LIBDIR}/QTDevWin)
SET(QUICKTIME_INC ${QUICKTIME}/CIncludes)
@@ -265,6 +277,11 @@ IF(WIN32)
SET(CMAKE_C_FLAGS_MINSIZEREL "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O1 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /J" CACHE STRING "MSVC MT flags " FORCE)
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /wd4800 /wd4244 /wd4305 /O2 /Ob1 /DNDEBUG /EHsc /MT /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
IF(WITH_OPENMP)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /openmp ")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp ")
ENDIF(WITH_OPENMP)
SET(SDL ${LIBDIR}/sdl)
SET(SDL_INC ${SDL}/include)
SET(SDL_LIB SDL)
@@ -342,6 +359,12 @@ IF(APPLE)
SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
IF(WITH_OPENMP)
SET(LLIBS "${LLIBS} -lgomp ")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")
ENDIF(WITH_OPENMP)
SET(SDL ${LIBDIR}/sdl)
SET(SDL_INC ${SDL}/include)
SET(SDL_LIB SDL)
@@ -361,6 +384,11 @@ IF(APPLE)
SET(EXETYPE MACOSX_BUNDLE)
ENDIF(APPLE)
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SET(BINRELOC ${CMAKE_SOURCE_DIR}/extern/binreloc)
SET(BINRELOC_INC ${BINRELOC}/include)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
#-----------------------------------------------------------------------------
# Common.
SET(VERSE_INC ${CMAKE_SOURCE_DIR}/extern/verse/dist)
@@ -379,6 +407,9 @@ INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
IF(WITH_GAMEENGINE)
SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DGAMEBLENDER ")
ENDIF(WITH_GAMEENGINE)
IF(WITH_BULLET)
SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DWITH_BULLET ")
ENDIF(WITH_BULLET)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS} ")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS} ")

View File

@@ -47,10 +47,15 @@ MAKEFLAGS=-I$(NANBLENDERHOME)/source --no-print-directory
SOURCEDIR =
ifeq ($(FREE_WINDOWS),true)
DIRS ?= dlltool extern intern source po
DIRS ?= dlltool extern intern source
endif
DIRS ?= extern intern source
ifneq ($(INTERNATIONAL),false)
DIRS += po
endif
DIRS ?= extern intern source po
include source/nan_subdirs.mk
.PHONY: release

View File

@@ -170,12 +170,32 @@ else:
opts = btools.read_opts(optfiles, B.arguments)
opts.Update(env)
if not env['BF_FANCY']:
B.bc.disable()
# disable elbeem (fluidsim) compilation?
if env['BF_NO_ELBEEM'] == 1:
env['CPPFLAGS'].append('-DDISABLE_ELBEEM')
env['CXXFLAGS'].append('-DDISABLE_ELBEEM')
env['CCFLAGS'].append('-DDISABLE_ELBEEM')
if env['WITH_BF_OPENMP'] == 1:
if env['OURPLATFORM']=='win32-vc':
env['CCFLAGS'].append('/openmp')
env['CPPFLAGS'].append('/openmp')
env['CXXFLAGS'].append('/openmp')
else:
if env['CC'] == 'icc':
env.Append(LINKFLAGS=['-openmp', '-static-intel'])
env['CCFLAGS'].append('-openmp')
env['CPPFLAGS'].append('-openmp')
env['CXXFLAGS'].append('-openmp')
else:
env.Append(LINKFLAGS=['-lgomp'])
env['CCFLAGS'].append('-fopenmp')
env['CPPFLAGS'].append('-fopenmp')
env['CXXFLAGS'].append('-fopenmp')
#check for additional debug libnames
if env.has_key('BF_DEBUG_LIBS'):
@@ -241,13 +261,16 @@ if 'clean' in B.targets:
do_clean = True
if not quickie and do_clean:
print B.bc.HEADER+'Cleaning...'+B.bc.ENDC
dirs = os.listdir(B.root_build_dir)
for dir in dirs:
if os.path.isdir(B.root_build_dir + dir) == 1:
print "clean dir %s"%(B.root_build_dir+dir)
shutil.rmtree(B.root_build_dir+dir)
print B.bc.OKGREEN+'...done'+B.bc.ENDC
if os.path.exists(B.root_build_dir):
print B.bc.HEADER+'Cleaning...'+B.bc.ENDC
dirs = os.listdir(B.root_build_dir)
for dir in dirs:
if os.path.isdir(B.root_build_dir + dir) == 1:
print "clean dir %s"%(B.root_build_dir+dir)
shutil.rmtree(B.root_build_dir+dir)
print B.bc.OKGREEN+'...done'+B.bc.ENDC
else:
print B.bc.HEADER+'Already Clean, nothing to do.'+B.bc.ENDC
Exit()
if not os.path.isdir ( B.root_build_dir):
@@ -390,12 +413,12 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
dllsources = ['${LCGDIR}/gettext/lib/gnu_gettext.dll',
'${LCGDIR}/png/lib/libpng.dll',
'#release/windows/extra/python25.zip',
# '#release/windows/extra/zlib.pyd',
'#release/windows/extra/zlib.pyd',
'${LCGDIR}/sdl/lib/SDL.dll',
'${LCGDIR}/zlib/lib/zlib.dll',
'${LCGDIR}/tiff/lib/libtiff.dll']
if env['BF_DEBUG']:
dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}.dll')
dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}_d.dll')
else:
dllsources.append('${LCGDIR}/python/lib/${BF_PYTHON_LIB}.dll')
if env['OURPLATFORM'] == 'win32-mingw':
@@ -404,10 +427,10 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
dllsources += ['${LCGDIR}/pthreads/lib/pthreadVC2.dll']
if env['WITH_BF_ICONV']:
dllsources += ['${LCGDIR}/iconv/lib/iconv.dll']
if env['WITH_BF_FFMPEG']:
dllsources += ['${LCGDIR}/ffmpeg/lib/avcodec-51.dll',
'${LCGDIR}/ffmpeg/lib/avformat-51.dll',
'${LCGDIR}/ffmpeg/lib/avutil-49.dll']
# if env['WITH_BF_FFMPEG']:
# dllsources += ['${LCGDIR}/ffmpeg/lib/avcodec-51.dll',
# '${LCGDIR}/ffmpeg/lib/avformat-51.dll',
# '${LCGDIR}/ffmpeg/lib/avutil-49.dll']
windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
allinstall += windlls
@@ -429,7 +452,9 @@ if not env['WITH_BF_GAMEENGINE']:
Depends(nsiscmd, allinstall)
Default(B.program_list)
Default(installtarget)
if not env['WITHOUT_BF_INSTALL']:
Default(installtarget)
#------------ RELEASE
# TODO: zipup the installation

View File

@@ -19,3 +19,4 @@ Polish:pl_PL
Romanian:ro
Arabic:ar
Bulgarian:bg
Greek:el

View File

@@ -54,6 +54,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread'
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'

View File

@@ -29,8 +29,14 @@ BF_FMOD = LIBDIR + '/fmod'
WITH_BF_OPENEXR = 'true'
BF_OPENEXR = '/usr'
# when compiling with your own openexr lib you might need to set...
# BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR ${BF_OPENEXR}/include'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
# BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
BF_JPEG = '/usr'
@@ -112,12 +118,17 @@ BF_ICONV_INC = '${BF_ICONV}/include'
BF_ICONV_LIB = 'iconv'
BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
WITH_BF_BINRELOC = 'true'
# enable ffmpeg support
WITH_BF_FFMPEG = 'false' # -DWITH_FFMPEG
BF_FFMPEG = '/usr'
WITH_BF_FFMPEG = 'true' # -DWITH_FFMPEG
BF_FFMPEG = '#extern/ffmpeg'
BF_FFMPEG_LIB = ''
# Uncomment the following two lines to use system's ffmpeg
# BF_FFMPEG = '/usr'
# BF_FFMPEG_LIB = 'avformat avcodec swscale avutil'
BF_FFMPEG_INC = '${BF_FFMPEG}/include'
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
BF_FFMPEG_LIB = 'avformat avcodec avutil'
# Mesa Libs should go here if your using them as well....
WITH_BF_STATICOPENGL = 'false'

View File

@@ -39,6 +39,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Half IlmImf Iex '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'

View File

@@ -28,6 +28,8 @@ BF_OPENEXR = '/usr/local'
BF_OPENEXR_INC = '${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
BF_JPEG = '/usr/local'
BF_JPEG_INC = '${BF_JPEG}/include'

View File

@@ -29,6 +29,8 @@ BF_OPENEXR_INC = ['${BF_OPENEXR}/include', '${BF_OPENEXR}/include/OpenEXR' ]
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
BF_OPENEXR_LIB = 'Half IlmImf Iex Imath '
WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
BF_JPEG = '/usr/local'
BF_JPEG_INC = '${BF_JPEG}/include'

View File

@@ -14,11 +14,11 @@ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = 'true'
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include'
BF_OPENAL_LIB = 'openal_static'
BF_OPENAL_LIB = 'dxguid openal_static'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_FFMPEG = 'false'
BF_FFMPEG_LIB = 'avformat avutil avcodec'
BF_FFMPEG_LIB = 'avformat swscale avcodec avutil xvidcore x264'
BF_FFMPEG_LIBPATH = LIBDIR + '/gcc/ffmpeg/lib'
BF_FFMPEG_INC = LIBDIR + '/gcc/ffmpeg/include'
@@ -42,6 +42,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
BF_OPENEXR_LIB = ' Half IlmImf Iex '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'
@@ -60,7 +62,6 @@ BF_TIFF_INC = '${BF_TIFF}/include'
WITH_BF_ZLIB = 'true'
BF_ZLIB = LIBDIR + '/zlib'
BF_ZLIB_INC = '${BF_ZLIB}/include'
#BF_ZLIB_LIB = 'z'
BF_ZLIB_LIBPATH = '${BF_ZLIB}/lib'
WITH_BF_INTERNATIONAL = 'true'
@@ -109,9 +110,6 @@ WITH_BF_YAFRAY = 'true'
#BF_MOZILLA_LIB =
# Will fall back to look in BF_MOZILLA_INC/nspr and BF_MOZILLA_LIB
# if this is not set.
#
# Be paranoid regarding library creation (do not update archives)
#BF_PARANOID = 'true'
# enable freetype2 support for text objects
BF_FREETYPE = LIBDIR + '/gcc/freetype'
@@ -141,8 +139,6 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a'
##
CC = 'gcc'
CXX = 'g++'
##ifeq ($CPU),alpha)
## CFLAGS += -pipe -fPIC -funsigned-char -fno-strict-aliasing -mieee
CCFLAGS = [ '-pipe', '-funsigned-char', '-fno-strict-aliasing' ]
@@ -150,24 +146,18 @@ CPPFLAGS = [ '-DXP_UNIX', '-DWIN32', '-DFREE_WINDOWS' ]
CXXFLAGS = ['-pipe', '-mwindows', '-funsigned-char', '-fno-strict-aliasing' ]
REL_CFLAGS = [ '-O2' ]
REL_CCFLAGS = [ '-O2' ]
##BF_DEPEND = 'true'
##
##AR = ar
##ARFLAGS = ruv
##ARFLAGSQUIET = ru
##
C_WARN = [ '-Wall' , '-Wno-char-subscripts', '-Wdeclaration-after-statement' ]
CC_WARN = [ '-Wall' ]
##FIX_STUBS_WARNINGS = -Wno-unused
LLIBS = ['-lshell32', '-lshfolder', '-ldxguid', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz'] #'-lutil', '-lc', '-lm', '-ldl', '-lpthread']
##LOPTS = --dynamic
##DYNLDFLAGS = -shared $(LDFLAGS)
LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++']
BF_DEBUG = 'false'
BF_DEBUG_FLAGS= '-g'
BF_PROFILE_FLAGS = ['-pg','-g']
BF_PROFILE = 'false'
BF_BUILDDIR = '..\\build\\win32-mingw'
BF_INSTALLDIR='..\\install\\win32-mingw'

View File

@@ -21,7 +21,7 @@ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
WITH_BF_OPENAL = 'true'
BF_OPENAL = LIBDIR + '/openal'
BF_OPENAL_INC = '${BF_OPENAL}/include ${BF_OPENAL}/include/AL '
BF_OPENAL_LIB = 'openal_static'
BF_OPENAL_LIB = 'dxguid openal_static'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_ICONV = 'true'
@@ -50,6 +50,8 @@ BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/IlmImf ${BF_OPENEX
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread '
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib_msvc'
WITH_BF_DDS = 'true'
WITH_BF_JPEG = 'true'
BF_JPEG = LIBDIR + '/jpeg'
BF_JPEG_INC = '${BF_JPEG}/include'
@@ -104,6 +106,8 @@ BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE'
WITH_BF_YAFRAY = 'true'
WITH_BF_BINRELOC = 'false'
#WITH_BF_NSPR = 'true'
#BF_NSPR = $(LIBDIR)/nspr
#BF_NSPR_INC = -I$(BF_NSPR)/include -I$(BF_NSPR)/include/nspr
@@ -145,15 +149,15 @@ CXX = 'cl.exe'
CCFLAGS = ['/nologo', '/Og', '/Ot', '/Ob1', '/Op', '/G6','/EHsc', '/J', '/W3', '/Gd', '/MT']
BF_DEBUG_FLAGS = ['/Zi', '/FR${TARGET.base}.sbr']
BF_DEBUG_FLAGS = ['/Zi', '/FR${TARGET}.sbr']
CPPFLAGS = ['-DWIN32','-D_CONSOLE', '-D_LIB', '-DUSE_OPENAL', '-DFTGL_LIBRARY_STATIC', '-D_CRT_SECURE_NO_DEPRECATE']
CPPFLAGS = ['-DWIN32','-D_CONSOLE', '-D_LIB', '-DFTGL_LIBRARY_STATIC', '-D_CRT_SECURE_NO_DEPRECATE']
REL_CFLAGS = ['-O2', '-DNDEBUG']
REL_CCFLAGS = ['-O2', '-DNDEBUG']
C_WARN = []
CC_WARN = []
LLIBS = 'ws2_32 dxguid vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid'
LLIBS = 'ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shell32 ole32 oleaut32 uuid'
PLATFORM_LINKFLAGS = '''
/SUBSYSTEM:CONSOLE

View File

@@ -1,6 +1,6 @@
$Id$
Note: The current official release of SCons is 0.96.1
Note: The current official release of SCons is 0.97
Blenders SCons build scripts
============================
@@ -29,7 +29,7 @@ $Id$
To build Blender with the SCons scripts you need a full Python
install, version 2.4 or later (http://www.python.org) and a SCons
installation, version v0.96.1 (http://www.scons.org).
installation, version v0.97 (http://www.scons.org).
Check from the page
http://www.blender.org/development/building-blender/getting-dependencies/
@@ -160,6 +160,17 @@ $Id$
for example, setting BF_QUICKDEBUG won't overwrite the contents of BF_DEBUG_LIBS.
Not installing
--------------
If you dont want to install the build result, you can use the following option either
on the commandline or in your user-config.py :
WITHOUT_BF_INSTALL='true'
by default, this is set to 'false', and so the build is installed
Supported toolset
-----------------

11
extern/CMakeLists.txt vendored
View File

@@ -29,12 +29,12 @@
IF(WITH_GAMEENGINE)
SUBDIRS(qhull solid)
IF(WITH_BULLET)
SUBDIRS(bullet2)
ENDIF(WITH_BULLET)
ENDIF(WITH_GAMEENGINE)
IF(WITH_BULLET)
SUBDIRS(bullet2)
ENDIF(WITH_BULLET)
IF(WITH_INTERNATIONAL)
SUBDIRS(bFTGL)
ENDIF(WITH_INTERNATIONAL)
@@ -43,3 +43,6 @@ IF(WITH_VERSE)
SUBDIRS(verse)
ENDIF(WITH_VERSE)
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SUBDIRS(binreloc)
ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")

4
extern/Makefile vendored
View File

@@ -56,6 +56,10 @@ ifneq ($(NAN_NO_KETSJI), true)
DIRS += bullet2
endif
ifeq ($(WITH_BINRELOC), true)
DIRS += binreloc
endif
TARGET =
ifneq ($(OS),irix)
TARGET=solid

11
extern/SConscript vendored
View File

@@ -5,11 +5,18 @@ Import('env')
if env['WITH_BF_GAMEENGINE']:
SConscript(['qhull/SConscript',
'solid/SConscript'])
if env['WITH_BF_BULLET']:
SConscript(['bullet2/src/SConscript'])
if env['WITH_BF_BULLET']:
SConscript(['bullet2/src/SConscript'])
if env['WITH_BF_INTERNATIONAL']:
SConscript(['bFTGL/SConscript'])
if env['WITH_BF_VERSE']:
SConscript(['verse/dist/SConstruct'])
if env['WITH_BF_FFMPEG'] and env['BF_FFMPEG_LIB'] == '':
SConscript(['ffmpeg/SConscript']);
if env['OURPLATFORM'] == 'linux2':
SConscript(['binreloc/SConscript']);

6
extern/bFTGL/include/FTGL.h vendored Executable file → Normal file
View File

@@ -42,7 +42,11 @@ typedef float FTGL_FLOAT;
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#if defined (__sun__) && !defined (__sparc__)
#include <mesa/glu.h>
#else
#include <GL/glu.h>
#endif
#endif
#endif

View File

@@ -5,8 +5,12 @@
#define CALLBACK
#endif
#ifdef __APPLE_CC__
typedef GLvoid (*GLUTesselatorFunction)(...);
#if defined(__APPLE_CC__)
#if __APPLE_CC__ >= 5465
typedef GLvoid (*GLUTesselatorFunction)();
#else
typedef GLvoid (*GLUTesselatorFunction)(...);
#endif
#elif defined( __mips ) || defined( __linux__ ) || defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __sun ) || defined (__CYGWIN__)
typedef GLvoid (*GLUTesselatorFunction)();
#elif defined ( WIN32)

View File

@@ -46,7 +46,8 @@ CCSRCS = FTBitmapGlyph.cpp FTCharmap.cpp FTContour.cpp FTExtrdGlyph.cpp \
include nan_compile.mk
CPPFLAGS += -I../include
CPPFLAGS += -I$(NAN_FREETYPE)/include -I$(NAN_FREETYPE)/include/freetype2
CPPFLAGS += -I$(NAN_FREETYPE)/include -I$(NAN_FREETYPE)/include/freetype2
CPPFLAGS += -I$(OPENGL_HEADERS)
install: all debug
@[ -d $(NAN_FTGL) ] || mkdir -p $(NAN_FTGL)

26
extern/binreloc/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,26 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# The Original Code is Copyright (C) 2008 by The Blender Foundation
# All rights reserved.
#
SET(INC ./include ${WINTAB_INC})
ADD_DEFINITIONS(-DWITH_BINRELOC)
FILE(GLOB SRC *.c)
BLENDERLIB(extern_binreloc "${SRC}" "${INC}")
#, libtype=['core','player'], priority = [25,15] )

37
extern/binreloc/Makefile vendored Normal file
View File

@@ -0,0 +1,37 @@
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# The Original Code is Copyright (C) 2008 by The Blender Foundation
# All rights reserved.
#
#
LIBNAME = binreloc
DIR = $(OCGDIR)/extern/$(LIBNAME)
include nan_definitions.mk
CPPFLAGS += -I./include
include nan_compile.mk
install: all debug
@[ -d $(DIR) ] || mkdir $(DIR)
@[ -d $(DIR)/include ] || mkdir $(DIR)/include
@../../intern/tools/cpifdiff.sh include/*.h $(DIR)/include/

13
extern/binreloc/SConscript vendored Normal file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/python
import sys
import os
Import('env')
defs = 'ENABLE_BINRELOC'
cflags = []
sources = ['binreloc.c']
incs = 'include'
env.BlenderLib ( 'extern_binreloc', sources, Split(incs), Split(defs), libtype=['intern','player'], priority=[36, 226], compileflags = cflags)

766
extern/binreloc/binreloc.c vendored Normal file
View File

@@ -0,0 +1,766 @@
/*
* BinReloc - a library for creating relocatable executables
* Written by: Hongli Lai <h.lai@chello.nl>
* http://autopackage.org/
*
* This source code is public domain. You can relicense this code
* under whatever license you want.
*
* See http://autopackage.org/docs/binreloc/ for
* more information and how to use this.
*/
#ifndef __BINRELOC_C__
#define __BINRELOC_C__
#ifdef ENABLE_BINRELOC
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif /* ENABLE_BINRELOC */
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include "binreloc.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** @internal
* Find the canonical filename of the executable. Returns the filename
* (which must be freed) or NULL on error. If the parameter 'error' is
* not NULL, the error code will be stored there, if an error occured.
*/
static char *
_br_find_exe (BrInitError *error)
{
#ifndef ENABLE_BINRELOC
if (error)
*error = BR_INIT_ERROR_DISABLED;
return NULL;
#else
char *path, *path2, *line, *result;
size_t buf_size;
ssize_t size;
struct stat stat_buf;
FILE *f;
/* Read from /proc/self/exe (symlink) */
if (sizeof (path) > SSIZE_MAX)
buf_size = SSIZE_MAX - 1;
else
buf_size = PATH_MAX - 1;
path = (char *) malloc (buf_size);
if (path == NULL) {
/* Cannot allocate memory. */
if (error)
*error = BR_INIT_ERROR_NOMEM;
return NULL;
}
path2 = (char *) malloc (buf_size);
if (path2 == NULL) {
/* Cannot allocate memory. */
if (error)
*error = BR_INIT_ERROR_NOMEM;
free (path);
return NULL;
}
strncpy (path2, "/proc/self/exe", buf_size - 1);
while (1) {
int i;
size = readlink (path2, path, buf_size - 1);
if (size == -1) {
/* Error. */
free (path2);
break;
}
/* readlink() success. */
path[size] = '\0';
/* Check whether the symlink's target is also a symlink.
* We want to get the final target. */
i = stat (path, &stat_buf);
if (i == -1) {
/* Error. */
free (path2);
break;
}
/* stat() success. */
if (!S_ISLNK (stat_buf.st_mode)) {
/* path is not a symlink. Done. */
free (path2);
return path;
}
/* path is a symlink. Continue loop and resolve this. */
strncpy (path, path2, buf_size - 1);
}
/* readlink() or stat() failed; this can happen when the program is
* running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
buf_size = PATH_MAX + 128;
line = (char *) realloc (path, buf_size);
if (line == NULL) {
/* Cannot allocate memory. */
free (path);
if (error)
*error = BR_INIT_ERROR_NOMEM;
return NULL;
}
f = fopen ("/proc/self/maps", "r");
if (f == NULL) {
free (line);
if (error)
*error = BR_INIT_ERROR_OPEN_MAPS;
return NULL;
}
/* The first entry should be the executable name. */
result = fgets (line, (int) buf_size, f);
if (result == NULL) {
fclose (f);
free (line);
if (error)
*error = BR_INIT_ERROR_READ_MAPS;
return NULL;
}
/* Get rid of newline character. */
buf_size = strlen (line);
if (buf_size <= 0) {
/* Huh? An empty string? */
fclose (f);
free (line);
if (error)
*error = BR_INIT_ERROR_INVALID_MAPS;
return NULL;
}
if (line[buf_size - 1] == 10)
line[buf_size - 1] = 0;
/* Extract the filename; it is always an absolute path. */
path = strchr (line, '/');
/* Sanity check. */
if (strstr (line, " r-xp ") == NULL || path == NULL) {
fclose (f);
free (line);
if (error)
*error = BR_INIT_ERROR_INVALID_MAPS;
return NULL;
}
path = strdup (path);
free (line);
fclose (f);
return path;
#endif /* ENABLE_BINRELOC */
}
/** @internal
* Find the canonical filename of the executable which owns symbol.
* Returns a filename which must be freed, or NULL on error.
*/
static char *
_br_find_exe_for_symbol (const void *symbol, BrInitError *error)
{
#ifndef ENABLE_BINRELOC
if (error)
*error = BR_INIT_ERROR_DISABLED;
return (char *) NULL;
#else
#define SIZE PATH_MAX + 100
FILE *f;
size_t address_string_len;
char *address_string, line[SIZE], *found;
if (symbol == NULL)
return (char *) NULL;
f = fopen ("/proc/self/maps", "r");
if (f == NULL)
return (char *) NULL;
address_string_len = 4;
address_string = (char *) malloc (address_string_len);
found = (char *) NULL;
while (!feof (f)) {
char *start_addr, *end_addr, *end_addr_end, *file;
void *start_addr_p, *end_addr_p;
size_t len;
if (fgets (line, SIZE, f) == NULL)
break;
/* Sanity check. */
if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
continue;
/* Parse line. */
start_addr = line;
end_addr = strchr (line, '-');
file = strchr (line, '/');
/* More sanity check. */
if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
continue;
end_addr[0] = '\0';
end_addr++;
end_addr_end = strchr (end_addr, ' ');
if (end_addr_end == NULL)
continue;
end_addr_end[0] = '\0';
len = strlen (file);
if (len == 0)
continue;
if (file[len - 1] == '\n')
file[len - 1] = '\0';
/* Get rid of "(deleted)" from the filename. */
len = strlen (file);
if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
file[len - 10] = '\0';
/* I don't know whether this can happen but better safe than sorry. */
len = strlen (start_addr);
if (len != strlen (end_addr))
continue;
/* Transform the addresses into a string in the form of 0xdeadbeef,
* then transform that into a pointer. */
if (address_string_len < len + 3) {
address_string_len = len + 3;
address_string = (char *) realloc (address_string, address_string_len);
}
memcpy (address_string, "0x", 2);
memcpy (address_string + 2, start_addr, len);
address_string[2 + len] = '\0';
sscanf (address_string, "%p", &start_addr_p);
memcpy (address_string, "0x", 2);
memcpy (address_string + 2, end_addr, len);
address_string[2 + len] = '\0';
sscanf (address_string, "%p", &end_addr_p);
if (symbol >= start_addr_p && symbol < end_addr_p) {
found = file;
break;
}
}
free (address_string);
fclose (f);
if (found == NULL)
return (char *) NULL;
else
return strdup (found);
#endif /* ENABLE_BINRELOC */
}
#ifndef BINRELOC_RUNNING_DOXYGEN
#undef NULL
#define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
#endif
static char *exe = (char *) NULL;
/** Initialize the BinReloc library (for applications).
*
* This function must be called before using any other BinReloc functions.
* It attempts to locate the application's canonical filename.
*
* @note If you want to use BinReloc for a library, then you should call
* br_init_lib() instead.
*
* @param error If BinReloc failed to initialize, then the error code will
* be stored in this variable. Set to NULL if you want to
* ignore this. See #BrInitError for a list of error codes.
*
* @returns 1 on success, 0 if BinReloc failed to initialize.
*/
int
br_init (BrInitError *error)
{
exe = _br_find_exe (error);
return exe != NULL;
}
/** Initialize the BinReloc library (for libraries).
*
* This function must be called before using any other BinReloc functions.
* It attempts to locate the calling library's canonical filename.
*
* @note The BinReloc source code MUST be included in your library, or this
* function won't work correctly.
*
* @param error If BinReloc failed to initialize, then the error code will
* be stored in this variable. Set to NULL if you want to
* ignore this. See #BrInitError for a list of error codes.
*
* @returns 1 on success, 0 if a filename cannot be found.
*/
int
br_init_lib (BrInitError *error)
{
exe = _br_find_exe_for_symbol ((const void *) "", error);
return exe != NULL;
}
/** Find the canonical filename of the current application.
*
* @param default_exe A default filename which will be used as fallback.
* @returns A string containing the application's canonical filename,
* which must be freed when no longer necessary. If BinReloc is
* not initialized, or if br_init() failed, then a copy of
* default_exe will be returned. If default_exe is NULL, then
* NULL will be returned.
*/
char *
br_find_exe (const char *default_exe)
{
if (exe == (char *) NULL) {
/* BinReloc is not initialized. */
if (default_exe != (const char *) NULL)
return strdup (default_exe);
else
return (char *) NULL;
}
return strdup (exe);
}
/** Locate the directory in which the current application is installed.
*
* The prefix is generated by the following pseudo-code evaluation:
* \code
* dirname(exename)
* \endcode
*
* @param default_dir A default directory which will used as fallback.
* @return A string containing the directory, which must be freed when no
* longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_dir
* will be returned. If default_dir is NULL, then NULL will be
* returned.
*/
char *
br_find_exe_dir (const char *default_dir)
{
if (exe == NULL) {
/* BinReloc not initialized. */
if (default_dir != NULL)
return strdup (default_dir);
else
return NULL;
}
return br_dirname (exe);
}
/** Locate the prefix in which the current application is installed.
*
* The prefix is generated by the following pseudo-code evaluation:
* \code
* dirname(dirname(exename))
* \endcode
*
* @param default_prefix A default prefix which will used as fallback.
* @return A string containing the prefix, which must be freed when no
* longer necessary. If BinReloc is not initialized, or if
* the initialization function failed, then a copy of default_prefix
* will be returned. If default_prefix is NULL, then NULL will be returned.
*/
char *
br_find_prefix (const char *default_prefix)
{
char *dir1, *dir2;
if (exe == (char *) NULL) {
/* BinReloc not initialized. */
if (default_prefix != (const char *) NULL)
return strdup (default_prefix);
else
return (char *) NULL;
}
dir1 = br_dirname (exe);
dir2 = br_dirname (dir1);
free (dir1);
return dir2;
}
/** Locate the application's binary folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/bin"
* \endcode
*
* @param default_bin_dir A default path which will used as fallback.
* @return A string containing the bin folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if
* the initialization function failed, then a copy of default_bin_dir will
* be returned. If default_bin_dir is NULL, then NULL will be returned.
*/
char *
br_find_bin_dir (const char *default_bin_dir)
{
char *prefix, *dir;
prefix = br_find_prefix ((const char *) NULL);
if (prefix == (char *) NULL) {
/* BinReloc not initialized. */
if (default_bin_dir != (const char *) NULL)
return strdup (default_bin_dir);
else
return (char *) NULL;
}
dir = br_build_path (prefix, "bin");
free (prefix);
return dir;
}
/** Locate the application's superuser binary folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/sbin"
* \endcode
*
* @param default_sbin_dir A default path which will used as fallback.
* @return A string containing the sbin folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_sbin_dir will
* be returned. If default_bin_dir is NULL, then NULL will be returned.
*/
char *
br_find_sbin_dir (const char *default_sbin_dir)
{
char *prefix, *dir;
prefix = br_find_prefix ((const char *) NULL);
if (prefix == (char *) NULL) {
/* BinReloc not initialized. */
if (default_sbin_dir != (const char *) NULL)
return strdup (default_sbin_dir);
else
return (char *) NULL;
}
dir = br_build_path (prefix, "sbin");
free (prefix);
return dir;
}
/** Locate the application's data folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/share"
* \endcode
*
* @param default_data_dir A default path which will used as fallback.
* @return A string containing the data folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_data_dir
* will be returned. If default_data_dir is NULL, then NULL will be
* returned.
*/
char *
br_find_data_dir (const char *default_data_dir)
{
char *prefix, *dir;
prefix = br_find_prefix ((const char *) NULL);
if (prefix == (char *) NULL) {
/* BinReloc not initialized. */
if (default_data_dir != (const char *) NULL)
return strdup (default_data_dir);
else
return (char *) NULL;
}
dir = br_build_path (prefix, "share");
free (prefix);
return dir;
}
/** Locate the application's localization folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/share/locale"
* \endcode
*
* @param default_locale_dir A default path which will used as fallback.
* @return A string containing the localization folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_locale_dir will be returned.
* If default_locale_dir is NULL, then NULL will be returned.
*/
char *
br_find_locale_dir (const char *default_locale_dir)
{
char *data_dir, *dir;
data_dir = br_find_data_dir ((const char *) NULL);
if (data_dir == (char *) NULL) {
/* BinReloc not initialized. */
if (default_locale_dir != (const char *) NULL)
return strdup (default_locale_dir);
else
return (char *) NULL;
}
dir = br_build_path (data_dir, "locale");
free (data_dir);
return dir;
}
/** Locate the application's library folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/lib"
* \endcode
*
* @param default_lib_dir A default path which will used as fallback.
* @return A string containing the library folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the initialization
* function failed, then a copy of default_lib_dir will be returned.
* If default_lib_dir is NULL, then NULL will be returned.
*/
char *
br_find_lib_dir (const char *default_lib_dir)
{
char *prefix, *dir;
prefix = br_find_prefix ((const char *) NULL);
if (prefix == (char *) NULL) {
/* BinReloc not initialized. */
if (default_lib_dir != (const char *) NULL)
return strdup (default_lib_dir);
else
return (char *) NULL;
}
dir = br_build_path (prefix, "lib");
free (prefix);
return dir;
}
/** Locate the application's libexec folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/libexec"
* \endcode
*
* @param default_libexec_dir A default path which will used as fallback.
* @return A string containing the libexec folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the initialization
* function failed, then a copy of default_libexec_dir will be returned.
* If default_libexec_dir is NULL, then NULL will be returned.
*/
char *
br_find_libexec_dir (const char *default_libexec_dir)
{
char *prefix, *dir;
prefix = br_find_prefix ((const char *) NULL);
if (prefix == (char *) NULL) {
/* BinReloc not initialized. */
if (default_libexec_dir != (const char *) NULL)
return strdup (default_libexec_dir);
else
return (char *) NULL;
}
dir = br_build_path (prefix, "libexec");
free (prefix);
return dir;
}
/** Locate the application's configuration files folder.
*
* The path is generated by the following pseudo-code evaluation:
* \code
* prefix + "/etc"
* \endcode
*
* @param default_etc_dir A default path which will used as fallback.
* @return A string containing the etc folder's path, which must be freed when
* no longer necessary. If BinReloc is not initialized, or if the initialization
* function failed, then a copy of default_etc_dir will be returned.
* If default_etc_dir is NULL, then NULL will be returned.
*/
char *
br_find_etc_dir (const char *default_etc_dir)
{
char *prefix, *dir;
prefix = br_find_prefix ((const char *) NULL);
if (prefix == (char *) NULL) {
/* BinReloc not initialized. */
if (default_etc_dir != (const char *) NULL)
return strdup (default_etc_dir);
else
return (char *) NULL;
}
dir = br_build_path (prefix, "etc");
free (prefix);
return dir;
}
/***********************
* Utility functions
***********************/
/** Concatenate str1 and str2 to a newly allocated string.
*
* @param str1 A string.
* @param str2 Another string.
* @returns A newly-allocated string. This string should be freed when no longer needed.
*/
char *
br_strcat (const char *str1, const char *str2)
{
char *result;
size_t len1, len2;
if (str1 == NULL)
str1 = "";
if (str2 == NULL)
str2 = "";
len1 = strlen (str1);
len2 = strlen (str2);
result = (char *) malloc (len1 + len2 + 1);
memcpy (result, str1, len1);
memcpy (result + len1, str2, len2);
result[len1 + len2] = '\0';
return result;
}
char *
br_build_path (const char *dir, const char *file)
{
char *dir2, *result;
size_t len;
int must_free = 0;
len = strlen (dir);
if (len > 0 && dir[len - 1] != '/') {
dir2 = br_strcat (dir, "/");
must_free = 1;
} else
dir2 = (char *) dir;
result = br_strcat (dir2, file);
if (must_free)
free (dir2);
return result;
}
/* Emulates glibc's strndup() */
static char *
br_strndup (const char *str, size_t size)
{
char *result = (char *) NULL;
size_t len;
if (str == (const char *) NULL)
return (char *) NULL;
len = strlen (str);
if (len == 0)
return strdup ("");
if (size > len)
size = len;
result = (char *) malloc (len + 1);
memcpy (result, str, size);
result[size] = '\0';
return result;
}
/** Extracts the directory component of a path.
*
* Similar to g_dirname() or the dirname commandline application.
*
* Example:
* \code
* br_dirname ("/usr/local/foobar"); --> Returns: "/usr/local"
* \endcode
*
* @param path A path.
* @returns A directory name. This string should be freed when no longer needed.
*/
char *
br_dirname (const char *path)
{
char *end, *result;
if (path == (const char *) NULL)
return (char *) NULL;
end = strrchr (path, '/');
if (end == (const char *) NULL)
return strdup (".");
while (end > path && *end == '/')
end--;
result = br_strndup (path, end - path + 1);
if (result[0] == 0) {
free (result);
return strdup ("/");
} else
return result;
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __BINRELOC_C__ */

80
extern/binreloc/include/binreloc.h vendored Normal file
View File

@@ -0,0 +1,80 @@
/*
* BinReloc - a library for creating relocatable executables
* Written by: Hongli Lai <h.lai@chello.nl>
* http://autopackage.org/
*
* This source code is public domain. You can relicense this code
* under whatever license you want.
*
* See http://autopackage.org/docs/binreloc/ for
* more information and how to use this.
*/
#ifndef __BINRELOC_H__
#define __BINRELOC_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** These error codes can be returned by br_init(), br_init_lib(), gbr_init() or gbr_init_lib(). */
typedef enum {
/** Cannot allocate memory. */
BR_INIT_ERROR_NOMEM,
/** Unable to open /proc/self/maps; see errno for details. */
BR_INIT_ERROR_OPEN_MAPS,
/** Unable to read from /proc/self/maps; see errno for details. */
BR_INIT_ERROR_READ_MAPS,
/** The file format of /proc/self/maps is invalid; kernel bug? */
BR_INIT_ERROR_INVALID_MAPS,
/** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
BR_INIT_ERROR_DISABLED
} BrInitError;
#ifndef BINRELOC_RUNNING_DOXYGEN
/* Mangle symbol names to avoid symbol collisions with other ELF objects. */
#define br_init zLhm65070058860608_br_init
#define br_init_lib zLhm65070058860608_br_init_lib
#define br_find_exe zLhm65070058860608_br_find_exe
#define br_find_exe_dir zLhm65070058860608_br_find_exe_dir
#define br_find_prefix zLhm65070058860608_br_find_prefix
#define br_find_bin_dir zLhm65070058860608_br_find_bin_dir
#define br_find_sbin_dir zLhm65070058860608_br_find_sbin_dir
#define br_find_data_dir zLhm65070058860608_br_find_data_dir
#define br_find_locale_dir zLhm65070058860608_br_find_locale_dir
#define br_find_lib_dir zLhm65070058860608_br_find_lib_dir
#define br_find_libexec_dir zLhm65070058860608_br_find_libexec_dir
#define br_find_etc_dir zLhm65070058860608_br_find_etc_dir
#define br_strcat zLhm65070058860608_br_strcat
#define br_build_path zLhm65070058860608_br_build_path
#define br_dirname zLhm65070058860608_br_dirname
#endif
int br_init (BrInitError *error);
int br_init_lib (BrInitError *error);
char *br_find_exe (const char *default_exe);
char *br_find_exe_dir (const char *default_dir);
char *br_find_prefix (const char *default_prefix);
char *br_find_bin_dir (const char *default_bin_dir);
char *br_find_sbin_dir (const char *default_sbin_dir);
char *br_find_data_dir (const char *default_data_dir);
char *br_find_locale_dir (const char *default_locale_dir);
char *br_find_lib_dir (const char *default_lib_dir);
char *br_find_libexec_dir (const char *default_libexec_dir);
char *br_find_etc_dir (const char *default_etc_dir);
/* Utility functions */
char *br_strcat (const char *str1, const char *str2);
char *br_build_path (const char *dir, const char *file);
char *br_dirname (const char *path);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __BINRELOC_H__ */

View File

@@ -340,12 +340,21 @@ ECHO Done
<File
RelativePath="..\..\src\btBulletDynamicsCommon.h">
</File>
<File
RelativePath="..\..\src\Bullet-C-Api.h">
</File>
<Filter
Name="BulletDynamics"
Filter="">
<Filter
Name="ConstraintSolver"
Filter="">
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btConeTwistConstraint.cpp">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btConeTwistConstraint.h">
</File>
<File
RelativePath="..\..\src\BulletDynamics\ConstraintSolver\btConstraintSolver.h">
</File>
@@ -422,6 +431,9 @@ ECHO Done
<File
RelativePath="..\..\src\BulletDynamics\Dynamics\btSimpleDynamicsWorld.h">
</File>
<File
RelativePath="..\..\src\BulletDynamics\Dynamics\Bullet-C-API.cpp">
</File>
</Filter>
<Filter
Name="Vehicle"
@@ -680,6 +692,12 @@ ECHO Done
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btBvhTriangleMeshShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btCapsuleShape.cpp">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btCapsuleShape.h">
</File>
<File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btCollisionMargin.h">
</File>

37
extern/bullet2/src/Bullet-C-Api.h vendored Normal file
View File

@@ -0,0 +1,37 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
Work in progress, functionality will be added on demand.
If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h"
*/
#ifndef BULLET_C_API_H
#define BULLET_C_API_H
#ifdef __cplusplus
extern "C" {
#endif
double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
#ifdef __cplusplus
}
#endif
#endif //BULLET_C_API_H

View File

@@ -21,9 +21,34 @@
#include <assert.h>
#ifdef DEBUG_BROADPHASE
#include <stdio.h>
void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality)
{
int numEdges = m_pHandles[0].m_maxEdges[axis];
printf("SAP Axis %d, numEdges=%d\n",axis,numEdges);
int i;
for (i=0;i<numEdges+1;i++)
{
Edge* pEdge = m_pEdges[axis] + i;
Handle* pHandlePrev = getHandle(pEdge->m_handle);
int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis];
char beginOrEnd;
beginOrEnd=pEdge->IsMax()?'E':'B';
printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex);
}
if (checkCardinality)
assert(numEdges == m_numHandles*2+1);
}
#endif //DEBUG_BROADPHASE
btBroadphaseProxy* btAxisSweep3::createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask)
{
unsigned short handleId = addHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask);
(void)shapeType;
BP_FP_INT_TYPE handleId = addHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask);
Handle* handle = getHandle(handleId);
@@ -40,6 +65,7 @@ void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,con
{
Handle* handle = static_cast<Handle*>(proxy);
updateHandle(handle->m_handleId,aabbMin,aabbMax);
}
@@ -50,10 +76,11 @@ void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,con
btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles)
:btOverlappingPairCache()
{
m_invalidPair = 0;
//assert(bounds.HasVolume());
// 1 handle is reserved as sentinel
assert(maxHandles > 1 && maxHandles < 32767);
btAssert(maxHandles > 1 && maxHandles < BP_MAX_HANDLES);
// init bounds
m_worldAabbMin = worldAabbMin;
@@ -61,7 +88,9 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
m_quantize = btVector3(65535.0f,65535.0f,65535.0f) / aabbSize;
BP_FP_INT_TYPE maxInt = BP_HANDLE_SENTINEL;
m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize;
// allocate handles buffer and put all handles on free list
m_pHandles = new Handle[maxHandles];
@@ -71,7 +100,7 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
// handle 0 is reserved as the null index, and is also used as the sentinel
m_firstFreeHandle = 1;
{
for (int i = m_firstFreeHandle; i < maxHandles; i++)
for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
m_pHandles[i].SetNextFree(i + 1);
m_pHandles[maxHandles - 1].SetNextFree(0);
}
@@ -94,9 +123,14 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
m_pEdges[axis][0].m_pos = 0;
m_pEdges[axis][0].m_handle = 0;
m_pEdges[axis][1].m_pos = 0xffff;
m_pEdges[axis][1].m_pos = BP_HANDLE_SENTINEL;
m_pEdges[axis][1].m_handle = 0;
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
}
btAxisSweep3::~btAxisSweep3()
@@ -107,43 +141,36 @@ btAxisSweep3::~btAxisSweep3()
delete[] m_pHandles;
}
void btAxisSweep3::quantize(unsigned short* out, const btPoint3& point, int isMax) const
void btAxisSweep3::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
{
btPoint3 clampedPoint(point);
/*
if (isMax)
clampedPoint += btVector3(10,10,10);
else
{
clampedPoint -= btVector3(10,10,10);
}
*/
clampedPoint.setMax(m_worldAabbMin);
clampedPoint.setMin(m_worldAabbMax);
btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
out[0] = (unsigned short)(((int)v.getX() & 0xfffc) | isMax);
out[1] = (unsigned short)(((int)v.getY() & 0xfffc) | isMax);
out[2] = (unsigned short)(((int)v.getZ() & 0xfffc) | isMax);
out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & BP_HANDLE_MASK) | isMax);
out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & BP_HANDLE_MASK) | isMax);
out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & BP_HANDLE_MASK) | isMax);
}
unsigned short btAxisSweep3::allocHandle()
BP_FP_INT_TYPE btAxisSweep3::allocHandle()
{
assert(m_firstFreeHandle);
unsigned short handle = m_firstFreeHandle;
BP_FP_INT_TYPE handle = m_firstFreeHandle;
m_firstFreeHandle = getHandle(handle)->GetNextFree();
m_numHandles++;
return handle;
}
void btAxisSweep3::freeHandle(unsigned short handle)
void btAxisSweep3::freeHandle(BP_FP_INT_TYPE handle)
{
assert(handle > 0 && handle < m_maxHandles);
@@ -155,15 +182,15 @@ void btAxisSweep3::freeHandle(unsigned short handle)
unsigned short btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask)
BP_FP_INT_TYPE btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask)
{
// quantize the bounds
unsigned short min[3], max[3];
BP_FP_INT_TYPE min[3], max[3];
quantize(min, aabbMin, 0);
quantize(max, aabbMax, 1);
// allocate a handle
unsigned short handle = allocHandle();
BP_FP_INT_TYPE handle = allocHandle();
assert(handle!= 0xcdcd);
Handle* pHandle = getHandle(handle);
@@ -175,11 +202,13 @@ unsigned short btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& a
pHandle->m_collisionFilterMask = collisionFilterMask;
// compute current limit of edge arrays
int limit = m_numHandles * 2;
BP_FP_INT_TYPE limit = m_numHandles * 2;
// insert new edges just inside the max boundary edge
for (int axis = 0; axis < 3; axis++)
for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
{
m_pHandles[0].m_maxEdges[axis] += 2;
m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
@@ -202,14 +231,14 @@ unsigned short btAxisSweep3::addHandle(const btPoint3& aabbMin,const btPoint3& a
sortMinDown(2, pHandle->m_minEdges[2], true);
sortMaxDown(2, pHandle->m_maxEdges[2], true);
//PrintAxis(1);
return handle;
}
void btAxisSweep3::removeHandle(unsigned short handle)
void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle)
{
Handle* pHandle = getHandle(handle);
//explicitly remove the pairs containing the proxy
@@ -220,42 +249,145 @@ void btAxisSweep3::removeHandle(unsigned short handle)
// compute current limit of edge arrays
int limit = m_numHandles * 2;
int axis;
for (axis = 0;axis<3;axis++)
{
Edge* pEdges = m_pEdges[axis];
int maxEdge= pHandle->m_maxEdges[axis];
pEdges[maxEdge].m_pos = 0xffff;
int minEdge = pHandle->m_minEdges[axis];
pEdges[minEdge].m_pos = 0xffff;
m_pHandles[0].m_maxEdges[axis] -= 2;
}
// remove the edges by sorting them up to the end of the list
for ( axis = 0; axis < 3; axis++)
{
Edge* pEdges = m_pEdges[axis];
int max = pHandle->m_maxEdges[axis];
pEdges[max].m_pos = 0xffff;
BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
pEdges[max].m_pos = BP_HANDLE_SENTINEL;
sortMaxUp(axis,max,false);
int i = pHandle->m_minEdges[axis];
pEdges[i].m_pos = 0xffff;
BP_FP_INT_TYPE i = pHandle->m_minEdges[axis];
pEdges[i].m_pos = BP_HANDLE_SENTINEL;
sortMinUp(axis,i,false);
pEdges[limit-1].m_handle = 0;
pEdges[limit-1].m_pos = 0xffff;
pEdges[limit-1].m_pos = BP_HANDLE_SENTINEL;
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis,false);
#endif //DEBUG_BROADPHASE
}
// free the handle
freeHandle(handle);
}
extern int gOverlappingPairs;
void btAxisSweep3::refreshOverlappingPairs()
{
}
void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback)
{
//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
m_overlappingPairArray.heapSort(btBroadphasePairSortPredicate());
//remove the 'invalid' ones
#ifdef USE_POPBACK_REMOVAL
while (m_invalidPair>0)
{
m_invalidPair--;
m_overlappingPairArray.pop_back();
}
#else
m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair);
m_invalidPair = 0;
#endif
int i;
btBroadphasePair previousPair;
previousPair.m_pProxy0 = 0;
previousPair.m_pProxy1 = 0;
previousPair.m_algorithm = 0;
for (i=0;i<m_overlappingPairArray.size();i++)
{
btBroadphasePair& pair = m_overlappingPairArray[i];
bool isDuplicate = (pair == previousPair);
previousPair = pair;
bool needsRemoval = false;
if (!isDuplicate)
{
bool hasOverlap = testOverlap(pair.m_pProxy0,pair.m_pProxy1);
if (hasOverlap)
{
needsRemoval = callback->processOverlap(pair);
} else
{
needsRemoval = true;
}
} else
{
//remove duplicate
needsRemoval = true;
//should have no algorithm
btAssert(!pair.m_algorithm);
}
if (needsRemoval)
{
cleanOverlappingPair(pair);
// m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
// m_overlappingPairArray.pop_back();
pair.m_pProxy0 = 0;
pair.m_pProxy1 = 0;
m_invalidPair++;
gOverlappingPairs--;
}
}
}
bool btAxisSweep3::testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
const Handle* pHandleA = static_cast<Handle*>(proxy0);
const Handle* pHandleB = static_cast<Handle*>(proxy1);
//optimization 1: check the array index (memory address), instead of the m_pos
for (int axis = 0; axis < 3; axis++)
{
if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
{
return false;
}
}
return true;
}
bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB)
{
//optimization 1: check the array index (memory address), instead of the m_pos
@@ -272,7 +404,7 @@ bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Hand
}
}
//optimization 2: only 2 axis need to be tested
//optimization 2: only 2 axis need to be tested (conflicts with 'delayed removal' optimization)
/*for (int axis = 0; axis < 3; axis++)
{
@@ -287,7 +419,7 @@ bool btAxisSweep3::testOverlap(int ignoreAxis,const Handle* pHandleA, const Hand
return true;
}
void btAxisSweep3::updateHandle(unsigned short handle, const btPoint3& aabbMin,const btPoint3& aabbMax)
void btAxisSweep3::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax)
{
// assert(bounds.IsFinite());
//assert(bounds.HasVolume());
@@ -295,15 +427,15 @@ void btAxisSweep3::updateHandle(unsigned short handle, const btPoint3& aabbMin,c
Handle* pHandle = getHandle(handle);
// quantize the new bounds
unsigned short min[3], max[3];
BP_FP_INT_TYPE min[3], max[3];
quantize(min, aabbMin, 0);
quantize(max, aabbMax, 1);
// update changed edges
for (int axis = 0; axis < 3; axis++)
{
unsigned short emin = pHandle->m_minEdges[axis];
unsigned short emax = pHandle->m_maxEdges[axis];
BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
@@ -324,14 +456,22 @@ void btAxisSweep3::updateHandle(unsigned short handle, const btPoint3& aabbMin,c
if (dmax < 0)
sortMaxDown(axis, emax);
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
//PrintAxis(1);
}
// sorting a min edge downwards can only ever *add* overlaps
void btAxisSweep3::sortMinDown(int axis, unsigned short edge, bool updateOverlaps)
void btAxisSweep3::sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pPrev = pEdge - 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
@@ -368,16 +508,21 @@ void btAxisSweep3::sortMinDown(int axis, unsigned short edge, bool updateOverlap
pEdge--;
pPrev--;
}
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
// sorting a min edge upwards can only ever *remove* overlaps
void btAxisSweep3::sortMinUp(int axis, unsigned short edge, bool updateOverlaps)
void btAxisSweep3::sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pNext = pEdge + 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pEdge->m_pos > pNext->m_pos)
while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
{
Handle* pHandleNext = getHandle(pNext->m_handle);
@@ -386,10 +531,12 @@ void btAxisSweep3::sortMinUp(int axis, unsigned short edge, bool updateOverlaps)
// if next edge is maximum remove any overlap between the two handles
if (updateOverlaps)
{
/*
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pNext->m_handle);
btBroadphasePair tmpPair(*handle0,*handle1);
removeOverlappingPair(tmpPair);
*/
}
@@ -410,11 +557,14 @@ void btAxisSweep3::sortMinUp(int axis, unsigned short edge, bool updateOverlaps)
pEdge++;
pNext++;
}
}
// sorting a max edge downwards can only ever *remove* overlaps
void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlaps)
void btAxisSweep3::sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pPrev = pEdge - 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
@@ -428,6 +578,8 @@ void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlap
// if previous edge was a minimum remove any overlap between the two handles
if (updateOverlaps)
{
//this is done during the overlappingpairarray iteration/narrowphase collision
/*
Handle* handle0 = getHandle(pEdge->m_handle);
Handle* handle1 = getHandle(pPrev->m_handle);
btBroadphasePair* pair = findPair(handle0,handle1);
@@ -437,6 +589,8 @@ void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlap
{
removeOverlappingPair(*pair);
}
*/
}
// update edge reference in other handle
@@ -456,16 +610,22 @@ void btAxisSweep3::sortMaxDown(int axis, unsigned short edge, bool updateOverlap
pEdge--;
pPrev--;
}
#ifdef DEBUG_BROADPHASE
debugPrintAxis(axis);
#endif //DEBUG_BROADPHASE
}
// sorting a max edge upwards can only ever *add* overlaps
void btAxisSweep3::sortMaxUp(int axis, unsigned short edge, bool updateOverlaps)
void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps)
{
Edge* pEdge = m_pEdges[axis] + edge;
Edge* pNext = pEdge + 1;
Handle* pHandleEdge = getHandle(pEdge->m_handle);
while (pEdge->m_pos > pNext->m_pos)
while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
{
Handle* pHandleNext = getHandle(pNext->m_handle);
@@ -496,4 +656,5 @@ void btAxisSweep3::sortMaxUp(int axis, unsigned short edge, bool updateOverlaps)
pEdge++;
pNext++;
}
}

View File

@@ -19,11 +19,29 @@
#ifndef AXIS_SWEEP_3_H
#define AXIS_SWEEP_3_H
#include "LinearMath/btPoint3.h"
#include "LinearMath/btVector3.h"
#include "../../LinearMath/btPoint3.h"
#include "../../LinearMath/btVector3.h"
#include "btOverlappingPairCache.h"
#include "btBroadphaseProxy.h"
//Enable BP_USE_FIXEDPOINT_INT_32 if you need more then 32767 objects
//#define BP_USE_FIXEDPOINT_INT_32 1
#ifdef BP_USE_FIXEDPOINT_INT_32
#define BP_FP_INT_TYPE unsigned int
#define BP_MAX_HANDLES 1500000 //arbitrary maximum number of handles
#define BP_HANDLE_SENTINEL 0x7fffffff
#define BP_HANDLE_MASK 0xfffffffe
#else
#define BP_FP_INT_TYPE unsigned short int
#define BP_MAX_HANDLES 32767
#define BP_HANDLE_SENTINEL 0xffff
#define BP_HANDLE_MASK 0xfffe
#endif //BP_USE_FIXEDPOINT_INT_32
//#define DEBUG_BROADPHASE 1
/// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using integer coordinates instead of floats.
/// The testOverlap check is optimized to check the array index, rather then the actual AABB coordinates/pos
@@ -36,10 +54,10 @@ public:
class Edge
{
public:
unsigned short m_pos; // low bit is min/max
unsigned short m_handle;
BP_FP_INT_TYPE m_pos; // low bit is min/max
BP_FP_INT_TYPE m_handle;
unsigned short IsMax() const {return m_pos & 1;}
BP_FP_INT_TYPE IsMax() const {return m_pos & 1;}
};
public:
@@ -48,14 +66,14 @@ public:
public:
// indexes into the edge arrays
unsigned short m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
unsigned short m_handleId;
unsigned short m_pad;
BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
BP_FP_INT_TYPE m_handleId;
BP_FP_INT_TYPE m_pad;
//void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
inline void SetNextFree(unsigned short next) {m_minEdges[0] = next;}
inline unsigned short GetNextFree() const {return m_minEdges[0];}
inline void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
inline BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];}
}; // 24 bytes + 24 for Edge structures = 44 bytes total per entry
@@ -65,51 +83,56 @@ private:
btVector3 m_quantize; // scaling factor for quantization
int m_numHandles; // number of active handles
BP_FP_INT_TYPE m_numHandles; // number of active handles
int m_maxHandles; // max number of handles
Handle* m_pHandles; // handles pool
unsigned short m_firstFreeHandle; // free handles list
BP_FP_INT_TYPE m_firstFreeHandle; // free handles list
Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
int m_invalidPair;
// allocation/deallocation
unsigned short allocHandle();
void freeHandle(unsigned short handle);
BP_FP_INT_TYPE allocHandle();
void freeHandle(BP_FP_INT_TYPE handle);
bool testOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB);
//Overlap* AddOverlap(unsigned short handleA, unsigned short handleB);
//void RemoveOverlap(unsigned short handleA, unsigned short handleB);
#ifdef DEBUG_BROADPHASE
void debugPrintAxis(int axis,bool checkCardinality=true);
#endif //DEBUG_BROADPHASE
void quantize(unsigned short* out, const btPoint3& point, int isMax) const;
//Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
//void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
void sortMinDown(int axis, unsigned short edge, bool updateOverlaps = true);
void sortMinUp(int axis, unsigned short edge, bool updateOverlaps = true);
void sortMaxDown(int axis, unsigned short edge, bool updateOverlaps = true);
void sortMaxUp(int axis, unsigned short edge, bool updateOverlaps = true);
void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;
void sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
void sortMinUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
void sortMaxDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
void sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps = true);
public:
btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles = 16384);
virtual ~btAxisSweep3();
virtual void refreshOverlappingPairs()
{
//this is replace by sweep and prune
}
virtual void refreshOverlappingPairs();
unsigned short addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask);
void removeHandle(unsigned short handle);
void updateHandle(unsigned short handle, const btPoint3& aabbMin,const btPoint3& aabbMax);
inline Handle* getHandle(unsigned short index) const {return m_pHandles + index;}
BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask);
void removeHandle(BP_FP_INT_TYPE handle);
void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax);
inline Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
void processAllOverlappingPairs(btOverlapCallback* callback);
//Broadphase Interface
virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
virtual void destroyProxy(btBroadphaseProxy* proxy);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax);
bool testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
};
#endif //AXIS_SWEEP_3_H
#endif

View File

@@ -21,7 +21,7 @@ subject to the following restrictions:
struct btDispatcherInfo;
class btDispatcher;
struct btBroadphaseProxy;
#include "LinearMath/btVector3.h"
#include "../../LinearMath/btVector3.h"
///BroadphaseInterface for aabb-overlapping object pairs
class btBroadphaseInterface

View File

@@ -16,6 +16,7 @@ subject to the following restrictions:
#ifndef BROADPHASE_PROXY_H
#define BROADPHASE_PROXY_H
#include "../../LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
/// btDispatcher uses these types
@@ -33,6 +34,7 @@ enum BroadphaseNativeTypes
IMPLICIT_CONVEX_SHAPES_START_HERE,
SPHERE_SHAPE_PROXYTYPE,
MULTI_SPHERE_SHAPE_PROXYTYPE,
CAPSULE_SHAPE_PROXYTYPE,
CONE_SHAPE_PROXYTYPE,
CONVEX_SHAPE_PROXYTYPE,
CYLINDER_SHAPE_PROXYTYPE,
@@ -71,7 +73,7 @@ struct btBroadphaseProxy
KinematicFilter = 4,
DebrisFilter = 8,
SensorTrigger = 16,
AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger,
AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
};
//Usually the client btCollisionObject or Rigidbody class
@@ -113,7 +115,8 @@ struct btBroadphaseProxy
return (proxyType == STATIC_PLANE_PROXYTYPE);
}
};
}
;
class btCollisionAlgorithm;
@@ -128,14 +131,16 @@ struct btBroadphasePair
:
m_pProxy0(0),
m_pProxy1(0),
m_algorithm(0)
m_algorithm(0),
m_userInfo(0)
{
}
btBroadphasePair(const btBroadphasePair& other)
: m_pProxy0(other.m_pProxy0),
m_pProxy1(other.m_pProxy1),
m_algorithm(other.m_algorithm)
m_algorithm(other.m_algorithm),
m_userInfo(other.m_userInfo)
{
}
btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1)
@@ -154,6 +159,7 @@ struct btBroadphasePair
}
m_algorithm = 0;
m_userInfo = 0;
}
@@ -161,15 +167,37 @@ struct btBroadphasePair
btBroadphaseProxy* m_pProxy1;
mutable btCollisionAlgorithm* m_algorithm;
mutable void* m_userInfo;
};
/*
//comparison for set operation, see Solid DT_Encounter
inline bool operator<(const btBroadphasePair& a, const btBroadphasePair& b)
SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b)
{
return a.m_pProxy0 < b.m_pProxy0 ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1);
}
*/
class btBroadphasePairSortPredicate
{
public:
bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
{
return a.m_pProxy0 > b.m_pProxy0 ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm);
}
};
SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b)
{
return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1);
}
#endif //BROADPHASE_PROXY_H

View File

@@ -16,6 +16,8 @@ subject to the following restrictions:
#ifndef COLLISION_ALGORITHM_H
#define COLLISION_ALGORITHM_H
#include "../../LinearMath/btScalar.h"
struct btBroadphaseProxy;
class btDispatcher;
class btManifoldResult;
@@ -34,6 +36,7 @@ struct btCollisionAlgorithmConstructionInfo
btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp)
:m_dispatcher(dispatcher)
{
(void)temp;
}
btDispatcher* m_dispatcher;
@@ -66,7 +69,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
};

View File

@@ -16,6 +16,8 @@ subject to the following restrictions:
#ifndef _DISPATCHER_H
#define _DISPATCHER_H
#include "../../LinearMath/btScalar.h"
class btCollisionAlgorithm;
struct btBroadphaseProxy;
class btRigidBody;
@@ -34,10 +36,10 @@ struct btDispatcherInfo
DISPATCH_CONTINUOUS
};
btDispatcherInfo()
:m_timeStep(0.f),
:m_timeStep(btScalar(0.)),
m_stepCount(0),
m_dispatchFunc(DISPATCH_DISCRETE),
m_timeOfImpact(1.f),
m_timeOfImpact(btScalar(1.)),
m_useContinuous(false),
m_debugDraw(0),
m_enableSatConvex(false),
@@ -46,10 +48,10 @@ struct btDispatcherInfo
{
}
float m_timeStep;
btScalar m_timeStep;
int m_stepCount;
int m_dispatchFunc;
float m_timeOfImpact;
btScalar m_timeOfImpact;
bool m_useContinuous;
class btIDebugDraw* m_debugDraw;
bool m_enableSatConvex;

View File

@@ -24,7 +24,8 @@ subject to the following restrictions:
int gOverlappingPairs = 0;
btOverlappingPairCache::btOverlappingPairCache():
m_blockedForChanges(false)
m_blockedForChanges(false),
m_overlapFilterCallback(0)
//m_NumOverlapBroadphasePair(0)
{
}
@@ -39,15 +40,15 @@ btOverlappingPairCache::~btOverlappingPairCache()
void btOverlappingPairCache::removeOverlappingPair(btBroadphasePair& findPair)
{
std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.find(findPair);
// assert(it != m_overlappingPairSet.end());
if (it != m_overlappingPairSet.end())
int findIndex = m_overlappingPairArray.findLinearSearch(findPair);
if (findIndex < m_overlappingPairArray.size())
{
gOverlappingPairs--;
btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
cleanOverlappingPair(*pair);
m_overlappingPairSet.erase(it);
btBroadphasePair& pair = m_overlappingPairArray[findIndex];
cleanOverlappingPair(pair);
m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.size()-1);
m_overlappingPairArray.pop_back();
}
}
@@ -78,7 +79,7 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa
btBroadphasePair pair(*proxy0,*proxy1);
m_overlappingPairSet.insert(pair);
m_overlappingPairArray.push_back(pair);
gOverlappingPairs++;
}
@@ -93,13 +94,15 @@ void btOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroa
return 0;
btBroadphasePair tmpPair(*proxy0,*proxy1);
std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.find(tmpPair);
if ((it == m_overlappingPairSet.end()))
return 0;
int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair);
//assert(it != m_overlappingPairSet.end());
btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
return pair;
if (findIndex < m_overlappingPairArray.size())
{
//assert(it != m_overlappingPairSet.end());
btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
return pair;
}
return 0;
}
@@ -170,30 +173,23 @@ void btOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseP
void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback)
{
std::set<btBroadphasePair>::iterator it = m_overlappingPairSet.begin();
for (; !(it==m_overlappingPairSet.end());)
int i;
for (i=0;i<m_overlappingPairArray.size();)
{
btBroadphasePair* pair = (btBroadphasePair*)(&(*it));
btBroadphasePair* pair = &m_overlappingPairArray[i];
if (callback->processOverlap(*pair))
{
cleanOverlappingPair(*pair);
std::set<btBroadphasePair>::iterator it2 = it;
//why does next line not compile under OS X??
#ifdef MAC_OSX_FIXED_STL_SET
it2++;
it = m_overlappingPairSet.erase(it);
assert(it == it2);
#else
it++;
m_overlappingPairSet.erase(it2);
#endif //MAC_OSX_FIXED_STL_SET
m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
m_overlappingPairArray.pop_back();
gOverlappingPairs--;
} else
{
it++;
i++;
}
}
}

View File

@@ -20,65 +20,101 @@ subject to the following restrictions:
#include "btBroadphaseInterface.h"
#include "btBroadphaseProxy.h"
#include "LinearMath/btPoint3.h"
#include <set>
#include "../../LinearMath/btPoint3.h"
#include "../../LinearMath/btAlignedObjectArray.h"
struct btOverlapCallback
{
virtual ~btOverlapCallback()
{
}
virtual ~btOverlapCallback()
{}
//return true for deletion of the pair
virtual bool processOverlap(btBroadphasePair& pair) = 0;
};
struct btOverlapFilterCallback
{
virtual ~btOverlapFilterCallback()
{}
// return true when pairs need collision
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
};
///btOverlappingPairCache maintains the objects with overlapping AABB
///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
class btOverlappingPairCache : public btBroadphaseInterface
{
//avoid brute-force finding all the time
std::set<btBroadphasePair> m_overlappingPairSet;
//during the dispatch, check that user doesn't destroy/create proxy
bool m_blockedForChanges;
protected:
//avoid brute-force finding all the time
btAlignedObjectArray<btBroadphasePair> m_overlappingPairArray;
//during the dispatch, check that user doesn't destroy/create proxy
bool m_blockedForChanges;
//if set, use the callback instead of the built in filter in needBroadphaseCollision
btOverlapFilterCallback* m_overlapFilterCallback;
public:
btOverlappingPairCache();
virtual ~btOverlappingPairCache();
virtual void processAllOverlappingPairs(btOverlapCallback*);
void removeOverlappingPair(btBroadphasePair& pair);
void cleanOverlappingPair(btBroadphasePair& pair);
btOverlappingPairCache();
virtual ~btOverlappingPairCache();
void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
void processAllOverlappingPairs(btOverlapCallback*);
void removeOverlappingPair(btBroadphasePair& pair);
void cleanOverlappingPair(btBroadphasePair& pair);
void addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
void cleanProxyFromPairs(btBroadphaseProxy* proxy);
void cleanProxyFromPairs(btBroadphaseProxy* proxy);
void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy);
void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy);
inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
{
if (m_overlapFilterCallback)
return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
return collides;
}
virtual void refreshOverlappingPairs() =0;
btBroadphasePair* getOverlappingPairArrayPtr()
{
return &m_overlappingPairArray[0];
}
const btBroadphasePair* getOverlappingPairArrayPtr() const
{
return &m_overlappingPairArray[0];
}
int getNumOverlappingPairs() const
{
return m_overlappingPairArray.size();
}
virtual void refreshOverlappingPairs() =0;
btOverlapFilterCallback* getOverlapFilterCallback()
{
return m_overlapFilterCallback;
}
void setOverlapFilterCallback(btOverlapFilterCallback* callback)
{
m_overlapFilterCallback = callback;
}
};
#endif //OVERLAPPING_PAIR_CACHE_H

View File

@@ -20,7 +20,7 @@ subject to the following restrictions:
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include <vector>
#include <new>
void btSimpleBroadphase::validate()
@@ -85,8 +85,8 @@ btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& min, cons
btSimpleBroadphaseProxy* proxy1 = &m_proxies[0];
int index = proxy - proxy1;
assert(index == freeIndex);
int index = int(proxy - proxy1);
btAssert(index == freeIndex);
m_pProxies[m_numProxies] = proxy;
m_numProxies++;
@@ -100,7 +100,8 @@ class RemovingOverlapCallback : public btOverlapCallback
protected:
virtual bool processOverlap(btBroadphasePair& pair)
{
assert(0);
(void)pair;
btAssert(0);
return false;
}
};
@@ -131,8 +132,8 @@ void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg)
btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
btSimpleBroadphaseProxy* proxy1 = &m_proxies[0];
int index = proxy0 - proxy1;
assert (index < m_maxProxies);
int index = int(proxy0 - proxy1);
btAssert (index < m_maxProxies);
m_freeProxies[--m_firstFreeProxy] = index;
removeOverlappingPairsContainingProxy(proxyOrg);

View File

@@ -31,6 +31,7 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask),
m_min(minpt),m_max(maxpt)
{
(void)shapeType;
}
@@ -40,6 +41,8 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
class btSimpleBroadphase : public btOverlappingPairCache
{
protected:
btSimpleBroadphaseProxy* m_proxies;
int* m_freeProxies;
int m_firstFreeProxy;

View File

@@ -13,6 +13,7 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "LinearMath/btScalar.h"
#include "SphereTriangleDetector.h"
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h"
@@ -28,13 +29,14 @@ m_triangle(triangle)
void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
{
(void)debugDraw;
const btTransform& transformA = input.m_transformA;
const btTransform& transformB = input.m_transformB;
btVector3 point,normal;
btScalar timeOfImpact = 1.f;
btScalar depth = 0.f;
// output.m_distance = 1e30f;
btScalar timeOfImpact = btScalar(1.);
btScalar depth = btScalar(0.);
// output.m_distance = btScalar(1e30);
//move sphere into triangle space
btTransform sphereInTr = transformB.inverseTimes(transformA);
@@ -45,19 +47,19 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
}
#define MAX_OVERLAP 0.f
#define MAX_OVERLAP btScalar(0.)
// See also geometrictools.com
// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv
float SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) {
btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) {
btVector3 diff = p - from;
btVector3 v = to - from;
float t = v.dot(diff);
btScalar t = v.dot(diff);
if (t > 0) {
float dotVV = v.dot(v);
btScalar dotVV = v.dot(v);
if (t < dotVV) {
t /= dotVV;
diff -= t*v;
@@ -80,7 +82,7 @@ bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* ve
}
///combined discrete/continuous sphere-triangle
bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, float &timeOfImpact)
bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact)
{
const btVector3* vertices = &m_triangle->getVertexPtr(0);
@@ -92,25 +94,25 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
normal.normalize();
btVector3 p1ToCentre = c - vertices[0];
float distanceFromPlane = p1ToCentre.dot(normal);
btScalar distanceFromPlane = p1ToCentre.dot(normal);
if (distanceFromPlane < 0.f)
if (distanceFromPlane < btScalar(0.))
{
//triangle facing the other way
distanceFromPlane *= -1.f;
normal *= -1.f;
distanceFromPlane *= btScalar(-1.);
normal *= btScalar(-1.);
}
///todo: move this gContactBreakingThreshold into a proper structure
extern float gContactBreakingThreshold;
extern btScalar gContactBreakingThreshold;
float contactMargin = gContactBreakingThreshold;
btScalar contactMargin = gContactBreakingThreshold;
bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
bool isInsideShellPlane = distanceFromPlane < r;
float deltaDotNormal = delta.dot(normal);
if (!isInsideShellPlane && deltaDotNormal >= 0.0f)
btScalar deltaDotNormal = delta.dot(normal);
if (!isInsideShellPlane && deltaDotNormal >= btScalar(0.0))
return false;
// Check for contact / intersection
@@ -123,7 +125,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
contactPoint = c - normal*distanceFromPlane;
} else {
// Could be inside one of the contact capsules
float contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
btScalar contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
btVector3 nearestOnEdge;
for (int i = 0; i < m_triangle->getNumEdges(); i++) {
@@ -132,7 +134,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
m_triangle->getEdge(i,pa,pb);
float distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge);
btScalar distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge);
if (distanceSqr < contactCapsuleRadiusSqr) {
// Yep, we're inside a capsule
hasContact = true;
@@ -145,25 +147,22 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
if (hasContact) {
btVector3 contactToCentre = c - contactPoint;
float distanceSqr = contactToCentre.length2();
btScalar distanceSqr = contactToCentre.length2();
if (distanceSqr < (r - MAX_OVERLAP)*(r - MAX_OVERLAP)) {
float distance = btSqrt(distanceSqr);
if (1)
{
resultNormal = contactToCentre;
resultNormal.normalize();
}
btScalar distance = btSqrt(distanceSqr);
resultNormal = contactToCentre;
resultNormal.normalize();
point = contactPoint;
depth = -(r-distance);
return true;
}
if (delta.dot(contactToCentre) >= 0.0f)
if (delta.dot(contactToCentre) >= btScalar(0.0))
return false;
// Moving towards the contact point -> collision
point = contactPoint;
timeOfImpact = 0.0f;
timeOfImpact = btScalar(0.0);
return true;
}
@@ -189,7 +188,7 @@ bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const b
btVector3 edge2_normal( edge2.cross(normal));
btVector3 edge3_normal( edge3.cross(normal));
float r1, r2, r3;
btScalar r1, r2, r3;
r1 = edge1_normal.dot( p1_to_p );
r2 = edge2_normal.dot( p2_to_p );
r3 = edge3_normal.dot( p3_to_p );

View File

@@ -16,8 +16,8 @@ subject to the following restrictions:
#ifndef SPHERE_TRIANGLE_DETECTOR_H
#define SPHERE_TRIANGLE_DETECTOR_H
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "LinearMath/btPoint3.h"
#include "../NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "../../LinearMath/btPoint3.h"
class btSphereShape;
@@ -36,7 +36,7 @@ struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
private:
bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, float &timeOfImpact);
bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact);
bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);

View File

@@ -16,9 +16,8 @@ subject to the following restrictions:
#ifndef COLLISION_CREATE_FUNC
#define COLLISION_CREATE_FUNC
#include <vector>
typedef std::vector<class btCollisionObject*> btCollisionObjectArray;
#include "../../LinearMath/btAlignedObjectArray.h"
typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
class btCollisionAlgorithm;
class btCollisionObject;
@@ -35,8 +34,11 @@ struct btCollisionAlgorithmCreateFunc
}
virtual ~btCollisionAlgorithmCreateFunc(){};
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , btCollisionObject* body0,btCollisionObject* body1)
{
(void)body0;
(void)body1;
return 0;
}
};

View File

@@ -25,7 +25,6 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include <algorithm>
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
int gNumManifold = 0;
@@ -33,16 +32,17 @@ int gNumManifold = 0;
#include <stdio.h>
btCollisionDispatcher::btCollisionDispatcher(bool noDefaultAlgorithms)
:m_useIslands(true),
m_convexConvexCreateFunc(0),
btCollisionDispatcher::btCollisionDispatcher(bool noDefaultAlgorithms):
m_count(0),
m_useIslands(true),
m_convexConvexCreateFunc(0),
m_convexConcaveCreateFunc(0),
m_swappedConvexConcaveCreateFunc(0),
m_compoundCreateFunc(0),
m_swappedCompoundCreateFunc(0),
m_emptyCreateFunc(0)
{
(void)noDefaultAlgorithms;
int i;
setNearCallback(defaultNearCallback);
@@ -56,11 +56,14 @@ m_emptyCreateFunc(0)
}
}
}
//if you want to not link with the default collision algorithms, you can
//define BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
//in your Bullet library build system
#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
btCollisionDispatcher::btCollisionDispatcher ():
m_useIslands(true),
m_count(0)
m_count(0),
m_useIslands(true)
{
int i;
@@ -86,6 +89,9 @@ btCollisionDispatcher::btCollisionDispatcher ():
};
#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
{
m_doubleDispatch[proxyType0][proxyType1] = createFunc;
@@ -129,20 +135,17 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
gNumManifold--;
//printf("releaseManifold: gNumManifold %d\n",gNumManifold);
clearManifold(manifold);
std::vector<btPersistentManifold*>::iterator i =
std::find(m_manifoldsPtr.begin(), m_manifoldsPtr.end(), manifold);
if (!(i == m_manifoldsPtr.end()))
///todo: this can be improved a lot, linear search might be slow part!
int findIndex = m_manifoldsPtr.findLinearSearch(manifold);
if (findIndex < m_manifoldsPtr.size())
{
std::swap(*i, m_manifoldsPtr.back());
m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
m_manifoldsPtr.pop_back();
delete manifold;
}
}
@@ -164,6 +167,8 @@ btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* bo
}
#ifndef BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(int proxyType0,int proxyType1)
{
@@ -197,6 +202,8 @@ btCollisionAlgorithmCreateFunc* btCollisionDispatcher::internalFindCreateFunc(in
return m_emptyCreateFunc;
}
#endif //BT_EXCLUDE_DEFAULT_COLLISIONALGORITHM_REGISTRATION
#ifndef USE_DISPATCH_REGISTRY_ARRAY
@@ -266,6 +273,8 @@ bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionO
if ((!body0->isActive()) && (!body1->isActive()))
needsCollision = false;
else if (!body0->checkCollideWith(body1))
needsCollision = false;
return needsCollision ;
@@ -288,6 +297,16 @@ public:
{
}
btCollisionPairCallback& operator=(btCollisionPairCallback& other)
{
m_dispatchInfo = other.m_dispatchInfo;
m_dispatcher = other.m_dispatcher;
return *this;
}
virtual ~btCollisionPairCallback() {}
virtual bool processOverlap(btBroadphasePair& pair)
{
(*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo);
@@ -337,7 +356,7 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair,
} else
{
//continuous collision detection query, time of impact (toi)
float toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
if (dispatchInfo.m_timeOfImpact > toi)
dispatchInfo.m_timeOfImpact = toi;

View File

@@ -16,13 +16,13 @@ subject to the following restrictions:
#ifndef COLLISION__DISPATCHER_H
#define COLLISION__DISPATCHER_H
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "../BroadphaseCollision/btDispatcher.h"
#include "../NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "../CollisionDispatch/btManifoldResult.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../../LinearMath/btAlignedObjectArray.h"
class btIDebugDraw;
class btOverlappingPairCache;
@@ -41,8 +41,9 @@ typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispa
///Time of Impact, Closest Points and Penetration Depth.
class btCollisionDispatcher : public btDispatcher
{
int m_count;
std::vector<btPersistentManifold*> m_manifoldsPtr;
btAlignedObjectArray<btPersistentManifold*> m_manifoldsPtr;
bool m_useIslands;
@@ -68,7 +69,6 @@ class btCollisionDispatcher : public btDispatcher
public:
///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc);
@@ -92,8 +92,6 @@ public:
return m_manifoldsPtr[index];
}
int m_count;
///the default constructor creates/register default collision algorithms, for convex, compound and concave shape support
btCollisionDispatcher ();

View File

@@ -20,15 +20,19 @@ btCollisionObject::btCollisionObject()
m_collisionShape(0),
m_collisionFlags(0),
m_activationState1(1),
m_deactivationTime(0.f),
m_deactivationTime(btScalar(0.)),
m_userObjectPointer(0),
m_hitFraction(1.f),
m_ccdSweptSphereRadius(0.f),
m_ccdSquareMotionThreshold(0.f)
m_hitFraction(btScalar(1.)),
m_ccdSweptSphereRadius(btScalar(0.)),
m_ccdSquareMotionThreshold(btScalar(0.)),
m_checkCollideWith(false)
{
}
btCollisionObject::~btCollisionObject()
{
}
void btCollisionObject::setActivationState(int newState)
{
@@ -46,7 +50,7 @@ void btCollisionObject::activate(bool forceActivation)
if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT)))
{
setActivationState(ACTIVE_TAG);
m_deactivationTime = 0.f;
m_deactivationTime = btScalar(0.);
}
}

View File

@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef COLLISION_OBJECT_H
#define COLLISION_OBJECT_H
#include "LinearMath/btTransform.h"
#include "../../LinearMath/btTransform.h"
//island management, m_activationState1
#define ACTIVE_TAG 1
@@ -27,21 +27,19 @@ subject to the following restrictions:
struct btBroadphaseProxy;
class btCollisionShape;
#include "LinearMath/btMotionState.h"
#include "../../LinearMath/btMotionState.h"
/// btCollisionObject can be used to manage collision detection objects.
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
/// They can be added to the btCollisionWorld.
class btCollisionObject
ATTRIBUTE_ALIGNED16(class) btCollisionObject
{
protected:
btTransform m_worldTransform;
btBroadphaseProxy* m_broadphaseHandle;
btCollisionShape* m_collisionShape;
///m_interpolationWorldTransform is used for CCD and interpolation
///it can be either previous or future (predicted) transform
@@ -50,12 +48,16 @@ protected:
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
btVector3 m_interpolationLinearVelocity;
btVector3 m_interpolationAngularVelocity;
btBroadphaseProxy* m_broadphaseHandle;
btCollisionShape* m_collisionShape;
int m_collisionFlags;
int m_islandTag1;
int m_companionId;
int m_activationState1;
float m_deactivationTime;
btScalar m_deactivationTime;
btScalar m_friction;
btScalar m_restitution;
@@ -67,13 +69,23 @@ protected:
void* m_internalOwner;
///time of impact calculation
float m_hitFraction;
btScalar m_hitFraction;
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
float m_ccdSweptSphereRadius;
btScalar m_ccdSweptSphereRadius;
/// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold
float m_ccdSquareMotionThreshold;
btScalar m_ccdSquareMotionThreshold;
/// If some object should have elaborate collision filtering by sub-classes
bool m_checkCollideWith;
char m_pad[7];
virtual bool checkCollideWithOverride(btCollisionObject* co)
{
return true;
}
public:
@@ -82,7 +94,7 @@ public:
CF_STATIC_OBJECT= 1,
CF_KINEMATIC_OBJECT= 2,
CF_NO_CONTACT_RESPONSE = 4,
CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution)
};
@@ -114,6 +126,7 @@ public:
btCollisionObject();
virtual ~btCollisionObject();
void setCollisionShape(btCollisionShape* collisionShape)
{
@@ -137,11 +150,11 @@ public:
void setActivationState(int newState);
void setDeactivationTime(float time)
void setDeactivationTime(btScalar time)
{
m_deactivationTime = time;
}
float getDeactivationTime() const
btScalar getDeactivationTime() const
{
return m_deactivationTime;
}
@@ -155,19 +168,19 @@ public:
return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
}
void setRestitution(float rest)
void setRestitution(btScalar rest)
{
m_restitution = rest;
}
float getRestitution() const
btScalar getRestitution() const
{
return m_restitution;
}
void setFriction(float frict)
void setFriction(btScalar frict)
{
m_friction = frict;
}
float getFriction() const
btScalar getFriction() const
{
return m_friction;
}
@@ -251,12 +264,22 @@ public:
m_islandTag1 = tag;
}
const float getHitFraction() const
const int getCompanionId() const
{
return m_companionId;
}
void setCompanionId(int id)
{
m_companionId = id;
}
const btScalar getHitFraction() const
{
return m_hitFraction;
}
void setHitFraction(float hitFraction)
void setHitFraction(btScalar hitFraction)
{
m_hitFraction = hitFraction;
}
@@ -273,25 +296,25 @@ public:
}
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
float getCcdSweptSphereRadius() const
btScalar getCcdSweptSphereRadius() const
{
return m_ccdSweptSphereRadius;
}
///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
void setCcdSweptSphereRadius(float radius)
void setCcdSweptSphereRadius(btScalar radius)
{
m_ccdSweptSphereRadius = radius;
}
float getCcdSquareMotionThreshold() const
btScalar getCcdSquareMotionThreshold() const
{
return m_ccdSquareMotionThreshold;
}
/// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold
void setCcdSquareMotionThreshold(float ccdSquareMotionThreshold)
void setCcdSquareMotionThreshold(btScalar ccdSquareMotionThreshold)
{
m_ccdSquareMotionThreshold = ccdSquareMotionThreshold;
}
@@ -308,6 +331,16 @@ public:
m_userObjectPointer = userPointer;
}
};
inline bool checkCollideWith(btCollisionObject* co)
{
if (m_checkCollideWith)
return checkCollideWithOverride(co);
return true;
}
}
;
#endif //COLLISION_OBJECT_H

View File

@@ -17,6 +17,8 @@ subject to the following restrictions:
#include "btCollisionDispatcher.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" //for raycasting
#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
@@ -31,7 +33,6 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
#include <algorithm>
btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize)
:m_dispatcher1(dispatcher),
@@ -50,13 +51,10 @@ btCollisionWorld::~btCollisionWorld()
delete m_stackAlloc;
//clean up remaining objects
std::vector<btCollisionObject*>::iterator i;
for (i=m_collisionObjects.begin();
!(i==m_collisionObjects.end()); i++)
int i;
for (i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* collisionObject= (*i);
btCollisionObject* collisionObject= m_collisionObjects[i];
btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
if (bp)
@@ -89,9 +87,7 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
{
//check that the object isn't already added
std::vector<btCollisionObject*>::iterator i = std::find(m_collisionObjects.begin(), m_collisionObjects.end(), collisionObject);
assert(i == m_collisionObjects.end());
btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size());
m_collisionObjects.push_back(collisionObject);
@@ -125,13 +121,13 @@ void btCollisionWorld::performDiscreteCollisionDetection()
{
btDispatcherInfo& dispatchInfo = getDispatchInfo();
BEGIN_PROFILE("performDiscreteCollisionDetection");
BEGIN_PROFILE("perform Broadphase Collision Detection");
//update aabb (of all moved objects)
btVector3 aabbMin,aabbMax;
for (size_t i=0;i<m_collisionObjects.size();i++)
for (int i=0;i<m_collisionObjects.size();i++)
{
m_collisionObjects[i]->getCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax);
m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax);
@@ -139,6 +135,11 @@ void btCollisionWorld::performDiscreteCollisionDetection()
m_broadphasePairCache->refreshOverlappingPairs();
END_PROFILE("perform Broadphase Collision Detection");
BEGIN_PROFILE("performDiscreteCollisionDetection");
btDispatcher* dispatcher = getDispatcher();
if (dispatcher)
dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache,dispatchInfo);
@@ -169,39 +170,53 @@ void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
}
std::vector<btCollisionObject*>::iterator i = std::find(m_collisionObjects.begin(), m_collisionObjects.end(), collisionObject);
if (!(i == m_collisionObjects.end()))
{
std::swap(*i, m_collisionObjects.back());
m_collisionObjects.pop_back();
}
//swapremove
m_collisionObjects.remove(collisionObject);
}
void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback)
RayResultCallback& resultCallback,short int collisionFilterMask)
{
btSphereShape pointShape(btScalar(0.0));
pointShape.setMargin(0.f);
objectQuerySingle(&pointShape,rayFromTrans,rayToTrans,
collisionObject,
collisionShape,
colObjWorldTransform,
resultCallback,collisionFilterMask);
}
void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& rayFromTrans,const btTransform& rayToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback,short int collisionFilterMask)
{
btSphereShape pointShape(0.0f);
if (collisionShape->isConvex())
{
btConvexCast::CastResult castResult;
castResult.m_fraction = 1.f;//??
castResult.m_fraction = btScalar(1.);//??
btConvexShape* convexShape = (btConvexShape*) collisionShape;
btVoronoiSimplexSolver simplexSolver;
btSubsimplexConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
//GjkConvexCast convexCaster(castShape,convexShape,&simplexSolver);
//ContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
{
//add hit
if (castResult.m_normal.length2() > 0.0001f)
if (castResult.m_normal.length2() > btScalar(0.0001))
{
castResult.m_normal.normalize();
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
@@ -252,7 +267,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
}
virtual float reportHit(const btVector3& hitNormalLocal, float hitFraction, int partId, int triangleIndex )
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = partId;
@@ -294,11 +309,11 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
btTransform childTrans = compoundShape->getChildTransform(i);
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childWorldTrans = colObjWorldTransform * childTrans;
rayTestSingle(rayFromTrans,rayToTrans,
objectQuerySingle(castShape, rayFromTrans,rayToTrans,
collisionObject,
childCollisionShape,
childWorldTrans,
resultCallback);
resultCallback, collisionFilterMask);
}
@@ -308,7 +323,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
}
}
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback)
void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback,short int collisionFilterMask)
{
@@ -321,28 +336,26 @@ void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& r
/// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
std::vector<btCollisionObject*>::iterator iter;
for (iter=m_collisionObjects.begin();
!(iter==m_collisionObjects.end()); iter++)
int i;
for (i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* collisionObject= (*iter);
btCollisionObject* collisionObject= m_collisionObjects[i];
//only perform raycast if filterMask matches
if(collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collisionFilterMask) {
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
float hitLambda = 1.f; //could use resultCallback.m_closestHitFraction, but needs testing
btVector3 hitNormal;
if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
{
rayTestSingle(rayFromTrans,rayToTrans,
collisionObject,
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
resultCallback);
btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
btVector3 hitNormal;
if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
{
rayTestSingle(rayFromTrans,rayToTrans,
collisionObject,
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
resultCallback);
}
}
}

View File

@@ -53,9 +53,9 @@ subject to the following restrictions:
* Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector.
*
* @section copyright Copyright
* Copyright (C) 2005-2006 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
* Copyright (C) 2005-2007 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
* Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
* Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren.
* Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt.
*
*/
@@ -66,16 +66,14 @@ subject to the following restrictions:
class btStackAlloc;
class btCollisionShape;
class btConvexShape;
class btBroadphaseInterface;
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btTransform.h"
#include "btCollisionObject.h"
#include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include <vector>
#include "../BroadphaseCollision/btOverlappingPairCache.h"
#include "../../LinearMath/btAlignedObjectArray.h"
///CollisionWorld is interface and container for the collision detection
class btCollisionWorld
@@ -84,7 +82,7 @@ class btCollisionWorld
protected:
std::vector<btCollisionObject*> m_collisionObjects;
btAlignedObjectArray<btCollisionObject*> m_collisionObjects;
btDispatcher* m_dispatcher1;
@@ -137,18 +135,18 @@ public:
LocalRayResult(btCollisionObject* collisionObject,
LocalShapeInfo* localShapeInfo,
const btVector3& hitNormalLocal,
float hitFraction)
btScalar hitFraction)
:m_collisionObject(collisionObject),
m_localShapeInfo(m_localShapeInfo),
m_localShapeInfo(localShapeInfo),
m_hitNormalLocal(hitNormalLocal),
m_hitFraction(hitFraction)
{
}
btCollisionObject* m_collisionObject;
btCollisionObject* m_collisionObject;
LocalShapeInfo* m_localShapeInfo;
const btVector3& m_hitNormalLocal;
float m_hitFraction;
btVector3 m_hitNormalLocal;
btScalar m_hitFraction;
};
@@ -158,17 +156,17 @@ public:
virtual ~RayResultCallback()
{
}
float m_closestHitFraction;
btScalar m_closestHitFraction;
bool HasHit()
{
return (m_closestHitFraction < 1.f);
return (m_closestHitFraction < btScalar(1.));
}
RayResultCallback()
:m_closestHitFraction(1.f)
:m_closestHitFraction(btScalar(1.))
{
}
virtual float AddSingleResult(LocalRayResult& rayResult) = 0;
virtual btScalar AddSingleResult(LocalRayResult& rayResult) = 0;
};
struct ClosestRayResultCallback : public RayResultCallback
@@ -187,7 +185,7 @@ public:
btVector3 m_hitPointWorld;
btCollisionObject* m_collisionObject;
virtual float AddSingleResult(LocalRayResult& rayResult)
virtual btScalar AddSingleResult(LocalRayResult& rayResult)
{
//caller already does the filter on the m_closestHitFraction
@@ -211,16 +209,23 @@ public:
/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback);
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback, short int collisionFilterMask=-1);
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
/// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
/// This allows more customization.
void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback);
RayResultCallback& resultCallback, short int collisionFilterMask=-1);
/// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest.
static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback, short int collisionFilterMask=-1);
void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=1,short int collisionFilterMask=1);

View File

@@ -77,9 +77,9 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
btTransform orgTrans = colObj->getWorldTransform();
btCollisionShape* orgShape = colObj->getCollisionShape();
btTransform childTrans = compoundShape->getChildTransform(i);
btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( newChildWorldTrans );
const btTransform& childTrans = compoundShape->getChildTransform(i);
//btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( orgTrans*childTrans );
//the contactpoint is still projected back using the original inverted worldtrans
colObj->setCollisionShape( childShape );
m_childCollisionAlgorithms[i]->processCollision(colObj,otherObj,dispatchInfo,resultOut);
@@ -89,7 +89,7 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
}
}
float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
btCollisionObject* colObj = m_isSwapped? body1 : body0;
@@ -106,7 +106,7 @@ float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* bod
//then use each overlapping node AABB against Tree0
//and vise versa.
float hitFraction = 1.f;
btScalar hitFraction = btScalar(1.);
int numChildren = m_childCollisionAlgorithms.size();
int i;
@@ -119,12 +119,12 @@ float btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* bod
btTransform orgTrans = colObj->getWorldTransform();
btCollisionShape* orgShape = colObj->getCollisionShape();
btTransform childTrans = compoundShape->getChildTransform(i);
btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( newChildWorldTrans );
const btTransform& childTrans = compoundShape->getChildTransform(i);
//btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( orgTrans*childTrans );
colObj->setCollisionShape( childShape );
float frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
if (frac<hitFraction)
{
hitFraction = frac;

View File

@@ -16,21 +16,21 @@ subject to the following restrictions:
#ifndef COMPOUND_COLLISION_ALGORITHM_H
#define COMPOUND_COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btDispatcher.h"
#include "../BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "../NarrowPhaseCollision/btPersistentManifold.h"
class btDispatcher;
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include <vector>
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "btCollisionCreateFunc.h"
#include "../../LinearMath/btAlignedObjectArray.h"
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
/// Place holder, not fully implemented yet
class btCompoundCollisionAlgorithm : public btCollisionAlgorithm
{
std::vector<btCollisionAlgorithm*> m_childCollisionAlgorithms;
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
bool m_isSwapped;
public:
@@ -41,7 +41,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{

View File

@@ -95,7 +95,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
//btVector3 center = triangle[0] + triangle[1]+triangle[2];
//center *= 0.333333f;
//center *= btScalar(0.333333);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(center),color);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(center),color);
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(center),color);
@@ -134,7 +134,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
void btConvexTriangleCallback::setTimeStepAndCounters(float collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
m_dispatchInfoPtr = &dispatchInfo;
m_collisionMarginTriangle = collisionMarginTriangle;
@@ -146,7 +146,7 @@ void btConvexTriangleCallback::setTimeStepAndCounters(float collisionMarginTrian
btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->getCollisionShape());
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
float extraMargin = collisionMarginTriangle;
btScalar extraMargin = collisionMarginTriangle;
btVector3 extra(extraMargin,extraMargin,extraMargin);
m_aabbMax += extra;
@@ -176,7 +176,7 @@ void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* bod
if (convexBody->getCollisionShape()->isConvex())
{
float collisionMarginTriangle = concaveShape->getMargin();
btScalar collisionMarginTriangle = concaveShape->getMargin();
resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
@@ -196,9 +196,10 @@ void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* bod
}
float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)resultOut;
(void)dispatchInfo;
btCollisionObject* convexbody = m_isSwapped ? body1 : body0;
btCollisionObject* triBody = m_isSwapped ? body0 : body1;
@@ -207,10 +208,10 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
//only perform CCD above a certain threshold, this prevents blocking on the long run
//because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
float squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2();
btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2();
if (squareMot0 < convexbody->getCcdSquareMotionThreshold())
{
return 1.f;
return btScalar(1.);
}
//const btVector3& from = convexbody->m_worldTransform.getOrigin();
@@ -227,11 +228,11 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
btTransform m_ccdSphereToTrans;
btTransform m_meshTransform;
float m_ccdSphereRadius;
float m_hitFraction;
btScalar m_ccdSphereRadius;
btScalar m_hitFraction;
LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,float ccdSphereRadius,float hitFraction)
LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction)
:m_ccdSphereFromTrans(from),
m_ccdSphereToTrans(to),
m_ccdSphereRadius(ccdSphereRadius),
@@ -242,6 +243,8 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
{
(void)partId;
(void)triangleIndex;
//do a swept sphere for now
btTransform ident;
ident.setIdentity();
@@ -276,11 +279,11 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
rayAabbMin.setMin(convexToLocal.getOrigin());
btVector3 rayAabbMax = convexFromLocal.getOrigin();
rayAabbMax.setMax(convexToLocal.getOrigin());
float ccdRadius0 = convexbody->getCcdSweptSphereRadius();
btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius();
rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
float curHitFraction = 1.f; //is this available?
btScalar curHitFraction = btScalar(1.); //is this available?
LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal,
convexbody->getCcdSweptSphereRadius(),curHitFraction);
@@ -304,6 +307,6 @@ float btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject
}
}
return 1.f;
return btScalar(1.);
}

View File

@@ -16,13 +16,13 @@ subject to the following restrictions:
#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btDispatcher.h"
#include "../BroadphaseCollision/btBroadphaseInterface.h"
#include "../CollisionShapes/btTriangleCallback.h"
#include "../NarrowPhaseCollision/btPersistentManifold.h"
class btDispatcher;
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "btCollisionCreateFunc.h"
///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
@@ -38,7 +38,7 @@ class btConvexTriangleCallback : public btTriangleCallback
btDispatcher* m_dispatcher;
const btDispatcherInfo* m_dispatchInfoPtr;
float m_collisionMarginTriangle;
btScalar m_collisionMarginTriangle;
public:
int m_triangleCount;
@@ -47,7 +47,7 @@ int m_triangleCount;
btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
void setTimeStepAndCounters(float collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual ~btConvexTriangleCallback();
@@ -86,7 +86,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void clearCache();

View File

@@ -43,23 +43,9 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#ifdef WIN32
#if _MSC_VER >= 1310
//only use SIMD Hull code under Win32
#ifdef TEST_HULL
#define USE_HULL 1
#endif //TEST_HULL
#endif //_MSC_VER
#endif //WIN32
#ifdef USE_HULL
#include "NarrowPhaseCollision/Hull.h"
#include "NarrowPhaseCollision/HullContactCollector.h"
#endif //USE_HULL
btConvexConvexAlgorithm::CreateFunc::CreateFunc()
@@ -76,6 +62,14 @@ btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simp
m_pdSolver = pdSolver;
}
btConvexConvexAlgorithm::CreateFunc::~CreateFunc()
{
if (m_ownsSolvers){
delete m_simplexSolver;
delete m_pdSolver;
}
}
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
: btCollisionAlgorithm(ci),
m_gjkPairDetector(0,0,simplexSolver,pdSolver),
@@ -83,6 +77,9 @@ m_ownManifold (false),
m_manifoldPtr(mf),
m_lowLevelOfDetail(false)
{
(void)body0;
(void)body1;
}
@@ -147,7 +144,7 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
// input.m_maximumDistanceSquared = 1e30f;
// input.m_maximumDistanceSquared = btScalar(1e30);
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
@@ -160,24 +157,26 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
bool disableCcd = false;
float btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)resultOut;
(void)dispatchInfo;
///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold
///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
///col0->m_worldTransform,
float resultFraction = 1.f;
btScalar resultFraction = btScalar(1.);
float squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2();
float squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2();
btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2();
btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2();
if (squareMot0 < col0->getCcdSquareMotionThreshold() &&
squareMot1 < col1->getCcdSquareMotionThreshold())
return resultFraction;
if (disableCcd)
return 1.f;
return btScalar(1.);
//An adhoc way of testing the Continuous Collision Detection algorithms

View File

@@ -16,11 +16,11 @@ subject to the following restrictions:
#ifndef CONVEX_CONVEX_ALGORITHM_H
#define CONVEX_CONVEX_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../NarrowPhaseCollision/btGjkPairDetector.h"
#include "../NarrowPhaseCollision/btPersistentManifold.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "btCollisionCreateFunc.h"
class btConvexPenetrationDepthSolver;
@@ -44,7 +44,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void setLowLevelOfDetail(bool useLowLevel);
@@ -62,6 +62,7 @@ public:
CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
CreateFunc();
virtual ~CreateFunc();
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{

View File

@@ -22,14 +22,13 @@ btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& c
{
}
void btEmptyAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btEmptyAlgorithm::processCollision (btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* )
{
}
float btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
btScalar btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* )
{
return 1.f;
return btScalar(1.);
}

View File

@@ -15,7 +15,7 @@ subject to the following restrictions:
#ifndef EMPTY_ALGORITH
#define EMPTY_ALGORITH
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "btCollisionCreateFunc.h"
#define ATTRIBUTE_ALIGNED(a)
@@ -31,12 +31,14 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
(void)body0;
(void)body1;
return new btEmptyAlgorithm(ci);
}
};

View File

@@ -27,7 +27,7 @@ inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const b
{
btScalar friction = body0->getFriction() * body1->getFriction();
const btScalar MAX_FRICTION = 10.f;
const btScalar MAX_FRICTION = btScalar(10.);
if (friction < -MAX_FRICTION)
friction = -MAX_FRICTION;
if (friction > MAX_FRICTION)
@@ -53,7 +53,7 @@ btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* b
}
void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth)
void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
assert(m_manifoldPtr);
//order in manifold needs to match
@@ -63,15 +63,22 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
btTransform transAInv = isSwapped? m_rootTransB.inverse() : m_rootTransA.inverse();
btTransform transBInv = isSwapped? m_rootTransA.inverse() : m_rootTransB.inverse();
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
btVector3 localA = transAInv(pointA );
btVector3 localB = transBInv(pointInWorld);
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
btVector3 localA;
btVector3 localB;
if (isSwapped)
{
localA = m_rootTransB.invXform(pointA );
localB = m_rootTransA.invXform(pointInWorld);
} else
{
localA = m_rootTransA.invXform(pointA );
localB = m_rootTransB.invXform(pointInWorld);
}
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
int insertIndex = m_manifoldPtr->getCacheEntry(newPt);

View File

@@ -23,7 +23,7 @@ class btManifoldPoint;
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "LinearMath/btTransform.h"
#include "../../LinearMath/btTransform.h"
typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
extern ContactAddedCallback gContactAddedCallback;
@@ -68,7 +68,7 @@ public:
m_index1=index1;
}
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,float depth);
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);

View File

@@ -8,8 +8,7 @@
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
#include <stdio.h>
#include <algorithm>
#include "LinearMath/btQuickprof.h"
btSimulationIslandManager::btSimulationIslandManager()
{
@@ -33,7 +32,7 @@ void btSimulationIslandManager::findUnions(btDispatcher* dispatcher)
for (int i=0;i<dispatcher->getNumManifolds();i++)
{
const btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
//static objects (invmass 0.f) don't merge !
//static objects (invmass btScalar(0.)) don't merge !
const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
@@ -57,16 +56,15 @@ void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld
// put the index into m_controllers into m_tag
{
std::vector<btCollisionObject*>::iterator i;
int index = 0;
for (i=colWorld->getCollisionObjectArray().begin();
!(i==colWorld->getCollisionObjectArray().end()); i++)
int i;
for (i=0;i<colWorld->getCollisionObjectArray().size(); i++)
{
btCollisionObject* collisionObject= (*i);
btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
collisionObject->setIslandTag(index);
collisionObject->setHitFraction(1.f);
collisionObject->setCompanionId(-1);
collisionObject->setHitFraction(btScalar(1.));
index++;
}
@@ -88,20 +86,19 @@ void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* col
{
std::vector<btCollisionObject*>::iterator i;
int index = 0;
for (i=colWorld->getCollisionObjectArray().begin();
!(i==colWorld->getCollisionObjectArray().end()); i++)
int i;
for (i=0;i<colWorld->getCollisionObjectArray().size();i++)
{
btCollisionObject* collisionObject= (*i);
btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
if (collisionObject->mergesSimulationIslands())
{
collisionObject->setIslandTag( m_unionFind.find(index) );
collisionObject->setCompanionId(-1);
} else
{
collisionObject->setIslandTag(-1);
collisionObject->setCompanionId(-2);
}
index++;
}
@@ -118,13 +115,21 @@ inline int getIslandId(const btPersistentManifold* lhs)
}
bool btPersistentManifoldSortPredicate(const btPersistentManifold* lhs, const btPersistentManifold* rhs)
/// function object that routes calls to operator<
class btPersistentManifoldSortPredicate
{
int rIslandId0,lIslandId0;
rIslandId0 = getIslandId(rhs);
lIslandId0 = getIslandId(lhs);
return lIslandId0 < rIslandId0;
}
public:
SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs )
{
return getIslandId(lhs) < getIslandId(rhs);
}
};
//
@@ -132,6 +137,22 @@ bool btPersistentManifoldSortPredicate(const btPersistentManifold* lhs, const bt
//
void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
{
/*if (0)
{
int maxNumManifolds = dispatcher->getNumManifolds();
btCollisionDispatcher* colDis = (btCollisionDispatcher*)dispatcher;
btPersistentManifold** manifold = colDis->getInternalManifoldPointer();
callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, 0);
return;
}
*/
BEGIN_PROFILE("islandUnionFindAndHeapSort");
//we are going to sort the unionfind array, and store the element id in the size
//afterwards, we clean unionfind, to make sure no-one uses it anymore
@@ -139,9 +160,11 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
int numElem = getUnionFind().getNumElements();
int endIslandIndex=1;
int startIslandIndex;
//update the sleeping state for bodies, if all are sleeping
for (int startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
{
int islandId = getUnionFind().getElement(startIslandIndex).m_id;
for (endIslandIndex = startIslandIndex+1;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
@@ -224,7 +247,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
}
}
std::vector<btPersistentManifold*> islandmanifold;
btAlignedObjectArray<btPersistentManifold*> islandmanifold;
int i;
int maxNumManifolds = dispatcher->getNumManifolds();
islandmanifold.reserve(maxNumManifolds);
@@ -261,63 +284,74 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
// Sort manifolds, based on islands
// Sort the vector using predicate and std::sort
std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
//std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
//we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
islandmanifold.heapSort(btPersistentManifoldSortPredicate());
//now process all active islands (sets of manifolds for now)
int startManifoldIndex = 0;
int endManifoldIndex = 1;
int islandId;
//int islandId;
END_PROFILE("islandUnionFindAndHeapSort");
btAlignedObjectArray<btCollisionObject*> islandBodies;
//traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
for (int startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
{
int islandId = getUnionFind().getElement(startIslandIndex).m_id;
bool islandSleeping = false;
//traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
{
int islandId = getUnionFind().getElement(startIslandIndex).m_id;
bool islandSleeping = false;
for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
{
int i = getUnionFind().getElement(endIslandIndex).m_sz;
btCollisionObject* colObj0 = collisionObjects[i];
islandBodies.push_back(colObj0);
if (!colObj0->isActive())
islandSleeping = true;
}
//find the accompanying contact manifold for this islandId
int numIslandManifolds = 0;
btPersistentManifold** startManifold = 0;
//find the accompanying contact manifold for this islandId
int numIslandManifolds = 0;
btPersistentManifold** startManifold = 0;
if (startManifoldIndex<numManifolds)
{
int curIslandId = getIslandId(islandmanifold[startManifoldIndex]);
if (curIslandId == islandId)
{
startManifold = &islandmanifold[startManifoldIndex];
if (startManifoldIndex<numManifolds)
{
int curIslandId = getIslandId(islandmanifold[startManifoldIndex]);
if (curIslandId == islandId)
{
startManifold = &islandmanifold[startManifoldIndex];
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(islandmanifold[endManifoldIndex]));endManifoldIndex++)
{
for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(islandmanifold[endManifoldIndex]));endManifoldIndex++)
{
}
/// Process the actual simulation, only if not sleeping/deactivated
numIslandManifolds = endManifoldIndex-startManifoldIndex;
}
}
/// Process the actual simulation, only if not sleeping/deactivated
numIslandManifolds = endManifoldIndex-startManifoldIndex;
}
}
}
if (!islandSleeping)
{
callback->ProcessIsland(&islandBodies[0],islandBodies.size(),startManifold,numIslandManifolds, islandId);
}
if (numIslandManifolds)
{
startManifoldIndex = endManifoldIndex;
}
if (!islandSleeping)
{
callback->ProcessIsland(startManifold,numIslandManifolds, islandId);
}
if (numIslandManifolds)
{
startManifoldIndex = endManifoldIndex;
}
}
islandBodies.resize(0);
}
}

View File

@@ -16,9 +16,10 @@ subject to the following restrictions:
#ifndef SIMULATION_ISLAND_MANAGER_H
#define SIMULATION_ISLAND_MANAGER_H
#include "BulletCollision/CollisionDispatch/btUnionFind.h"
#include "../CollisionDispatch/btUnionFind.h"
#include "btCollisionCreateFunc.h"
class btCollisionObject;
class btCollisionWorld;
class btDispatcher;
@@ -49,7 +50,7 @@ public:
{
virtual ~IslandCallback() {};
virtual void ProcessIsland(class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0;
virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0;
};
void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback);

View File

@@ -50,6 +50,8 @@ btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm()
void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
(void)resultOut;
if (!m_manifoldPtr)
return;
@@ -64,7 +66,7 @@ void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,b
btVector3 sphereCenter = sphereObj->getWorldTransform().getOrigin();
btScalar radius = sphere0->getRadius();
float dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
if (dist < SIMD_EPSILON)
{
@@ -81,10 +83,15 @@ void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,b
}
float btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)resultOut;
(void)dispatchInfo;
(void)col0;
(void)col1;
//not yet
return 1.f;
return btScalar(1.);
}
@@ -117,14 +124,14 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
/////////////////////////////////////////////////
btVector3 tmp, prel, n[6], normal, v3P;
btScalar fSep = 10000000.0f, fSepThis;
btScalar fSep = btScalar(10000000.0), fSepThis;
n[0].setValue( -1.0f, 0.0f, 0.0f );
n[1].setValue( 0.0f, -1.0f, 0.0f );
n[2].setValue( 0.0f, 0.0f, -1.0f );
n[3].setValue( 1.0f, 0.0f, 0.0f );
n[4].setValue( 0.0f, 1.0f, 0.0f );
n[5].setValue( 0.0f, 0.0f, 1.0f );
n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) );
n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) );
n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) );
n[3].setValue( btScalar(1.0), btScalar(0.0), btScalar(0.0) );
n[4].setValue( btScalar(0.0), btScalar(1.0), btScalar(0.0) );
n[5].setValue( btScalar(0.0), btScalar(0.0), btScalar(1.0) );
// convert point in local space
prel = m44T.invXform( sphereCenter);
@@ -136,7 +143,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
for (int i=0;i<6;i++)
{
int j = i<3? 0:1;
if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > 0.0f )
if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > btScalar(0.0) )
{
v3P = v3P - n[i]*fSepThis;
bFound = true;
@@ -154,9 +161,9 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
pointOnBox = v3P + normal*margins;
v3PointOnSphere = prel - normal*fRadius;
if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > 0.0f )
if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > btScalar(0.0) )
{
return 1.0f;
return btScalar(1.0);
}
// transform back in world space
@@ -171,7 +178,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
{
fSep = - btSqrt(fSeps2);
normal = (pointOnBox-v3PointOnSphere);
normal *= 1.f/fSep;
normal *= btScalar(1.)/fSep;
}
return fSep;
@@ -185,10 +192,10 @@ btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* box
bounds[0] = boundsVec[0];
bounds[1] = boundsVec[1];
if ( fPenetration <= 0.0f )
if ( fPenetration <= btScalar(0.0) )
return (fPenetration-margins);
else
return 1.0f;
return btScalar(1.0);
}
btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* boxObj,btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax)
@@ -200,14 +207,14 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject*
bounds[1] = aabbMax;
btVector3 p0, tmp, prel, n[6], normal;
btScalar fSep = -10000000.0f, fSepThis;
btScalar fSep = btScalar(-10000000.0), fSepThis;
n[0].setValue( -1.0f, 0.0f, 0.0f );
n[1].setValue( 0.0f, -1.0f, 0.0f );
n[2].setValue( 0.0f, 0.0f, -1.0f );
n[3].setValue( 1.0f, 0.0f, 0.0f );
n[4].setValue( 0.0f, 1.0f, 0.0f );
n[5].setValue( 0.0f, 0.0f, 1.0f );
n[0].setValue( btScalar(-1.0), btScalar(0.0), btScalar(0.0) );
n[1].setValue( btScalar(0.0), btScalar(-1.0), btScalar(0.0) );
n[2].setValue( btScalar(0.0), btScalar(0.0), btScalar(-1.0) );
n[3].setValue( btScalar(1.0), btScalar(0.0), btScalar(0.0) );
n[4].setValue( btScalar(0.0), btScalar(1.0), btScalar(0.0) );
n[5].setValue( btScalar(0.0), btScalar(0.0), btScalar(1.0) );
const btTransform& m44T = boxObj->getWorldTransform();
@@ -219,7 +226,7 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject*
for (int i=0;i<6;i++)
{
int j = i<3 ? 0:1;
if ( (fSepThis = ((prel-bounds[j]) .dot( n[i]))-fRadius) > 0.0f ) return 1.0f;
if ( (fSepThis = ((prel-bounds[j]) .dot( n[i]))-fRadius) > btScalar(0.0) ) return btScalar(1.0);
if ( fSepThis > fSep )
{
p0 = bounds[j]; normal = (btVector3&)n[i];

View File

@@ -16,11 +16,11 @@ subject to the following restrictions:
#ifndef SPHERE_BOX_COLLISION_ALGORITHM_H
#define SPHERE_BOX_COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
#include "LinearMath/btVector3.h"
#include "../../LinearMath/btVector3.h"
/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
@@ -38,7 +38,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius );

View File

@@ -41,6 +41,8 @@ btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm()
void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
if (!m_manifoldPtr)
return;
@@ -48,7 +50,7 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape();
btVector3 diff = col0->getWorldTransform().getOrigin()- col1->getWorldTransform().getOrigin();
float len = diff.length();
btScalar len = diff.length();
btScalar radius0 = sphere0->getRadius();
btScalar radius1 = sphere1->getRadius();
@@ -71,8 +73,13 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
}
float btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)col0;
(void)col1;
(void)dispatchInfo;
(void)resultOut;
//not yet
return 1.f;
return btScalar(1.);
}

View File

@@ -16,9 +16,9 @@ subject to the following restrictions:
#ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H
#define SPHERE_SPHERE_COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
@@ -37,7 +37,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual ~btSphereSphereCollisionAlgorithm();

View File

@@ -56,7 +56,7 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
SphereTriangleDetector detector(sphere,triangle);
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_maximumDistanceSquared = 1e30f;//todo: tighter bounds
input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds
input.m_transformA = col0->getWorldTransform();
input.m_transformB = col1->getWorldTransform();
@@ -64,8 +64,13 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
}
float btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)resultOut;
(void)dispatchInfo;
(void)col0;
(void)col1;
//not yet
return 1.f;
return btScalar(1.);
}

View File

@@ -16,9 +16,9 @@ subject to the following restrictions:
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
#include "../BroadphaseCollision/btCollisionAlgorithm.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
@@ -38,7 +38,7 @@ public:
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual ~btSphereTriangleCollisionAlgorithm();

View File

@@ -15,7 +15,6 @@ subject to the following restrictions:
#include "btUnionFind.h"
#include <assert.h>
#include <algorithm>
@@ -50,11 +49,16 @@ void btUnionFind::reset(int N)
}
}
bool btUnionFindElementSortPredicate(const btElement& lhs, const btElement& rhs)
{
return lhs.m_id < rhs.m_id;
}
class btUnionFindElementSortPredicate
{
public:
bool operator() ( const btElement& lhs, const btElement& rhs )
{
return lhs.m_id < rhs.m_id;
}
};
///this is a special operation, destroying the content of btUnionFind.
///it sorts the elements, based on island id, in order to make it easy to iterate over islands
@@ -71,7 +75,9 @@ void btUnionFind::sortIslands()
}
// Sort the vector using predicate and std::sort
std::sort(m_elements.begin(), m_elements.end(), btUnionFindElementSortPredicate);
//std::sort(m_elements.begin(), m_elements.end(), btUnionFindElementSortPredicate);
//perhaps use radix sort?
m_elements.heapSort(btUnionFindElementSortPredicate());
}

View File

@@ -16,7 +16,10 @@ subject to the following restrictions:
#ifndef UNION_FIND_H
#define UNION_FIND_H
#include <vector>
#include "../../LinearMath/btAlignedObjectArray.h"
#define USE_PATH_COMPRESSION 1
struct btElement
{
int m_id;
@@ -29,7 +32,7 @@ struct btElement
class btUnionFind
{
private:
std::vector<btElement> m_elements;
btAlignedObjectArray<btElement> m_elements;
public:
@@ -78,6 +81,7 @@ class btUnionFind
if (i == j)
return;
#ifndef USE_PATH_COMPRESSION
//weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) )
if (m_elements[i].m_sz < m_elements[j].m_sz)
{
@@ -87,6 +91,9 @@ class btUnionFind
{
m_elements[j].m_id = i; m_elements[i].m_sz += m_elements[j].m_sz;
}
#else
m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz;
#endif //USE_PATH_COMPRESSION
}
int find(int x)
@@ -97,7 +104,7 @@ class btUnionFind
while (x != m_elements[x].m_id)
{
//not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically
#define USE_PATH_COMPRESSION 1
#ifdef USE_PATH_COMPRESSION
//
m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id;

View File

@@ -42,17 +42,16 @@ void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabb
void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
//float margin = 0.f;
//btScalar margin = btScalar(0.);
btVector3 halfExtents = getHalfExtents();
btScalar lx=2.f*(halfExtents.x());
btScalar ly=2.f*(halfExtents.y());
btScalar lz=2.f*(halfExtents.z());
inertia[0] = mass/(12.0f) * (ly*ly + lz*lz);
inertia[1] = mass/(12.0f) * (lx*lx + lz*lz);
inertia[2] = mass/(12.0f) * (lx*lx + ly*ly);
btScalar lx=btScalar(2.)*(halfExtents.x());
btScalar ly=btScalar(2.)*(halfExtents.y());
btScalar lz=btScalar(2.)*(halfExtents.z());
inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
mass/(btScalar(12.0)) * (lx*lx + lz*lz),
mass/(btScalar(12.0)) * (lx*lx + ly*ly));
}

View File

@@ -17,10 +17,10 @@ subject to the following restrictions:
#define OBB_BOX_MINKOWSKI_H
#include "btPolyhedralConvexShape.h"
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "LinearMath/btPoint3.h"
#include "LinearMath/btSimdMinMax.h"
#include "btCollisionMargin.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h"
#include "../../LinearMath/btPoint3.h"
#include "../../LinearMath/btSimdMinMax.h"
///btBoxShape implements both a feature based (vertex/edge/plane) and implicit (getSupportingVertex) Box
class btBoxShape: public btPolyhedralConvexShape
@@ -41,9 +41,9 @@ public:
btVector3 halfExtents = getHalfExtents();
btVector3 supVertex;
supVertex = btPoint3(vec.x() < btScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
supVertex = btPoint3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
return supVertex;
}
@@ -54,9 +54,9 @@ public:
btVector3 margin(getMargin(),getMargin(),getMargin());
halfExtents -= margin;
return btVector3(vec.x() < btScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
return btVector3(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
}
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
@@ -69,9 +69,9 @@ public:
for (int i=0;i<numVectors;i++)
{
const btVector3& vec = vectors[i];
supportVerticesOut[i].setValue(vec.x() < btScalar(0.0f) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0f) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0f) ? -halfExtents.z() : halfExtents.z());
supportVerticesOut[i].setValue(vec.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
vec.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
vec.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z());
}
}
@@ -132,27 +132,27 @@ public:
switch (i)
{
case 0:
plane.setValue(1.f,0.f,0.f);
plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
plane[3] = -halfExtents.x();
break;
case 1:
plane.setValue(-1.f,0.f,0.f);
plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
plane[3] = -halfExtents.x();
break;
case 2:
plane.setValue(0.f,1.f,0.f);
plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
plane[3] = -halfExtents.y();
break;
case 3:
plane.setValue(0.f,-1.f,0.f);
plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
plane[3] = -halfExtents.y();
break;
case 4:
plane.setValue(0.f,0.f,1.f);
plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
plane[3] = -halfExtents.z();
break;
case 5:
plane.setValue(0.f,0.f,-1.f);
plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
plane[3] = -halfExtents.z();
break;
default:
@@ -265,22 +265,22 @@ public:
switch (index)
{
case 0:
penetrationVector.setValue(1.f,0.f,0.f);
penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
break;
case 1:
penetrationVector.setValue(-1.f,0.f,0.f);
penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
break;
case 2:
penetrationVector.setValue(0.f,1.f,0.f);
penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
break;
case 3:
penetrationVector.setValue(0.f,-1.f,0.f);
penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
break;
case 4:
penetrationVector.setValue(0.f,0.f,1.f);
penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
break;
case 5:
penetrationVector.setValue(0.f,0.f,-1.f);
penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
break;
default:
assert(0);

View File

@@ -18,21 +18,53 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface)
:btTriangleMeshShape(meshInterface)
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression)
:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
{
//construct bvh from meshInterface
#ifndef DISABLE_BVH
m_bvh = new btOptimizedBvh();
m_bvh->build(meshInterface);
btVector3 bvhAabbMin,bvhAabbMax;
meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
#endif //DISABLE_BVH
}
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
:btTriangleMeshShape(meshInterface),m_useQuantizedAabbCompression(useQuantizedAabbCompression)
{
//construct bvh from meshInterface
#ifndef DISABLE_BVH
m_bvh = new btOptimizedBvh();
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
#endif //DISABLE_BVH
}
void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax)
{
m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax );
m_localAabbMin.setMin(aabbMin);
m_localAabbMax.setMax(aabbMax);
}
void btBvhTriangleMeshShape::refitTree()
{
m_bvh->refit( m_meshInterface );
recalcLocalAabb();
}
btBvhTriangleMeshShape::~btBvhTriangleMeshShape()
{
delete m_bvh;
@@ -63,7 +95,7 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
{
}
virtual void processNode(const btOptimizedBvhNode* node)
virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
{
const unsigned char *vertexbase;
int numverts;
@@ -84,19 +116,21 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
indexstride,
numfaces,
indicestype,
node->m_subPart);
nodeSubPart);
int* gfxbase = (int*)(indexbase+node->m_triangleIndex*indexstride);
int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride);
const btVector3& meshScaling = m_meshInterface->getScaling();
for (int j=2;j>=0;j--)
{
int graphicsindex = gfxbase[j];
#ifdef DEBUG_TRIANGLE_MESH
printf("%d ,",graphicsindex);
#endif //DEBUG_TRIANGLE_MESH
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
m_triangle[j] = btVector3(
graphicsbase[0]*meshScaling.getX(),
@@ -107,8 +141,8 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
#endif //DEBUG_TRIANGLE_MESH
}
m_callback->processTriangle(m_triangle,node->m_subPart,node->m_triangleIndex);
m_meshInterface->unLockReadOnlyVertexBase(node->m_subPart);
m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
}
};
@@ -130,8 +164,10 @@ void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
{
btTriangleMeshShape::setLocalScaling(scaling);
delete m_bvh;
///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
m_bvh = new btOptimizedBvh();
m_bvh->build(m_meshInterface);
//rebuild the bvh...
m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
}
}

View File

@@ -16,20 +16,26 @@ subject to the following restrictions:
#ifndef BVH_TRIANGLE_MESH_SHAPE_H
#define BVH_TRIANGLE_MESH_SHAPE_H
#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
#include "btTriangleMeshShape.h"
#include "btOptimizedBvh.h"
///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
class btBvhTriangleMeshShape : public btTriangleMeshShape
ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape
{
btOptimizedBvh* m_bvh;
public:
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface);
bool m_useQuantizedAabbCompression;
bool m_pad[12];////need padding due to alignment
public:
btBvhTriangleMeshShape() :btTriangleMeshShape(0) {};
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression);
///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
virtual ~btBvhTriangleMeshShape();
@@ -44,6 +50,10 @@ public:
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void refitTree();
///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks
void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax);
//debugging
virtual char* getName()const {return "BVHTRIANGLEMESH";}
@@ -51,8 +61,15 @@ public:
virtual void setLocalScaling(const btVector3& scaling);
};
btOptimizedBvh* getOptimizedBvh()
{
return m_bvh;
}
bool usesQuantizedAabbCompression() const
{
return m_useQuantizedAabbCompression;
}
}
;
#endif //BVH_TRIANGLE_MESH_SHAPE_H

View File

@@ -0,0 +1,146 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "btCapsuleShape.h"
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
#include "LinearMath/btQuaternion.h"
btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
{
m_implicitShapeDimensions.setValue(radius,0.5f*height,radius);
}
btVector3 btCapsuleShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
btVector3 supVec(0,0,0);
btScalar maxDot(btScalar(-1e30));
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
btVector3 vtx;
btScalar newDot;
btScalar radius = getRadius();
{
btVector3 pos(0,getHalfHeight(),0);
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supVec = vtx;
}
}
{
btVector3 pos(0,-getHalfHeight(),0);
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supVec = vtx;
}
}
return supVec;
}
void btCapsuleShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
{
btScalar radius = getRadius();
for (int j=0;j<numVectors;j++)
{
btScalar maxDot(btScalar(-1e30));
const btVector3& vec = vectors[j];
btVector3 vtx;
btScalar newDot;
{
btVector3 pos(0,getHalfHeight(),0);
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supportVerticesOut[j] = vtx;
}
}
{
btVector3 pos(0,-getHalfHeight(),0);
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supportVerticesOut[j] = vtx;
}
}
}
}
void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
//as an approximation, take the inertia of the box that bounds the spheres
btTransform ident;
ident.setIdentity();
btScalar radius = getRadius();
btVector3 halfExtents(radius,radius+getHalfHeight(),radius);
btScalar margin = CONVEX_DISTANCE_MARGIN;
btScalar lx=btScalar(2.)*(halfExtents[0]+margin);
btScalar ly=btScalar(2.)*(halfExtents[1]+margin);
btScalar lz=btScalar(2.)*(halfExtents[2]+margin);
const btScalar x2 = lx*lx;
const btScalar y2 = ly*ly;
const btScalar z2 = lz*lz;
const btScalar scaledmass = mass * btScalar(.08333333);
inertia[0] = scaledmass * (y2+z2);
inertia[1] = scaledmass * (x2+z2);
inertia[2] = scaledmass * (x2+y2);
}

View File

@@ -0,0 +1,60 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_CAPSULE_SHAPE_H
#define BT_CAPSULE_SHAPE_H
#include "btConvexShape.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
///btCapsuleShape represents a capsule around the Y axis
///A more general solution that can represent capsules is the btMultiSphereShape
class btCapsuleShape : public btConvexShape
{
public:
btCapsuleShape(btScalar radius,btScalar height);
///CollisionShape Interface
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
/// btConvexShape Interface
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
virtual int getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; }
virtual char* getName()const
{
return "CapsuleShape";
}
btScalar getRadius() const
{
return m_implicitShapeDimensions.getX();
}
btScalar getHalfHeight() const
{
return m_implicitShapeDimensions.getY();
}
};
#endif //BT_CAPSULE_SHAPE_H

View File

@@ -18,7 +18,7 @@ subject to the following restrictions:
//used by Gjk and some other algorithms
#define CONVEX_DISTANCE_MARGIN 0.04f// 0.1f//;//0.01f
#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01)

View File

@@ -15,6 +15,16 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
/*
Make sure this dummy function never changes so that it
can be used by probes that are checking whether the
library is actually installed.
*/
extern "C" void btBulletCollisionProbe () {}
void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const
{
btTransform tr;
@@ -23,14 +33,14 @@ void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) con
getAabb(tr,aabbMin,aabbMax);
radius = (aabbMax-aabbMin).length()*0.5f;
center = (aabbMin+aabbMax)*0.5f;
radius = (aabbMax-aabbMin).length()*btScalar(0.5);
center = (aabbMin+aabbMax)*btScalar(0.5);
}
float btCollisionShape::getAngularMotionDisc() const
btScalar btCollisionShape::getAngularMotionDisc() const
{
btVector3 center;
float disc;
btScalar disc;
getBoundingSphere(center,disc);
disc += (center).length();
return disc;
@@ -41,25 +51,25 @@ void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const b
//start with static aabb
getAabb(curTrans,temporalAabbMin,temporalAabbMax);
float temporalAabbMaxx = temporalAabbMax.getX();
float temporalAabbMaxy = temporalAabbMax.getY();
float temporalAabbMaxz = temporalAabbMax.getZ();
float temporalAabbMinx = temporalAabbMin.getX();
float temporalAabbMiny = temporalAabbMin.getY();
float temporalAabbMinz = temporalAabbMin.getZ();
btScalar temporalAabbMaxx = temporalAabbMax.getX();
btScalar temporalAabbMaxy = temporalAabbMax.getY();
btScalar temporalAabbMaxz = temporalAabbMax.getZ();
btScalar temporalAabbMinx = temporalAabbMin.getX();
btScalar temporalAabbMiny = temporalAabbMin.getY();
btScalar temporalAabbMinz = temporalAabbMin.getZ();
// add linear motion
btVector3 linMotion = linvel*timeStep;
//todo: simd would have a vector max/min operation, instead of per-element access
if (linMotion.x() > 0.f)
if (linMotion.x() > btScalar(0.))
temporalAabbMaxx += linMotion.x();
else
temporalAabbMinx += linMotion.x();
if (linMotion.y() > 0.f)
if (linMotion.y() > btScalar(0.))
temporalAabbMaxy += linMotion.y();
else
temporalAabbMiny += linMotion.y();
if (linMotion.z() > 0.f)
if (linMotion.z() > btScalar(0.))
temporalAabbMaxz += linMotion.z();
else
temporalAabbMinz += linMotion.z();

View File

@@ -16,18 +16,18 @@ subject to the following restrictions:
#ifndef COLLISION_SHAPE_H
#define COLLISION_SHAPE_H
#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
#include <LinearMath/btMatrix3x3.h>
#include "LinearMath/btPoint3.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
#include "../../LinearMath/btTransform.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "../../LinearMath/btPoint3.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
///btCollisionShape provides interface for collision shapes that can be shared among btCollisionObjects.
class btCollisionShape
{
public:
btCollisionShape() :m_tempDebug(0)
btCollisionShape()
{
}
virtual ~btCollisionShape()
@@ -40,14 +40,15 @@ public:
virtual void getBoundingSphere(btVector3& center,btScalar& radius) const;
///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations.
virtual float getAngularMotionDisc() const;
virtual btScalar getAngularMotionDisc() const;
virtual int getShapeType() const=0;
///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
///result is conservative
void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax);
#ifndef __SPU__
inline bool isPolyhedral() const
{
return btBroadphaseProxy::isPolyhedral(getShapeType());
@@ -72,20 +73,20 @@ public:
return btBroadphaseProxy::isInfinite(getShapeType());
}
virtual int getShapeType() const=0;
virtual void setLocalScaling(const btVector3& scaling) =0;
virtual const btVector3& getLocalScaling() const =0;
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) = 0;
//debugging support
virtual char* getName()const =0 ;
const char* getExtraDebugInfo() const { return m_tempDebug;}
void setExtraDebugInfo(const char* extraDebugInfo) { m_tempDebug = extraDebugInfo;}
const char * m_tempDebug;
//endif debugging support
#endif //__SPU__
virtual void setMargin(float margin) = 0;
virtual float getMargin() const = 0;
virtual void setMargin(btScalar margin) = 0;
virtual btScalar getMargin() const = 0;
};

View File

@@ -20,11 +20,11 @@ subject to the following restrictions:
btCompoundShape::btCompoundShape()
:m_localAabbMin(1e30f,1e30f,1e30f),
m_localAabbMax(-1e30f,-1e30f,-1e30f),
:m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
m_aabbTree(0),
m_collisionMargin(0.f),
m_localScaling(1.f,1.f,1.f)
m_collisionMargin(btScalar(0.)),
m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
{
}
@@ -60,8 +60,8 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{
btVector3 localHalfExtents = 0.5f*(m_localAabbMax-m_localAabbMin);
btVector3 localCenter = 0.5f*(m_localAabbMax+m_localAabbMin);
btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
@@ -84,15 +84,15 @@ void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
btVector3 aabbMin,aabbMax;
getAabb(ident,aabbMin,aabbMax);
btVector3 halfExtents = (aabbMax-aabbMin)*0.5f;
btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
btScalar lx=2.f*(halfExtents.x());
btScalar ly=2.f*(halfExtents.y());
btScalar lz=2.f*(halfExtents.z());
btScalar lx=btScalar(2.)*(halfExtents.x());
btScalar ly=btScalar(2.)*(halfExtents.y());
btScalar lz=btScalar(2.)*(halfExtents.z());
inertia[0] = mass/(12.0f) * (ly*ly + lz*lz);
inertia[1] = mass/(12.0f) * (lx*lx + lz*lz);
inertia[2] = mass/(12.0f) * (lx*lx + ly*ly);
inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz);
inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz);
inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly);
}

View File

@@ -18,12 +18,11 @@ subject to the following restrictions:
#include "btCollisionShape.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include <vector>
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btTransform.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "btCollisionMargin.h"
#include "../../LinearMath/btAlignedObjectArray.h"
class btOptimizedBvh;
@@ -59,11 +58,11 @@ public:
return m_childShapes[index];
}
btTransform getChildTransform(int index)
btTransform& getChildTransform(int index)
{
return m_childTransforms[index];
}
const btTransform getChildTransform(int index) const
const btTransform& getChildTransform(int index) const
{
return m_childTransforms[index];
}
@@ -85,11 +84,11 @@ public:
virtual int getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;}
virtual void setMargin(float margin)
virtual void setMargin(btScalar margin)
{
m_collisionMargin = margin;
}
virtual float getMargin() const
virtual btScalar getMargin() const
{
return m_collisionMargin;
}

View File

@@ -17,7 +17,7 @@ subject to the following restrictions:
#include "btConcaveShape.h"
btConcaveShape::btConcaveShape() : m_collisionMargin(0.f)
btConcaveShape::btConcaveShape() : m_collisionMargin(btScalar(0.))
{
}

View File

@@ -16,9 +16,8 @@ subject to the following restrictions:
#ifndef CONCAVE_SHAPE_H
#define CONCAVE_SHAPE_H
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "btCollisionShape.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "btTriangleCallback.h"
@@ -27,7 +26,7 @@ subject to the following restrictions:
class btConcaveShape : public btCollisionShape
{
protected:
float m_collisionMargin;
btScalar m_collisionMargin;
public:
btConcaveShape();
@@ -36,10 +35,10 @@ public:
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const = 0;
virtual float getMargin() const {
virtual btScalar getMargin() const {
return m_collisionMargin;
}
virtual void setMargin(float collisionMargin)
virtual void setMargin(btScalar collisionMargin)
{
m_collisionMargin = collisionMargin;
}

View File

@@ -24,7 +24,7 @@ m_height(height)
{
setConeUpIndex(1);
btVector3 halfExtents;
m_sinAngle = (m_radius / sqrt(m_radius * m_radius + m_height * m_height));
m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height));
}
btConeShapeZ::btConeShapeZ (btScalar radius,btScalar height):
@@ -67,15 +67,15 @@ void btConeShape::setConeUpIndex(int upIndex)
btVector3 btConeShape::coneLocalSupport(const btVector3& v) const
{
float halfHeight = m_height * 0.5f;
btScalar halfHeight = m_height * btScalar(0.5);
if (v[m_coneIndices[1]] > v.length() * m_sinAngle)
{
btVector3 tmp;
tmp[m_coneIndices[0]] = 0.f;
tmp[m_coneIndices[0]] = btScalar(0.);
tmp[m_coneIndices[1]] = halfHeight;
tmp[m_coneIndices[2]] = 0.f;
tmp[m_coneIndices[2]] = btScalar(0.);
return tmp;
}
else {
@@ -90,9 +90,9 @@ btVector3 btConeShape::coneLocalSupport(const btVector3& v) const
}
else {
btVector3 tmp;
tmp[m_coneIndices[0]] = 0.f;
tmp[m_coneIndices[0]] = btScalar(0.);
tmp[m_coneIndices[1]] = -halfHeight;
tmp[m_coneIndices[2]] = 0.f;
tmp[m_coneIndices[2]] = btScalar(0.);
return tmp;
}
}
@@ -117,12 +117,12 @@ void btConeShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVect
btVector3 btConeShape::localGetSupportingVertex(const btVector3& vec) const
{
btVector3 supVertex = coneLocalSupport(vec);
if ( getMargin()!=0.f )
if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
vecnorm.setValue(-1.f,-1.f,-1.f);
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;

View File

@@ -17,16 +17,16 @@ subject to the following restrictions:
#define CONE_MINKOWSKI_H
#include "btConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
///btConeShape implements a Cone shape, around the Y axis
class btConeShape : public btConvexShape
{
float m_sinAngle;
float m_radius;
float m_height;
btScalar m_sinAngle;
btScalar m_radius;
btScalar m_height;
int m_coneIndices[3];
btVector3 coneLocalSupport(const btVector3& v) const;
@@ -38,8 +38,8 @@ public:
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
float getRadius() const { return m_radius;}
float getHeight() const { return m_height;}
btScalar getRadius() const { return m_radius;}
btScalar getHeight() const { return m_height;}
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia)
@@ -49,17 +49,17 @@ public:
btVector3 aabbMin,aabbMax;
getAabb(identity,aabbMin,aabbMax);
btVector3 halfExtents = (aabbMax-aabbMin)*0.5f;
btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
float margin = getMargin();
btScalar margin = getMargin();
btScalar lx=2.f*(halfExtents.x()+margin);
btScalar ly=2.f*(halfExtents.y()+margin);
btScalar lz=2.f*(halfExtents.z()+margin);
btScalar lx=btScalar(2.)*(halfExtents.x()+margin);
btScalar ly=btScalar(2.)*(halfExtents.y()+margin);
btScalar lz=btScalar(2.)*(halfExtents.z()+margin);
const btScalar x2 = lx*lx;
const btScalar y2 = ly*ly;
const btScalar z2 = lz*lz;
const btScalar scaledmass = mass * 0.08333333f;
const btScalar scaledmass = mass * btScalar(0.08333333);
inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));

View File

@@ -19,7 +19,7 @@ subject to the following restrictions:
btConvexHullShape ::btConvexHullShape (const float* points,int numPoints,int stride)
btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride)
{
m_points.resize(numPoints);
@@ -30,26 +30,37 @@ btConvexHullShape ::btConvexHullShape (const float* points,int numPoints,int str
btPoint3* point = (btPoint3*)(pointsBaseAddress + i*stride);
m_points[i] = point[0];
}
recalcLocalAabb();
}
void btConvexHullShape::addPoint(const btPoint3& point)
{
m_points.push_back(point);
recalcLocalAabb();
}
btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
btVector3 supVec(0.f,0.f,0.f);
btScalar newDot,maxDot = -1e30f;
btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
btScalar newDot,maxDot = btScalar(-1e30);
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
if (lenSqr < 0.0001f)
if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
float rlen = 1.f / btSqrt(lenSqr );
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
for (size_t i=0;i<m_points.size();i++)
for (int i=0;i<m_points.size();i++)
{
btPoint3 vtx = m_points[i] * m_localScaling;
@@ -70,10 +81,10 @@ void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const
{
for (int i=0;i<numVectors;i++)
{
supportVerticesOut[i][3] = -1e30f;
supportVerticesOut[i][3] = btScalar(-1e30);
}
}
for (size_t i=0;i<m_points.size();i++)
for (int i=0;i<m_points.size();i++)
{
btPoint3 vtx = m_points[i] * m_localScaling;
@@ -101,12 +112,12 @@ btVector3 btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const
{
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
if ( getMargin()!=0.f )
if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
vecnorm.setValue(-1.f,-1.f,-1.f);
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
@@ -153,13 +164,14 @@ int btConvexHullShape::getNumPlanes() const
return 0;
}
void btConvexHullShape::getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
void btConvexHullShape::getPlane(btVector3& ,btPoint3& ,int ) const
{
assert(0);
btAssert(0);
}
//not yet
bool btConvexHullShape::isInside(const btPoint3& pt,btScalar tolerance) const
bool btConvexHullShape::isInside(const btPoint3& ,btScalar ) const
{
assert(0);
return false;

View File

@@ -17,29 +17,37 @@ subject to the following restrictions:
#define CONVEX_HULL_SHAPE_H
#include "btPolyhedralConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "LinearMath/btAlignedObjectArray.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "../../LinearMath/btAlignedObjectArray.h"
///ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices)
///No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices.
///on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash.
///(memory is much slower then the cpu)
class btConvexHullShape : public btPolyhedralConvexShape
ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape
{
btAlignedObjectArray<btPoint3> m_points;
public:
///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive float (x,y,z), the striding defines the number of bytes between each point, in memory.
///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory.
///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint.
///btConvexHullShape make an internal copy of the points.
btConvexHullShape(const float* points=0,int numPoints=0, int stride=sizeof(btPoint3));
btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btPoint3));
void addPoint(const btPoint3& point)
void addPoint(const btPoint3& point);
btPoint3* getPoints()
{
m_points.push_back(point);
return &m_points[0];
}
int getNumPoints()
{
return m_points.size();
}
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;

View File

@@ -15,8 +15,9 @@ subject to the following restrictions:
#include "btConvexShape.h"
btConvexShape::btConvexShape()
: m_localScaling(1.f,1.f,1.f),
: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
m_collisionMargin(CONVEX_DISTANCE_MARGIN)
{
}
@@ -35,35 +36,42 @@ void btConvexShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVec
btScalar margin = getMargin();
for (int i=0;i<3;i++)
{
btVector3 vec(0.f,0.f,0.f);
vec[i] = 1.f;
btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
vec[i] = btScalar(1.);
btVector3 sv = localGetSupportingVertex(vec*trans.getBasis());
btVector3 tmp = trans(sv);
maxAabb[i] = tmp[i]+margin;
vec[i] = -1.f;
vec[i] = btScalar(-1.);
tmp = trans(localGetSupportingVertex(vec*trans.getBasis()));
minAabb[i] = tmp[i]-margin;
}
};
btVector3 btConvexShape::localGetSupportingVertex(const btVector3& vec)const
{
{
#ifndef __SPU__
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
if ( getMargin()!=0.f )
if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
vecnorm.setValue(-1.f,-1.f,-1.f);
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
}
return supVertex;
#else
return btVector3(0,0,0);
#endif //__SPU__
}

View File

@@ -18,11 +18,10 @@ subject to the following restrictions:
#include "btCollisionShape.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include <vector>
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btTransform.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "btCollisionMargin.h"
//todo: get rid of this btConvexCastResult thing!
struct btConvexCastResult;
@@ -31,9 +30,9 @@ struct btConvexCastResult;
/// btConvexShape is an abstract shape interface.
/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface.
/// used in combination with GJK or btConvexCast
class btConvexShape : public btCollisionShape
ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape
{
protected:
//local scaling. collisionMargin is not scaled !
@@ -43,14 +42,27 @@ protected:
btScalar m_collisionMargin;
btScalar m_padding[2];
public:
btConvexShape();
virtual ~btConvexShape()
{
}
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
#ifndef __SPU__
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
//notice that the vectors should be unit length
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
#endif //#ifndef __SPU__
const btVector3& getImplicitShapeDimensions() const
{
@@ -74,12 +86,21 @@ public:
return m_localScaling;
}
const btVector3& getLocalScalingNV() const
{
return m_localScaling;
}
virtual void setMargin(float margin)
virtual void setMargin(btScalar margin)
{
m_collisionMargin = margin;
}
virtual float getMargin() const
virtual btScalar getMargin() const
{
return m_collisionMargin;
}
btScalar getMarginNV() const
{
return m_collisionMargin;
}
@@ -91,12 +112,15 @@ public:
virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
{
assert(0);
(void)penetrationVector;
(void)index;
btAssert(0);
}
};
}
;

View File

@@ -22,6 +22,7 @@ subject to the following restrictions:
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface)
:m_stridingMesh(meshInterface)
{
recalcLocalAabb();
}
@@ -39,14 +40,17 @@ public:
btVector3 m_supportVecLocal;
LocalSupportVertexCallback(const btVector3& supportVecLocal)
: m_supportVertexLocal(0.f,0.f,0.f),
m_maxDot(-1e30f),
: m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)),
m_maxDot(btScalar(-1e30)),
m_supportVecLocal(supportVecLocal)
{
}
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
{
(void)triangleIndex;
(void)partId;
for (int i=0;i<3;i++)
{
btScalar dot = m_supportVecLocal.dot(triangle[i]);
@@ -71,21 +75,21 @@ public:
btVector3 btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
btVector3 supVec(0.f,0.f,0.f);
btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
if (lenSqr < 0.0001f)
if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
float rlen = 1.f / btSqrt(lenSqr );
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
LocalSupportVertexCallback supportCallback(vec);
btVector3 aabbMax(1e30f,1e30f,1e30f);
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
supVec = supportCallback.GetSupportVertexLocal();
@@ -98,7 +102,7 @@ void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargi
{
for (int i=0;i<numVectors;i++)
{
supportVerticesOut[i][3] = -1e30f;
supportVerticesOut[i][3] = btScalar(-1e30);
}
}
@@ -109,7 +113,7 @@ void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargi
{
const btVector3& vec = vectors[j];
LocalSupportVertexCallback supportCallback(vec);
btVector3 aabbMax(1e30f,1e30f,1e30f);
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
supportVerticesOut[j] = supportCallback.GetSupportVertexLocal();
}
@@ -122,12 +126,12 @@ btVector3 btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& v
{
btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
if ( getMargin()!=0.f )
if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
vecnorm.setValue(-1.f,-1.f,-1.f);
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
@@ -157,14 +161,14 @@ int btConvexTriangleMeshShape::getNumEdges() const
return 0;
}
void btConvexTriangleMeshShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const
void btConvexTriangleMeshShape::getEdge(int ,btPoint3& ,btPoint3& ) const
{
assert(0);
btAssert(0);
}
void btConvexTriangleMeshShape::getVertex(int i,btPoint3& vtx) const
void btConvexTriangleMeshShape::getVertex(int ,btPoint3& ) const
{
assert(0);
btAssert(0);
}
int btConvexTriangleMeshShape::getNumPlanes() const
@@ -172,15 +176,15 @@ int btConvexTriangleMeshShape::getNumPlanes() const
return 0;
}
void btConvexTriangleMeshShape::getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
void btConvexTriangleMeshShape::getPlane(btVector3& ,btPoint3& ,int ) const
{
assert(0);
btAssert(0);
}
//not yet
bool btConvexTriangleMeshShape::isInside(const btPoint3& pt,btScalar tolerance) const
bool btConvexTriangleMeshShape::isInside(const btPoint3& ,btScalar ) const
{
assert(0);
btAssert(0);
return false;
}
@@ -189,5 +193,13 @@ bool btConvexTriangleMeshShape::isInside(const btPoint3& pt,btScalar tolerance)
void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling)
{
m_stridingMesh->setScaling(scaling);
recalcLocalAabb();
}
const btVector3& btConvexTriangleMeshShape::getLocalScaling() const
{
return m_stridingMesh->getScaling();
}

View File

@@ -3,9 +3,8 @@
#include "btPolyhedralConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include <vector>
/// btConvexTriangleMeshShape is a convex hull of a triangle mesh. If you just have a point cloud, you can use btConvexHullShape instead.
/// It uses the btStridingMeshInterface instead of a point cloud. This can avoid the duplication of the triangle mesh data.
@@ -40,7 +39,8 @@ public:
virtual bool isInside(const btPoint3& pt,btScalar tolerance) const;
void setLocalScaling(const btVector3& scaling);
virtual void setLocalScaling(const btVector3& scaling);
virtual const btVector3& getLocalScaling() const;
};

View File

@@ -16,23 +16,33 @@ subject to the following restrictions:
#include "LinearMath/btPoint3.h"
btCylinderShape::btCylinderShape (const btVector3& halfExtents)
:btBoxShape(halfExtents)
:btBoxShape(halfExtents),
m_upAxis(1)
{
recalcLocalAabb();
}
btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents)
:btCylinderShape(halfExtents)
{
m_upAxis = 0;
recalcLocalAabb();
}
btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents)
:btCylinderShape(halfExtents)
{
m_upAxis = 2;
recalcLocalAabb();
}
void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
//skip the box 'getAabb'
btPolyhedralConvexShape::getAabb(t,aabbMin,aabbMax);
}
inline btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v)
@@ -46,8 +56,8 @@ const int ZZ = 2;
// extents of the cylinder is: X,Y is for radius, and Z for height
float radius = halfExtents[XX];
float halfHeight = halfExtents[cylinderUpAxis];
btScalar radius = halfExtents[XX];
btScalar halfHeight = halfExtents[cylinderUpAxis];
btVector3 tmp;
@@ -87,8 +97,8 @@ const int YY = 1;
const int ZZ = 2;
float radius = halfExtents[XX];
float halfHeight = halfExtents[cylinderUpAxis];
btScalar radius = halfExtents[XX];
btScalar halfHeight = halfExtents[cylinderUpAxis];
btVector3 tmp;
@@ -124,8 +134,8 @@ const int ZZ = 1;
// extents of the cylinder is: X,Y is for radius, and Z for height
float radius = halfExtents[XX];
float halfHeight = halfExtents[cylinderUpAxis];
btScalar radius = halfExtents[XX];
btScalar halfHeight = halfExtents[cylinderUpAxis];
btVector3 tmp;

View File

@@ -17,22 +17,23 @@ subject to the following restrictions:
#define CYLINDER_MINKOWSKI_H
#include "btBoxShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "LinearMath/btVector3.h"
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "../../LinearMath/btVector3.h"
/// implements cylinder shape interface
class btCylinderShape : public btBoxShape
{
protected:
int m_upAxis;
public:
btCylinderShape (const btVector3& halfExtents);
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
getAabbSlow(t,aabbMin,aabbMax);
}
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -44,12 +45,12 @@ public:
btVector3 supVertex;
supVertex = localGetSupportingVertexWithoutMargin(vec);
if ( getMargin()!=0.f )
if ( getMargin()!=btScalar(0.) )
{
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
vecnorm.setValue(-1.f,-1.f,-1.f);
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
@@ -66,12 +67,12 @@ public:
return CYLINDER_SHAPE_PROXYTYPE;
}
virtual int getUpAxis() const
int getUpAxis() const
{
return 1;
return m_upAxis;
}
virtual float getRadius() const
virtual btScalar getRadius() const
{
return getHalfExtents().getX();
}
@@ -93,17 +94,14 @@ public:
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
virtual int getUpAxis() const
{
return 0;
}
//debugging
virtual char* getName()const
{
return "CylinderX";
}
virtual float getRadius() const
virtual btScalar getRadius() const
{
return getHalfExtents().getY();
}
@@ -128,7 +126,7 @@ public:
return "CylinderZ";
}
virtual float getRadius() const
virtual btScalar getRadius() const
{
return getHalfExtents().getX();
}

View File

@@ -40,9 +40,9 @@ void btEmptyShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aa
}
void btEmptyShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
void btEmptyShape::calculateLocalInertia(btScalar ,btVector3& )
{
assert(0);
btAssert(0);
}

View File

@@ -18,11 +18,10 @@ subject to the following restrictions:
#include "btConcaveShape.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include <vector>
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
#include "../../LinearMath/btVector3.h"
#include "../../LinearMath/btTransform.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "btCollisionMargin.h"

View File

@@ -18,9 +18,66 @@ subject to the following restrictions:
#include "LinearMath/btTransformUtil.h"
btHeightfieldTerrainShape::btHeightfieldTerrainShape()
:m_localScaling(0.f,0.f,0.f)
btHeightfieldTerrainShape::btHeightfieldTerrainShape(int width,int length,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
:m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
m_width(width),
m_length(length),
m_heightfieldDataUnknown(heightfieldData),
m_maxHeight(maxHeight),
m_upAxis(upAxis),
m_useFloatData(useFloatData),
m_flipQuadEdges(flipQuadEdges),
m_useDiamondSubdivision(false)
{
btScalar quantizationMargin = 1.f;
//enlarge the AABB to avoid division by zero when initializing the quantization values
btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
btVector3 halfExtents(0,0,0);
switch (m_upAxis)
{
case 0:
{
halfExtents.setValue(
m_maxHeight,
m_width,
m_length);
break;
}
case 1:
{
halfExtents.setValue(
m_width,
m_maxHeight,
m_length);
break;
};
case 2:
{
halfExtents.setValue(
m_width,
m_length,
m_maxHeight
);
break;
}
default:
{
//need to get valid m_upAxis
btAssert(0);
}
}
halfExtents*= btScalar(0.5);
m_localAabbMin = -halfExtents - clampValue;
m_localAabbMax = halfExtents + clampValue;
btVector3 aabbSize = m_localAabbMax - m_localAabbMin;
}
@@ -32,54 +89,244 @@ btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
/*
aabbMin.setValue(-1e30f,-1e30f,-1e30f);
aabbMax.setValue(1e30f,1e30f,1e30f);
*/
btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5);
btMatrix3x3 abs_b = t.getBasis().absolute();
btPoint3 center = t.getOrigin();
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
abs_b[1].dot(halfExtents),
abs_b[2].dot(halfExtents));
extent += btVector3(getMargin(),getMargin(),getMargin());
aabbMin = center - extent;
aabbMax = center + extent;
}
btScalar btHeightfieldTerrainShape::getHeightFieldValue(int x,int y) const
{
btScalar val = 0.f;
if (m_useFloatData)
{
val = m_heightfieldDataFloat[(y*m_width)+x];
} else
{
//assume unsigned short int
unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_width)+x];
val = heightFieldValue* (m_maxHeight/btScalar(65535));
}
return val;
}
void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
{
btAssert(x>=0);
btAssert(y>=0);
btAssert(x<m_width);
btAssert(y<m_length);
btScalar height = getHeightFieldValue(x,y);
switch (m_upAxis)
{
case 0:
{
vertex.setValue(
height,
(-m_width/2 ) + x,
(-m_length/2 ) + y
);
break;
}
case 1:
{
vertex.setValue(
(-m_width/2 ) + x,
height,
(-m_length/2 ) + y
);
break;
};
case 2:
{
vertex.setValue(
(-m_width/2 ) + x,
(-m_length/2 ) + y,
height
);
break;
}
default:
{
//need to get valid m_upAxis
btAssert(0);
}
}
vertex*=m_localScaling;
}
void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point) const
{
btVector3 clampedPoint(point);
clampedPoint.setMax(m_localAabbMin);
clampedPoint.setMin(m_localAabbMax);
btVector3 v = (clampedPoint );// * m_quantization;
out[0] = (int)(v.getX());
out[1] = (int)(v.getY());
out[2] = (int)(v.getZ());
//correct for
}
void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
(void)callback;
(void)aabbMax;
(void)aabbMin;
btVector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
btScalar radius = halfExtents.length();
btVector3 center = (aabbMax + aabbMin) * 0.5f;
//quantize the aabbMin and aabbMax, and adjust the start/end ranges
int quantizedAabbMin[3];
int quantizedAabbMax[3];
btVector3 localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
btVector3 localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
quantizeWithClamp(quantizedAabbMin, localAabbMin);
quantizeWithClamp(quantizedAabbMax, localAabbMax);
//TODO
//this is where the triangles are generated, given AABB and plane equation (normal/constant)
/*
btVector3 tangentDir0,tangentDir1;
//tangentDir0/tangentDir1 can be precalculated
btPlaneSpace1(m_planeNormal,tangentDir0,tangentDir1);
btVector3 supVertex0,supVertex1;
btVector3 projectedCenter = center - (m_planeNormal.dot(center) - m_planeConstant)*m_planeNormal;
btVector3 triangle[3];
triangle[0] = projectedCenter + tangentDir0*radius + tangentDir1*radius;
triangle[1] = projectedCenter + tangentDir0*radius - tangentDir1*radius;
triangle[2] = projectedCenter - tangentDir0*radius - tangentDir1*radius;
callback->processTriangle(triangle,0,0);
int startX=0;
int endX=m_width-1;
int startJ=0;
int endJ=m_length-1;
triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius;
triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius;
triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius;
switch (m_upAxis)
{
case 0:
{
quantizedAabbMin[1]+=m_width/2-1;
quantizedAabbMax[1]+=m_width/2+1;
quantizedAabbMin[2]+=m_length/2-1;
quantizedAabbMax[2]+=m_length/2+1;
callback->processTriangle(triangle,0,1);
*/
if (quantizedAabbMin[1]>startX)
startX = quantizedAabbMin[1];
if (quantizedAabbMax[1]<endX)
endX = quantizedAabbMax[1];
if (quantizedAabbMin[2]>startJ)
startJ = quantizedAabbMin[2];
if (quantizedAabbMax[2]<endJ)
endJ = quantizedAabbMax[2];
break;
}
case 1:
{
quantizedAabbMin[0]+=m_width/2-1;
quantizedAabbMax[0]+=m_width/2+1;
quantizedAabbMin[2]+=m_length/2-1;
quantizedAabbMax[2]+=m_length/2+1;
if (quantizedAabbMin[0]>startX)
startX = quantizedAabbMin[0];
if (quantizedAabbMax[0]<endX)
endX = quantizedAabbMax[0];
if (quantizedAabbMin[2]>startJ)
startJ = quantizedAabbMin[2];
if (quantizedAabbMax[2]<endJ)
endJ = quantizedAabbMax[2];
break;
};
case 2:
{
quantizedAabbMin[0]+=m_width/2-1;
quantizedAabbMax[0]+=m_width/2+1;
quantizedAabbMin[1]+=m_length/2-1;
quantizedAabbMax[1]+=m_length/2+1;
if (quantizedAabbMin[0]>startX)
startX = quantizedAabbMin[0];
if (quantizedAabbMax[0]<endX)
endX = quantizedAabbMax[0];
if (quantizedAabbMin[1]>startJ)
startJ = quantizedAabbMin[1];
if (quantizedAabbMax[1]<endJ)
endJ = quantizedAabbMax[1];
break;
}
default:
{
//need to get valid m_upAxis
btAssert(0);
}
}
for(int j=startJ; j<endJ; j++)
{
for(int x=startX; x<endX; x++)
{
btVector3 vertices[3];
if (m_flipQuadEdges || (m_useDiamondSubdivision && ((j+x) & 1)))
{
//first triangle
getVertex(x,j,vertices[0]);
getVertex(x+1,j,vertices[1]);
getVertex(x+1,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
//second triangle
getVertex(x,j,vertices[0]);
getVertex(x+1,j+1,vertices[1]);
getVertex(x,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
} else
{
//first triangle
getVertex(x,j,vertices[0]);
getVertex(x,j+1,vertices[1]);
getVertex(x+1,j,vertices[2]);
callback->processTriangle(vertices,x,j);
//second triangle
getVertex(x+1,j,vertices[0]);
getVertex(x,j+1,vertices[1]);
getVertex(x+1,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
}
}
}
}
void btHeightfieldTerrainShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
void btHeightfieldTerrainShape::calculateLocalInertia(btScalar ,btVector3& inertia)
{
//moving concave objects not supported
inertia.setValue(0.f,0.f,0.f);
inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
void btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling)

View File

@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef HEIGHTFIELD_TERRAIN_SHAPE_H
#define HEIGHTFIELD_TERRAIN_SHAPE_H
#include "BulletCollision/CollisionShapes/btConcaveShape.h"
#include "btConcaveShape.h"
///btHeightfieldTerrainShape simulates a 2D heightfield terrain
class btHeightfieldTerrainShape : public btConcaveShape
@@ -25,16 +25,46 @@ protected:
btVector3 m_localAabbMin;
btVector3 m_localAabbMax;
//todo: terrain data
///terrain data
int m_width;
int m_length;
btScalar m_maxHeight;
union
{
unsigned char* m_heightfieldDataUnsignedChar;
btScalar* m_heightfieldDataFloat;
void* m_heightfieldDataUnknown;
};
bool m_useFloatData;
bool m_flipQuadEdges;
bool m_useDiamondSubdivision;
int m_upAxis;
btVector3 m_localScaling;
virtual btScalar getHeightFieldValue(int x,int y) const;
void quantizeWithClamp(int* out, const btVector3& point) const;
void getVertex(int x,int y,btVector3& vertex) const;
inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const
{
bool overlap = true;
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
return overlap;
}
public:
btHeightfieldTerrainShape();
btHeightfieldTerrainShape(int width,int height,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
virtual ~btHeightfieldTerrainShape();
void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
virtual int getShapeType() const
{
return TERRAIN_SHAPE_PROXYTYPE;

View File

@@ -16,7 +16,7 @@ subject to the following restrictions:
#include "btMinkowskiSumShape.h"
btMinkowskiSumShape::btMinkowskiSumShape(btConvexShape* shapeA,btConvexShape* shapeB)
btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB)
:m_shapeA(shapeA),
m_shapeB(shapeB)
{
@@ -43,7 +43,7 @@ void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(cons
float btMinkowskiSumShape::getMargin() const
btScalar btMinkowskiSumShape::getMargin() const
{
return m_shapeA->getMargin() + m_shapeB->getMargin();
}
@@ -51,6 +51,7 @@ float btMinkowskiSumShape::getMargin() const
void btMinkowskiSumShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
assert(0);
(void)mass;
btAssert(0);
inertia.setValue(0,0,0);
}

View File

@@ -17,7 +17,7 @@ subject to the following restrictions:
#define MINKOWSKI_SUM_SHAPE_H
#include "btConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
/// btMinkowskiSumShape represents implicit (getSupportingVertex) based minkowski sum of two convex implicit shapes.
class btMinkowskiSumShape : public btConvexShape
@@ -25,12 +25,12 @@ class btMinkowskiSumShape : public btConvexShape
btTransform m_transA;
btTransform m_transB;
btConvexShape* m_shapeA;
btConvexShape* m_shapeB;
const btConvexShape* m_shapeA;
const btConvexShape* m_shapeB;
public:
btMinkowskiSumShape(btConvexShape* shapeA,btConvexShape* shapeB);
btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB);
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -48,7 +48,7 @@ public:
virtual int getShapeType() const { return MINKOWSKI_SUM_SHAPE_PROXYTYPE; }
virtual float getMargin() const;
virtual btScalar getMargin() const;
const btConvexShape* getShapeA() const { return m_shapeA;}
const btConvexShape* getShapeB() const { return m_shapeB;}

View File

@@ -20,7 +20,7 @@ subject to the following restrictions:
btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres)
:m_inertiaHalfExtents(inertiaHalfExtents)
{
float startMargin = 1e30f;
btScalar startMargin = btScalar(1e30);
m_numSpheres = numSpheres;
for (int i=0;i<m_numSpheres;i++)
@@ -42,17 +42,17 @@ btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,cons
int i;
btVector3 supVec(0,0,0);
btScalar maxDot(-1e30f);
btScalar maxDot(btScalar(-1e30));
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
if (lenSqr < 0.0001f)
if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
float rlen = 1.f / btSqrt(lenSqr );
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
@@ -84,7 +84,7 @@ btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,cons
for (int j=0;j<numVectors;j++)
{
btScalar maxDot(-1e30f);
btScalar maxDot(btScalar(-1e30));
const btVector3& vec = vectors[j];
@@ -126,17 +126,17 @@ void btMultiSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
// getAabb(ident,aabbMin,aabbMax);
btVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* 0.5f;
btVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* btScalar(0.5);
float margin = CONVEX_DISTANCE_MARGIN;
btScalar margin = CONVEX_DISTANCE_MARGIN;
btScalar lx=2.f*(halfExtents[0]+margin);
btScalar ly=2.f*(halfExtents[1]+margin);
btScalar lz=2.f*(halfExtents[2]+margin);
btScalar lx=btScalar(2.)*(halfExtents[0]+margin);
btScalar ly=btScalar(2.)*(halfExtents[1]+margin);
btScalar lz=btScalar(2.)*(halfExtents[2]+margin);
const btScalar x2 = lx*lx;
const btScalar y2 = ly*ly;
const btScalar z2 = lz*lz;
const btScalar scaledmass = mass * 0.08333333f;
const btScalar scaledmass = mass * btScalar(.08333333);
inertia[0] = scaledmass * (y2+z2);
inertia[1] = scaledmass * (x2+z2);

View File

@@ -17,7 +17,7 @@ subject to the following restrictions:
#define MULTI_SPHERE_MINKOWSKI_H
#include "btConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "../BroadphaseCollision/btBroadphaseProxy.h" // for the types
#define MAX_NUM_SPHERES 5
@@ -46,6 +46,20 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
int getSphereCount() const
{
return m_numSpheres;
}
const btVector3& getSpherePosition(int index) const
{
return m_localPositions[index];
}
btScalar getSphereRadius(int index) const
{
return m_radi[index];
}
virtual int getShapeType() const { return MULTI_SPHERE_SHAPE_PROXYTYPE; }

View File

@@ -16,89 +16,373 @@ subject to the following restrictions:
#include "btOptimizedBvh.h"
#include "btStridingMeshInterface.h"
#include "LinearMath/btAabbUtil2.h"
#include "LinearMath/btIDebugDraw.h"
btOptimizedBvh::btOptimizedBvh() :m_rootNode1(0), m_numNodes(0)
btOptimizedBvh::btOptimizedBvh() : m_useQuantization(false),
m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
//m_traversalMode(TRAVERSAL_STACKLESS)
//m_traversalMode(TRAVERSAL_RECURSIVE)
{
}
void btOptimizedBvh::build(btStridingMeshInterface* triangles)
void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax)
{
//int countTriangles = 0;
m_useQuantization = useQuantizedAabbCompression;
// NodeArray triangleNodes;
struct NodeTriangleCallback : public btInternalTriangleIndexCallback
{
NodeArray& m_triangleNodes;
NodeTriangleCallback& operator=(NodeTriangleCallback& other)
{
m_triangleNodes = other.m_triangleNodes;
return *this;
}
NodeTriangleCallback(NodeArray& triangleNodes)
:m_triangleNodes(triangleNodes)
{
}
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
{
btOptimizedBvhNode node;
node.m_aabbMin = btVector3(1e30f,1e30f,1e30f);
node.m_aabbMax = btVector3(-1e30f,-1e30f,-1e30f);
node.m_aabbMin.setMin(triangle[0]);
node.m_aabbMax.setMax(triangle[0]);
node.m_aabbMin.setMin(triangle[1]);
node.m_aabbMax.setMax(triangle[1]);
node.m_aabbMin.setMin(triangle[2]);
node.m_aabbMax.setMax(triangle[2]);
btVector3 aabbMin,aabbMax;
aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
aabbMin.setMin(triangle[0]);
aabbMax.setMax(triangle[0]);
aabbMin.setMin(triangle[1]);
aabbMax.setMax(triangle[1]);
aabbMin.setMin(triangle[2]);
aabbMax.setMax(triangle[2]);
//with quantization?
node.m_aabbMinOrg = aabbMin;
node.m_aabbMaxOrg = aabbMax;
node.m_escapeIndex = -1;
node.m_leftChild = 0;
node.m_rightChild = 0;
//for child nodes
node.m_subPart = partId;
node.m_triangleIndex = triangleIndex;
m_triangleNodes.push_back(node);
}
};
struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback
{
QuantizedNodeArray& m_triangleNodes;
const btOptimizedBvh* m_optimizedTree; // for quantization
QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other)
{
m_triangleNodes = other.m_triangleNodes;
m_optimizedTree = other.m_optimizedTree;
return *this;
}
QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const btOptimizedBvh* tree)
:m_triangleNodes(triangleNodes),m_optimizedTree(tree)
{
}
virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
{
btAssert(partId==0);
//negative indices are reserved for escapeIndex
btAssert(triangleIndex>=0);
btQuantizedBvhNode node;
btVector3 aabbMin,aabbMax;
aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
aabbMin.setMin(triangle[0]);
aabbMax.setMax(triangle[0]);
aabbMin.setMin(triangle[1]);
aabbMax.setMax(triangle[1]);
aabbMin.setMin(triangle[2]);
aabbMax.setMax(triangle[2]);
m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMin[0],aabbMin);
m_optimizedTree->quantizeWithClamp(&node.m_quantizedAabbMax[0],aabbMax);
node.m_escapeIndexOrTriangleIndex = triangleIndex;
m_triangleNodes.push_back(node);
}
};
NodeTriangleCallback callback(m_leafNodes);
btVector3 aabbMin(-1e30f,-1e30f,-1e30f);
btVector3 aabbMax(1e30f,1e30f,1e30f);
int numLeafNodes = 0;
triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax);
if (m_useQuantization)
{
//now we have an array of leafnodes in m_leafNodes
//initialize quantization values
setQuantizationValues(bvhAabbMin,bvhAabbMax);
QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this);
triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax);
//now we have an array of leafnodes in m_leafNodes
numLeafNodes = m_quantizedLeafNodes.size();
m_quantizedContiguousNodes.resize(2*numLeafNodes);
} else
{
NodeTriangleCallback callback(m_leafNodes);
btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax);
//now we have an array of leafnodes in m_leafNodes
numLeafNodes = m_leafNodes.size();
m_contiguousNodes.resize(2*numLeafNodes);
}
m_contiguousNodes = new btOptimizedBvhNode[2*m_leafNodes.size()];
m_curNodeIndex = 0;
m_rootNode1 = buildTree(m_leafNodes,0,m_leafNodes.size());
buildTree(0,numLeafNodes);
///create the leafnodes first
// btOptimizedBvhNode* leafNodes = new btOptimizedBvhNode;
///if the entire tree is small then subtree size, we need to create a header info for the tree
if(m_useQuantization && !m_SubtreeHeaders.size())
{
btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]);
subtree.m_rootNodeIndex = 0;
subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
}
}
void btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax)
{
//incrementally initialize quantization values
btAssert(m_useQuantization);
btAssert(aabbMin.getX() > m_bvhAabbMin.getX());
btAssert(aabbMin.getY() > m_bvhAabbMin.getY());
btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ());
btAssert(aabbMax.getX() < m_bvhAabbMax.getX());
btAssert(aabbMax.getY() < m_bvhAabbMax.getY());
btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ());
///we should update all quantization values, using updateBvhNodes(meshInterface);
///but we only update chunks that overlap the given aabb
unsigned short quantizedQueryAabbMin[3];
unsigned short quantizedQueryAabbMax[3];
quantizeWithClamp(&quantizedQueryAabbMin[0],aabbMin);
quantizeWithClamp(&quantizedQueryAabbMax[0],aabbMax);
int i;
for (i=0;i<this->m_SubtreeHeaders.size();i++)
{
btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
if (overlap)
{
updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i);
subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]);
}
}
}
///just for debugging, to visualize the individual patches/subtrees
#ifdef DEBUG_PATCH_COLORS
btVector3 color[4]=
{
btVector3(255,0,0),
btVector3(0,255,0),
btVector3(0,0,255),
btVector3(0,255,255)
};
#endif //DEBUG_PATCH_COLORS
void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index)
{
(void)index;
btAssert(m_useQuantization);
int nodeSubPart=0;
//get access info to trianglemesh data
const unsigned char *vertexbase;
int numverts;
PHY_ScalarType type;
int stride;
const unsigned char *indexbase;
int indexstride;
int numfaces;
PHY_ScalarType indicestype;
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart);
btVector3 triangleVerts[3];
btVector3 aabbMin,aabbMax;
const btVector3& meshScaling = meshInterface->getScaling();
int i;
for (i=endNode-1;i>=firstNode;i--)
{
btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i];
if (curNode.isLeafNode())
{
//recalc aabb from triangle data
int nodeTriangleIndex = curNode.getTriangleIndex();
//triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts,
int* gfxbase = (int*)(indexbase+nodeTriangleIndex*indexstride);
for (int j=2;j>=0;j--)
{
int graphicsindex = gfxbase[j];
btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
#ifdef DEBUG_PATCH_COLORS
btVector3 mycolor = color[index&3];
graphicsbase[8] = mycolor.getX();
graphicsbase[9] = mycolor.getY();
graphicsbase[10] = mycolor.getZ();
#endif //DEBUG_PATCH_COLORS
triangleVerts[j] = btVector3(
graphicsbase[0]*meshScaling.getX(),
graphicsbase[1]*meshScaling.getY(),
graphicsbase[2]*meshScaling.getZ());
}
aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
aabbMin.setMin(triangleVerts[0]);
aabbMax.setMax(triangleVerts[0]);
aabbMin.setMin(triangleVerts[1]);
aabbMax.setMax(triangleVerts[1]);
aabbMin.setMin(triangleVerts[2]);
aabbMax.setMax(triangleVerts[2]);
quantizeWithClamp(&curNode.m_quantizedAabbMin[0],aabbMin);
quantizeWithClamp(&curNode.m_quantizedAabbMax[0],aabbMax);
} else
{
//combine aabb from both children
btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1];
btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] :
&m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()];
{
for (int i=0;i<3;i++)
{
curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i];
if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i])
curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i];
curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i];
if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i])
curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i];
}
}
}
}
meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
}
void btOptimizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin)
{
//enlarge the AABB to avoid division by zero when initializing the quantization values
btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
m_bvhAabbMin = bvhAabbMin - clampValue;
m_bvhAabbMax = bvhAabbMax + clampValue;
btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
m_bvhQuantization = btVector3(btScalar(65535.0),btScalar(65535.0),btScalar(65535.0)) / aabbSize;
}
void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface)
{
if (m_useQuantization)
{
//calculate new aabb
btVector3 aabbMin,aabbMax;
meshInterface->calculateAabbBruteForce(aabbMin,aabbMax);
setQuantizationValues(aabbMin,aabbMax);
updateBvhNodes(meshInterface,0,m_curNodeIndex,0);
///now update all subtree headers
int i;
for (i=0;i<m_SubtreeHeaders.size();i++)
{
btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]);
}
} else
{
}
}
btOptimizedBvh::~btOptimizedBvh()
{
if (m_contiguousNodes)
delete []m_contiguousNodes;
}
btOptimizedBvhNode* btOptimizedBvh::buildTree (NodeArray& leafNodes,int startIndex,int endIndex)
#ifdef DEBUG_TREE_BUILDING
int gStackDepth = 0;
int gMaxStackDepth = 0;
#endif //DEBUG_TREE_BUILDING
void btOptimizedBvh::buildTree (int startIndex,int endIndex)
{
btOptimizedBvhNode* internalNode;
#ifdef DEBUG_TREE_BUILDING
gStackDepth++;
if (gStackDepth > gMaxStackDepth)
gMaxStackDepth = gStackDepth;
#endif //DEBUG_TREE_BUILDING
int splitAxis, splitIndex, i;
int numIndices =endIndex-startIndex;
@@ -108,96 +392,172 @@ btOptimizedBvhNode* btOptimizedBvh::buildTree (NodeArray& leafNodes,int startInd
if (numIndices==1)
{
return new (&m_contiguousNodes[m_curNodeIndex++]) btOptimizedBvhNode(leafNodes[startIndex]);
#ifdef DEBUG_TREE_BUILDING
gStackDepth--;
#endif //DEBUG_TREE_BUILDING
assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex);
m_curNodeIndex++;
return;
}
//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
splitAxis = calcSplittingAxis(leafNodes,startIndex,endIndex);
splitAxis = calcSplittingAxis(startIndex,endIndex);
splitIndex = sortAndCalcSplittingIndex(leafNodes,startIndex,endIndex,splitAxis);
splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis);
internalNode = &m_contiguousNodes[m_curNodeIndex++];
int internalNodeIndex = m_curNodeIndex;
internalNode->m_aabbMax.setValue(-1e30f,-1e30f,-1e30f);
internalNode->m_aabbMin.setValue(1e30f,1e30f,1e30f);
setInternalNodeAabbMax(m_curNodeIndex,btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)));
setInternalNodeAabbMin(m_curNodeIndex,btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30)));
for (i=startIndex;i<endIndex;i++)
{
internalNode->m_aabbMax.setMax(leafNodes[i].m_aabbMax);
internalNode->m_aabbMin.setMin(leafNodes[i].m_aabbMin);
mergeInternalNodeAabb(m_curNodeIndex,getAabbMin(i),getAabbMax(i));
}
m_curNodeIndex++;
//internalNode->m_escapeIndex;
internalNode->m_leftChild = buildTree(leafNodes,startIndex,splitIndex);
internalNode->m_rightChild = buildTree(leafNodes,splitIndex,endIndex);
int leftChildNodexIndex = m_curNodeIndex;
//build left child tree
buildTree(startIndex,splitIndex);
int rightChildNodexIndex = m_curNodeIndex;
//build right child tree
buildTree(splitIndex,endIndex);
#ifdef DEBUG_TREE_BUILDING
gStackDepth--;
#endif //DEBUG_TREE_BUILDING
int escapeIndex = m_curNodeIndex - curIndex;
if (m_useQuantization)
{
//escapeIndex is the number of nodes of this subtree
const int sizeQuantizedNode =sizeof(btQuantizedBvhNode);
const int treeSizeInBytes = escapeIndex * sizeQuantizedNode;
if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES)
{
updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
}
}
setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex);
internalNode->m_escapeIndex = m_curNodeIndex - curIndex;
return internalNode;
}
int btOptimizedBvh::sortAndCalcSplittingIndex(NodeArray& leafNodes,int startIndex,int endIndex,int splitAxis)
void btOptimizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex)
{
btAssert(m_useQuantization);
btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex];
int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex();
int leftSubTreeSizeInBytes = leftSubTreeSize * sizeof(btQuantizedBvhNode);
btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex];
int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex();
int rightSubTreeSizeInBytes = rightSubTreeSize * sizeof(btQuantizedBvhNode);
if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
{
btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
subtree.setAabbFromQuantizeNode(leftChildNode);
subtree.m_rootNodeIndex = leftChildNodexIndex;
subtree.m_subtreeSize = leftSubTreeSize;
}
if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
{
btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
subtree.setAabbFromQuantizeNode(rightChildNode);
subtree.m_rootNodeIndex = rightChildNodexIndex;
subtree.m_subtreeSize = rightSubTreeSize;
}
}
int btOptimizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis)
{
int i;
int splitIndex =startIndex;
int numIndices = endIndex - startIndex;
float splitValue;
btScalar splitValue;
btVector3 means(0.f,0.f,0.f);
btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
for (i=startIndex;i<endIndex;i++)
{
btVector3 center = 0.5f*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
means+=center;
}
means *= (1.f/(float)numIndices);
means *= (btScalar(1.)/(btScalar)numIndices);
splitValue = means[splitAxis];
//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
for (i=startIndex;i<endIndex;i++)
{
btVector3 center = 0.5f*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
if (center[splitAxis] > splitValue)
{
//swap
btOptimizedBvhNode tmp = leafNodes[i];
leafNodes[i] = leafNodes[splitIndex];
leafNodes[splitIndex] = tmp;
swapLeafNodes(i,splitIndex);
splitIndex++;
}
}
if ((splitIndex==startIndex) || (splitIndex == (endIndex-1)))
//if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
//otherwise the tree-building might fail due to stack-overflows in certain cases.
//unbalanced1 is unsafe: it can cause stack overflows
//bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
//unbalanced2 should work too: always use center (perfect balanced trees)
//bool unbalanced2 = true;
//this should be safe too:
int rangeBalancedIndices = numIndices/3;
bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
if (unbalanced)
{
splitIndex = startIndex+ (numIndices>>1);
}
bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
btAssert(!unbal);
return splitIndex;
}
int btOptimizedBvh::calcSplittingAxis(NodeArray& leafNodes,int startIndex,int endIndex)
int btOptimizedBvh::calcSplittingAxis(int startIndex,int endIndex)
{
int i;
btVector3 means(0.f,0.f,0.f);
btVector3 variance(0.f,0.f,0.f);
btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
int numIndices = endIndex-startIndex;
for (i=startIndex;i<endIndex;i++)
{
btVector3 center = 0.5f*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
means+=center;
}
means *= (1.f/(float)numIndices);
means *= (btScalar(1.)/(btScalar)numIndices);
for (i=startIndex;i<endIndex;i++)
{
btVector3 center = 0.5f*(leafNodes[i].m_aabbMax+leafNodes[i].m_aabbMin);
btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
btVector3 diff2 = center-means;
diff2 = diff2 * diff2;
variance += diff2;
}
variance *= (1.f/ ((float)numIndices-1) );
variance *= (btScalar(1.)/ ((btScalar)numIndices-1) );
return variance.maxAxis();
}
@@ -208,11 +568,83 @@ void btOptimizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallb
{
//either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
//walkTree(m_rootNode1,nodeCallback,aabbMin,aabbMax);
walkStacklessTree(m_rootNode1,nodeCallback,aabbMin,aabbMax);
if (m_useQuantization)
{
///quantize query AABB
unsigned short int quantizedQueryAabbMin[3];
unsigned short int quantizedQueryAabbMax[3];
quantizeWithClamp(quantizedQueryAabbMin,aabbMin);
quantizeWithClamp(quantizedQueryAabbMax,aabbMax);
switch (m_traversalMode)
{
case TRAVERSAL_STACKLESS:
walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,0,m_curNodeIndex);
break;
case TRAVERSAL_STACKLESS_CACHE_FRIENDLY:
walkStacklessQuantizedTreeCacheFriendly(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
break;
case TRAVERSAL_RECURSIVE:
{
const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[0];
walkRecursiveQuantizedTreeAgainstQueryAabb(rootNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
}
break;
default:
//unsupported
btAssert(0);
}
} else
{
walkStacklessTree(nodeCallback,aabbMin,aabbMax);
}
}
int maxIterations = 0;
void btOptimizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
btAssert(!m_useQuantization);
const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
int escapeIndex, curIndex = 0;
int walkIterations = 0;
bool aabbOverlap, isLeafNode;
while (curIndex < m_curNodeIndex)
{
//catch bugs in tree data
assert (walkIterations < m_curNodeIndex);
walkIterations++;
aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
isLeafNode = rootNode->m_escapeIndex == -1;
if (isLeafNode && aabbOverlap)
{
nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
}
if (aabbOverlap || isLeafNode)
{
rootNode++;
curIndex++;
} else
{
escapeIndex = rootNode->m_escapeIndex;
rootNode += escapeIndex;
curIndex += escapeIndex;
}
}
if (maxIterations < walkIterations)
maxIterations = walkIterations;
}
/*
///this was the original recursive traversal, before we optimized towards stackless traversal
void btOptimizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
@@ -230,27 +662,82 @@ void btOptimizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback
}
}
*/
int maxIterations = 0;
void btOptimizedBvh::walkStacklessTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
void btOptimizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
{
int escapeIndex, curIndex = 0;
int walkIterations = 0;
btAssert(m_useQuantization);
bool aabbOverlap, isLeafNode;
while (curIndex < m_curNodeIndex)
aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax);
isLeafNode = currentNode->isLeafNode();
if (aabbOverlap)
{
if (isLeafNode)
{
nodeCallback->processNode(0,currentNode->getTriangleIndex());
} else
{
//process left and right children
const btQuantizedBvhNode* leftChildNode = currentNode+1;
walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex();
walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
}
}
}
void btOptimizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const
{
btAssert(m_useQuantization);
int curIndex = startNodeIndex;
int walkIterations = 0;
int subTreeSize = endNodeIndex - startNodeIndex;
const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
int escapeIndex;
bool aabbOverlap, isLeafNode;
while (curIndex < endNodeIndex)
{
//#define VISUALLY_ANALYZE_BVH 1
#ifdef VISUALLY_ANALYZE_BVH
//some code snippet to debugDraw aabb, to visually analyze bvh structure
static int drawPatch = 0;
//need some global access to a debugDrawer
extern btIDebugDraw* debugDrawerPtr;
if (curIndex==drawPatch)
{
btVector3 aabbMin,aabbMax;
aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
btVector3 color(1,0,0);
debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
}
#endif//VISUALLY_ANALYZE_BVH
//catch bugs in tree data
assert (walkIterations < m_curNodeIndex);
assert (walkIterations < subTreeSize);
walkIterations++;
aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild);
aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
isLeafNode = rootNode->isLeafNode();
if (isLeafNode && aabbOverlap)
{
nodeCallback->processNode(rootNode);
nodeCallback->processNode(0,rootNode->getTriangleIndex());
}
if (aabbOverlap || isLeafNode)
@@ -259,21 +746,100 @@ void btOptimizedBvh::walkStacklessTree(btOptimizedBvhNode* rootNode,btNodeOverla
curIndex++;
} else
{
escapeIndex = rootNode->m_escapeIndex;
escapeIndex = rootNode->getEscapeIndex();
rootNode += escapeIndex;
curIndex += escapeIndex;
}
}
if (maxIterations < walkIterations)
maxIterations = walkIterations;
}
//This traversal can be called from Playstation 3 SPU
void btOptimizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
{
btAssert(m_useQuantization);
int i;
for (i=0;i<this->m_SubtreeHeaders.size();i++)
{
const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
bool overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
if (overlap)
{
walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
subtree.m_rootNodeIndex,
subtree.m_rootNodeIndex+subtree.m_subtreeSize);
}
}
}
void btOptimizedBvh::reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
(void)nodeCallback;
(void)aabbMin;
(void)aabbMax;
//not yet, please use aabb
btAssert(0);
}
void btOptimizedBvh::quantizeWithClamp(unsigned short* out, const btVector3& point) const
{
btAssert(m_useQuantization);
btVector3 clampedPoint(point);
clampedPoint.setMax(m_bvhAabbMin);
clampedPoint.setMin(m_bvhAabbMax);
btVector3 v = (clampedPoint - m_bvhAabbMin) * m_bvhQuantization;
out[0] = (unsigned short)(v.getX()+0.5f);
out[1] = (unsigned short)(v.getY()+0.5f);
out[2] = (unsigned short)(v.getZ()+0.5f);
}
btVector3 btOptimizedBvh::unQuantize(const unsigned short* vecIn) const
{
btVector3 vecOut;
vecOut.setValue(
(btScalar)(vecIn[0]) / (m_bvhQuantization.getX()),
(btScalar)(vecIn[1]) / (m_bvhQuantization.getY()),
(btScalar)(vecIn[2]) / (m_bvhQuantization.getZ()));
vecOut += m_bvhAabbMin;
return vecOut;
}
void btOptimizedBvh::swapLeafNodes(int i,int splitIndex)
{
if (m_useQuantization)
{
btQuantizedBvhNode tmp = m_quantizedLeafNodes[i];
m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex];
m_quantizedLeafNodes[splitIndex] = tmp;
} else
{
btOptimizedBvhNode tmp = m_leafNodes[i];
m_leafNodes[i] = m_leafNodes[splitIndex];
m_leafNodes[splitIndex] = tmp;
}
}
void btOptimizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex)
{
if (m_useQuantization)
{
m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex];
} else
{
m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex];
}
}

View File

@@ -17,103 +17,313 @@ subject to the following restrictions:
#define OPTIMIZED_BVH_H
#include "LinearMath/btVector3.h"
#include "../../LinearMath/btVector3.h"
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp
#include <vector>
class btStridingMeshInterface;
/// btOptimizedBvhNode contains both internal and leaf node information.
/// It hasn't been optimized yet for storage. Some obvious optimizations are:
/// Removal of the pointers (can already be done, they are not used for traversal)
/// and storing aabbmin/max as quantized integers.
/// 'subpart' doesn't need an integer either. It allows to re-use graphics triangle
/// meshes stored in a non-uniform way (like batches/subparts of triangle-fans
ATTRIBUTE_ALIGNED16 (struct btOptimizedBvhNode)
//Note: currently we have 16 bytes per quantized node
#define MAX_SUBTREE_SIZE_IN_BYTES 2048
///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode
{
//12 bytes
unsigned short int m_quantizedAabbMin[3];
unsigned short int m_quantizedAabbMax[3];
//4 bytes
int m_escapeIndexOrTriangleIndex;
btVector3 m_aabbMin;
btVector3 m_aabbMax;
bool isLeafNode() const
{
//skipindex is negative (internal node), triangleindex >=0 (leafnode)
return (m_escapeIndexOrTriangleIndex >= 0);
}
int getEscapeIndex() const
{
btAssert(!isLeafNode());
return -m_escapeIndexOrTriangleIndex;
}
int getTriangleIndex() const
{
btAssert(isLeafNode());
return m_escapeIndexOrTriangleIndex;
}
}
;
//these 2 pointers are obsolete, the stackless traversal just uses the escape index
btOptimizedBvhNode* m_leftChild;
btOptimizedBvhNode* m_rightChild;
/// btOptimizedBvhNode contains both internal and leaf node information.
/// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes.
ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode
{
//32 bytes
btVector3 m_aabbMinOrg;
btVector3 m_aabbMaxOrg;
//4
int m_escapeIndex;
//8
//for child nodes
int m_subPart;
int m_triangleIndex;
int m_padding[5];//bad, due to alignment
};
///btBvhSubtreeInfo provides info to gather a subtree of limited size
ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo
{
public:
//12 bytes
unsigned short int m_quantizedAabbMin[3];
unsigned short int m_quantizedAabbMax[3];
//4 bytes, points to the root of the subtree
int m_rootNodeIndex;
//4 bytes
int m_subtreeSize;
int m_padding[3];
void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode)
{
m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0];
m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1];
m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2];
m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0];
m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1];
m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2];
}
}
;
class btNodeOverlapCallback
{
public:
virtual ~btNodeOverlapCallback() {};
virtual void processNode(const btOptimizedBvhNode* node) = 0;
virtual void processNode(int subPart, int triangleIndex) = 0;
};
#include "LinearMath/btAlignedAllocator.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "../../LinearMath/btAlignedAllocator.h"
#include "../../LinearMath/btAlignedObjectArray.h"
//typedef std::vector< unsigned , allocator_type > container_type;
const unsigned size = (1 << 20);
typedef btAlignedAllocator< btOptimizedBvhNode , size > allocator_type;
//typedef btAlignedObjectArray<btOptimizedBvhNode, allocator_type> NodeArray;
///for code readability:
typedef btAlignedObjectArray<btOptimizedBvhNode> NodeArray;
typedef btAlignedObjectArray<btQuantizedBvhNode> QuantizedNodeArray;
typedef btAlignedObjectArray<btBvhSubtreeInfo> BvhSubtreeInfoArray;
///OptimizedBvh store an AABB tree that can be quickly traversed on CPU (and SPU,GPU in future)
class btOptimizedBvh
ATTRIBUTE_ALIGNED16(class) btOptimizedBvh
{
NodeArray m_leafNodes;
NodeArray m_contiguousNodes;
btOptimizedBvhNode* m_rootNode1;
QuantizedNodeArray m_quantizedLeafNodes;
QuantizedNodeArray m_quantizedContiguousNodes;
btOptimizedBvhNode* m_contiguousNodes;
int m_curNodeIndex;
int m_numNodes;
//quantization data
bool m_useQuantization;
btVector3 m_bvhAabbMin;
btVector3 m_bvhAabbMax;
btVector3 m_bvhQuantization;
enum btTraversalMode
{
TRAVERSAL_STACKLESS = 0,
TRAVERSAL_STACKLESS_CACHE_FRIENDLY,
TRAVERSAL_RECURSIVE
};
btTraversalMode m_traversalMode;
BvhSubtreeInfoArray m_SubtreeHeaders;
///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!)
///this might be refactored into a virtual, it is usually not calculated at run-time
void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin)
{
if (m_useQuantization)
{
quantizeWithClamp(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin);
} else
{
m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin;
}
}
void setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax)
{
if (m_useQuantization)
{
quantizeWithClamp(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax);
} else
{
m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax;
}
}
btVector3 getAabbMin(int nodeIndex) const
{
if (m_useQuantization)
{
return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]);
}
//non-quantized
return m_leafNodes[nodeIndex].m_aabbMinOrg;
}
btVector3 getAabbMax(int nodeIndex) const
{
if (m_useQuantization)
{
return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]);
}
//non-quantized
return m_leafNodes[nodeIndex].m_aabbMaxOrg;
}
void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0));
void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex)
{
if (m_useQuantization)
{
m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex;
}
else
{
m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex;
}
}
void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax)
{
if (m_useQuantization)
{
unsigned short int quantizedAabbMin[3];
unsigned short int quantizedAabbMax[3];
quantizeWithClamp(quantizedAabbMin,newAabbMin);
quantizeWithClamp(quantizedAabbMax,newAabbMax);
for (int i=0;i<3;i++)
{
if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i])
m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i];
if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i])
m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i];
}
} else
{
//non-quantized
m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin);
m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax);
}
}
void swapLeafNodes(int firstIndex,int secondIndex);
void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex);
protected:
void buildTree (int startIndex,int endIndex);
int calcSplittingAxis(int startIndex,int endIndex);
int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis);
void walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const;
///tree traversal designed for small-memory processors like PS3 SPU
void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const;
inline bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
{
bool overlap = true;
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
return overlap;
}
void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex);
public:
btOptimizedBvh();
virtual ~btOptimizedBvh();
void build(btStridingMeshInterface* triangles);
btOptimizedBvhNode* buildTree (NodeArray& leafNodes,int startIndex,int endIndex);
int calcSplittingAxis(NodeArray& leafNodes,int startIndex,int endIndex);
int sortAndCalcSplittingIndex(NodeArray& leafNodes,int startIndex,int endIndex,int splitAxis);
void walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void walkStacklessTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
//OptimizedBvhNode* GetRootNode() { return m_rootNode1;}
int getNumNodes() { return m_numNodes;}
void build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax);
void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void reportSphereOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
void quantizeWithClamp(unsigned short* out, const btVector3& point) const;
btVector3 unQuantize(const unsigned short* vecIn) const;
};
///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees.
void setTraversalMode(btTraversalMode traversalMode)
{
m_traversalMode = traversalMode;
}
void refit(btStridingMeshInterface* triangles);
void refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax);
void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index);
QuantizedNodeArray& getQuantizedNodeArray()
{
return m_quantizedContiguousNodes;
}
BvhSubtreeInfoArray& getSubtreeInfoArray()
{
return m_SubtreeHeaders;
}
}
;
#endif //OPTIMIZED_BVH_H

View File

@@ -16,7 +16,10 @@ subject to the following restrictions:
#include <BulletCollision/CollisionShapes/btPolyhedralConvexShape.h>
btPolyhedralConvexShape::btPolyhedralConvexShape()
:m_optionalHull(0)
:m_localAabbMin(1,1,1),
m_localAabbMax(-1,-1,-1),
m_isLocalAabbValid(false),
m_optionalHull(0)
{
}
@@ -28,16 +31,16 @@ btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const b
int i;
btVector3 supVec(0,0,0);
btScalar maxDot(-1e30f);
btScalar maxDot(btScalar(-1e30));
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
if (lenSqr < 0.0001f)
if (lenSqr < btScalar(0.0001))
{
vec.setValue(1,0,0);
} else
{
float rlen = 1.f / btSqrt(lenSqr );
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
@@ -68,7 +71,7 @@ void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(
for (i=0;i<numVectors;i++)
{
supportVerticesOut[i][3] = -1e30f;
supportVerticesOut[i][3] = btScalar(-1e30);
}
for (int j=0;j<numVectors;j++)
@@ -96,23 +99,50 @@ void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& ine
{
//not yet, return box inertia
float margin = getMargin();
btScalar margin = getMargin();
btTransform ident;
ident.setIdentity();
btVector3 aabbMin,aabbMax;
getAabb(ident,aabbMin,aabbMax);
btVector3 halfExtents = (aabbMax-aabbMin)*0.5f;
btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
btScalar lx=2.f*(halfExtents.x()+margin);
btScalar ly=2.f*(halfExtents.y()+margin);
btScalar lz=2.f*(halfExtents.z()+margin);
btScalar lx=btScalar(2.)*(halfExtents.x()+margin);
btScalar ly=btScalar(2.)*(halfExtents.y()+margin);
btScalar lz=btScalar(2.)*(halfExtents.z()+margin);
const btScalar x2 = lx*lx;
const btScalar y2 = ly*ly;
const btScalar z2 = lz*lz;
const btScalar scaledmass = mass * 0.08333333f;
const btScalar scaledmass = mass * btScalar(0.08333333);
inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
}
void btPolyhedralConvexShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{
getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin());
}
void btPolyhedralConvexShape::recalcLocalAabb()
{
m_isLocalAabbValid = true;
for (int i=0;i<3;i++)
{
btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
vec[i] = btScalar(1.);
btVector3 tmp = localGetSupportingVertex(vec);
m_localAabbMax[i] = tmp[i]+m_collisionMargin;
vec[i] = btScalar(-1.);
tmp = localGetSupportingVertex(vec);
m_localAabbMin[i] = tmp[i]-m_collisionMargin;
}
}

View File

@@ -16,15 +16,20 @@ subject to the following restrictions:
#ifndef BU_SHAPE
#define BU_SHAPE
#include <LinearMath/btPoint3.h>
#include <LinearMath/btMatrix3x3.h>
#include <BulletCollision/CollisionShapes/btConvexShape.h>
#include "../../LinearMath/btPoint3.h"
#include "../../LinearMath/btMatrix3x3.h"
#include "btConvexShape.h"
///PolyhedralConvexShape is an interface class for feature based (vertex/edge/face) convex shapes.
class btPolyhedralConvexShape : public btConvexShape
{
protected:
btVector3 m_localAabbMin;
btVector3 m_localAabbMax;
bool m_isLocalAabbValid;
public:
btPolyhedralConvexShape();
@@ -36,6 +41,39 @@ public:
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia);
inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const
{
//lazy evaluation of local aabb
btAssert(m_isLocalAabbValid);
btAssert(m_localAabbMin.getX() <= m_localAabbMax.getX());
btAssert(m_localAabbMin.getY() <= m_localAabbMax.getY());
btAssert(m_localAabbMin.getZ() <= m_localAabbMax.getZ());
btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
btPoint3 center = trans(localCenter);
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
abs_b[1].dot(localHalfExtents),
abs_b[2].dot(localHalfExtents));
extent += btVector3(margin,margin,margin);
aabbMin = center - extent;
aabbMax = center + extent;
}
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
void recalcLocalAabb();
virtual int getNumVertices() const = 0 ;
virtual int getNumEdges() const = 0;

View File

@@ -26,14 +26,17 @@ btSphereShape ::btSphereShape (btScalar radius)
btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
return btVector3(0.f,0.f,0.f);
(void)vec;
return btVector3(btScalar(0.),btScalar(0.),btScalar(0.));
}
void btSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
{
(void)vectors;
for (int i=0;i<numVectors;i++)
{
supportVerticesOut[i].setValue(0.f,0.f,0.f);
supportVerticesOut[i].setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
}
@@ -46,7 +49,7 @@ btVector3 btSphereShape::localGetSupportingVertex(const btVector3& vec)const
btVector3 vecnorm = vec;
if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
{
vecnorm.setValue(-1.f,-1.f,-1.f);
vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
}
vecnorm.normalize();
supVertex+= getMargin() * vecnorm;
@@ -67,8 +70,8 @@ void btSphereShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& a
void btSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia)
{
btScalar elem = 0.4f * mass * getMargin()*getMargin();
inertia[0] = inertia[1] = inertia[2] = elem;
btScalar elem = btScalar(0.4) * mass * getMargin()*getMargin();
inertia.setValue(elem,elem,elem);
}

Some files were not shown because too many files have changed in this diff Show More