resolved conflict state with HEAD r14096
blenderbuttons still bad not let this compile
This commit is contained in:
@@ -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} ")
|
||||
|
||||
|
||||
9
Makefile
9
Makefile
@@ -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
|
||||
|
||||
53
SConstruct
53
SConstruct
@@ -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
|
||||
|
||||
@@ -19,3 +19,4 @@ Polish:pl_PL
|
||||
Romanian:ro
|
||||
Arabic:ar
|
||||
Bulgarian:bg
|
||||
Greek:el
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
11
extern/CMakeLists.txt
vendored
@@ -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
4
extern/Makefile
vendored
@@ -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
11
extern/SConscript
vendored
@@ -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
6
extern/bFTGL/include/FTGL.h
vendored
Executable file → Normal 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
|
||||
|
||||
8
extern/bFTGL/src/FTVectoriser.cpp
vendored
8
extern/bFTGL/src/FTVectoriser.cpp
vendored
@@ -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)
|
||||
|
||||
3
extern/bFTGL/src/Makefile
vendored
3
extern/bFTGL/src/Makefile
vendored
@@ -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
26
extern/binreloc/CMakeLists.txt
vendored
Normal 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
37
extern/binreloc/Makefile
vendored
Normal 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
13
extern/binreloc/SConscript
vendored
Normal 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
766
extern/binreloc/binreloc.c
vendored
Normal 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
80
extern/binreloc/include/binreloc.h
vendored
Normal 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__ */
|
||||
18
extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj
vendored
18
extern/bullet2/make/msvc_7_0/Bullet_vc7.vcproj
vendored
@@ -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
37
extern/bullet2/src/Bullet-C-Api.h
vendored
Normal 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
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
@@ -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.);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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.);
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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.);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
146
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
vendored
Normal file
146
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
vendored
Normal 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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
60
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
vendored
Normal file
60
extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
vendored
Normal 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
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ subject to the following restrictions:
|
||||
|
||||
#include "btConcaveShape.h"
|
||||
|
||||
btConcaveShape::btConcaveShape() : m_collisionMargin(0.f)
|
||||
btConcaveShape::btConcaveShape() : m_collisionMargin(btScalar(0.))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user