Merge branch 'development'

This commit is contained in:
DavidWyand-GG 2013-11-13 16:09:40 -05:00
commit d5beea41c8
710 changed files with 92636 additions and 8637 deletions

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
Copyright (c) 2003-2010 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.
@ -13,5 +13,6 @@ subject to the following restrictions:
*/
Free for commercial use, but please mail bullet@erwincoumans.com to report projects, and join the forum at
www.continuousphysics.com/Bullet/phpBB2
Free for commercial use, please report projects in the forum at http://www.bulletphysics.org
In case you want to display a Bullet logo in your software: you can download the Bullet logo in various vector formats and high resolution at the download section in http://bullet.googlecode.com

Binary file not shown.

View file

@ -1,15 +1,302 @@
cmake_minimum_required(VERSION 2.4)
cmake_minimum_required(VERSION 2.4.3)
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
#this line has to appear before 'PROJECT' in order to be able to disable incremental linking
SET(MSVC_INCREMENTAL_DEFAULT ON)
PROJECT(BULLET_PHYSICS)
SET(BULLET_VERSION 2.75)
SET(BULLET_VERSION 2.81)
IF(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
ENDIF(COMMAND cmake_policy)
IF (NOT CMAKE_BUILD_TYPE)
# SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_BUILD_TYPE "Release")
ENDIF (NOT CMAKE_BUILD_TYPE)
# string (REPLACE "/D_WINDOWS" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
remove_definitions(-D_WINDOWS )
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
#MESSAGE("CMAKE_CXX_FLAGS_DEBUG="+${CMAKE_CXX_FLAGS_DEBUG})
OPTION(USE_DOUBLE_PRECISION "Use double precision" OFF)
OPTION(USE_GRAPHICAL_BENCHMARK "Use Graphical Benchmark" ON)
OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" OFF)
OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF)
OPTION(USE_CUSTOM_VECTOR_MATH "Use custom vectormath library" OFF)
IF (USE_CUSTOM_VECTOR_MATH)
ADD_DEFINITIONS(-DUSE_SYSTEM_VECTORMATH)
IF(WIN32)
SET (VECTOR_MATH_INCLUDE ${BULLET_PHYSICS_SOURCE_DIR}/src/vectormath/sse CACHE PATH "Vector Math library include path.")
ELSE(WIN32)
SET (VECTOR_MATH_INCLUDE ${BULLET_PHYSICS_SOURCE_DIR}/src/vectormath/scalar CACHE PATH "Vector Math library include path.")
ENDIF(WIN32)
ENDIF(USE_CUSTOM_VECTOR_MATH)
IF (APPLE OR MSVC)
OPTION(BUILD_MULTITHREADING "Use BulletMultiThreading" ON)
ELSE()
OPTION(BUILD_MULTITHREADING "Use BulletMultiThreading" OFF)
ENDIF()
IF (BUILD_MULTITHREADING)
OPTION(USE_MULTITHREADED_BENCHMARK "Use Multithreaded Benchmark" OFF)
IF (USE_MULTITHREADED_BENCHMARK)
ADD_DEFINITIONS(-DUSE_PARALLEL_SOLVER_BENCHMARK -DUSE_PARALLEL_DISPATCHER_BENCHMARK)
ENDIF(USE_MULTITHREADED_BENCHMARK)
IF (MSVC OR APPLE)
OPTION(BUILD_MINICL_OPENCL_DEMOS "Build OpenCL demos for MiniCL (Generic CPU)" ON)
ELSE()
OPTION(BUILD_MINICL_OPENCL_DEMOS "Build OpenCL demos for MiniCL (Generic CPU)" OFF)
ENDIF(MSVC OR APPLE)
IF(MSVC)
FIND_PATH(DIRECTX_SDK_BASE_DIR Include/D3D11.h PATH $ENV{DXSDK_DIR} )
IF(DIRECTX_SDK_BASE_DIR)
OPTION(USE_DX11 "Use DirectX 11" ON)
ELSE()
OPTION(USE_DX11 "Use DirectX 11" OFF)
ENDIF()
FIND_PATH(AMD_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{ATISTREAMSDKROOT} $ENV{AMDAPPSDKROOT} )
IF(AMD_OPENCL_BASE_DIR)
#AMD adds an extras slash at the end of the ATISTREAMSDKROOT variable
SET(AMD_OPENCL_INCLUDES ${AMD_OPENCL_BASE_DIR}/include )
MESSAGE("AMD OPENCL SDK FOUND")
IF (CMAKE_CL_64)
SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86_64 )
ELSE(CMAKE_CL_64)
SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86 )
ENDIF(CMAKE_CL_64)
SET(CMAKE_ATISTREAMSDK_LIBRARY ${CMAKE_ATISTREAMSDK_LIBPATH}/OpenCL.lib )
OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" ON)
IF (CMAKE_CL_64)
SET(CMAK_GLEW_LIBRARY
${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64s.lib )
ELSE(CMAKE_CL_64)
SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32s.lib )
ENDIF(CMAKE_CL_64)
ELSE()
OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" OFF)
ENDIF()
FIND_PATH(INTEL_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{INTELOCLSDKROOT} )
IF(INTEL_OPENCL_BASE_DIR)
SET(INTEL_OPENCL_INCLUDES ${INTEL_OPENCL_BASE_DIR}/include )
MESSAGE("INTEL OPENCL SDK FOUND")
MESSAGE(${INTEL_OPENCL_INCLUDES})
IF (CMAKE_CL_64)
SET(CMAKE_INTELOCLSDK_LIBPATH ${INTEL_OPENCL_BASE_DIR}/lib/x64 )
ELSE(CMAKE_CL_64)
SET(CMAKE_INTELOCLSDK_LIBPATH ${INTEL_OPENCL_BASE_DIR}/lib/x86 )
ENDIF(CMAKE_CL_64)
SET(INTEL_OPENCL_LIBRARIES ${CMAKE_INTELOCLSDK_LIBPATH}/OpenCL.lib)
OPTION(BUILD_INTEL_OPENCL_DEMOS "Build OpenCL demos for Intel (CPU)" ON)
ELSE()
OPTION(BUILD_INTEL_OPENCL_DEMOS "Build OpenCL demos for Intel (CPU)" OFF)
ENDIF()
FIND_PATH(NVIDIA_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{CUDA_PATH} )
IF(NVIDIA_OPENCL_BASE_DIR)
SET(NVIDIA_OPENCL_INCLUDES ${NVIDIA_OPENCL_BASE_DIR}/include )
MESSAGE("NVIDIA OPENCL SDK FOUND")
MESSAGE(${NVIDIA_OPENCL_INCLUDES})
IF (CMAKE_CL_64)
SET(CMAKE_NVSDKCOMPUTE_LIBPATH ${NVIDIA_OPENCL_BASE_DIR}/lib/x64 )
ELSE(CMAKE_CL_64)
SET(CMAKE_NVSDKCOMPUTE_LIBPATH ${NVIDIA_OPENCL_BASE_DIR}/lib/Win32 )
ENDIF(CMAKE_CL_64)
SET(NVIDIA_OPENCL_LIBRARIES ${CMAKE_NVSDKCOMPUTE_LIBPATH}/OpenCL.lib)
OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" ON)
ELSE()
OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" OFF)
ENDIF()
ELSE(MSVC)
FIND_PATH(AMD_OPENCL_BASE_DIR include/CL/cl.h PATH $ENV{ATISTREAMSDKROOT} $ENV{AMDAPPSDKROOT} )
IF(AMD_OPENCL_BASE_DIR)
#AMD adds an extras slash at the end of the ATISTREAMSDKROOT variable
SET(AMD_OPENCL_INCLUDES ${AMD_OPENCL_BASE_DIR}/include )
MESSAGE("AMD OPENCL SDK FOUND")
MESSAGE(${AMD_OPENCL_INCLUDES})
IF (CMAKE_CL_64)
SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86_64 )
ELSE(CMAKE_CL_64)
SET(CMAKE_ATISTREAMSDK_LIBPATH ${AMD_OPENCL_BASE_DIR}/lib/x86 )
ENDIF(CMAKE_CL_64)
OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" ON)
SET(CMAKE_ATISTREAMSDK_LIBRARY OpenCL )
ELSE()
OPTION(BUILD_AMD_OPENCL_DEMOS "Build OpenCL demos for AMD (GPU or CPU)" OFF)
ENDIF(AMD_OPENCL_BASE_DIR)
FIND_PATH(INTEL_OPENCL_INCLUDES CL/cl.h)
FIND_PATH(INTEL_OPENCL_ICD_CFG intelocl64.icd /etc/OpenCL/vendors)
FIND_LIBRARY(INTEL_OPENCL_LIBRARIES OpenCL PATH /usr/lib64)
IF (INTEL_OPENCL_INCLUDES AND INTEL_OPENCL_LIBRARIES AND INTEL_OPENCL_ICD_CFG)
MESSAGE("INTEL OPENCL SDK FOUND")
MESSAGE(${INTEL_OPENCL_LIBRARIES})
OPTION(BUILD_INTEL_OPENCL_DEMOS "Build OpenCL demos for Intel (CPU)" ON)
ELSE ()
MESSAGE("INTEL OPENCL NOT FOUND")
OPTION(BUILD_INTEL_OPENCL_DEMOS "Build OpenCL demos for Intel (CPU)" OFF)
ENDIF ()
FIND_PATH(NVIDIA_OPENCL_INCLUDES CL/cl.h)
FIND_PATH(NVIDIA_OPENCL_ICD_CFG nvidia.icd /etc/OpenCL/vendors)
FIND_LIBRARY(NVIDIA_OPENCL_LIBRARIES OpenCL PATH /usr/lib64 /usr/local/lib)
IF (NVIDIA_OPENCL_INCLUDES AND NVIDIA_OPENCL_LIBRARIES AND NVIDIA_OPENCL_ICD_CFG)
MESSAGE("NVidia OPENCL FOUND")
MESSAGE(${NVIDIA_OPENCL_LIBRARIES})
OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" ON)
ELSE ()
MESSAGE("NVidia OPENCL NOT FOUND")
OPTION(BUILD_NVIDIA_OPENCL_DEMOS "Build OpenCL demos for NVidia (GPU)" OFF)
ENDIF ()
ENDIF(MSVC)
ELSE(BUILD_MULTITHREADING)
# SET(BUILD_NVIDIA_OPENCL_DEMOS OFF CACHE BOOL "Build OpenCL demos for NVidia" FORCE)
# SET(BUILD_AMD_OPENCL_DEMOS OFF CACHE BOOL "Build OpenCL demos for AMD" FORCE)
# SET(BUILD_INTEL_OPENCL_DEMOS OFF CACHE BOOL "Build OpenCL demos for Intel (CPU)" FORCE)
# SET(BUILD_MINICL_OPENCL_DEMOS OFF CACHE BOOL "Build OpenCL demos for MiniCL (Generic CPU)" FORCE)
# SET(USE_DX11 OFF CACHE BOOL "Use DirectX 11" FORCE)
# SET(USE_MULTITHREADED_BENCHMARK OFF CACHE BOOL "Use Multithreaded Benchmark" FORCE)
ENDIF(BUILD_MULTITHREADING)
#SET(CMAKE_EXE_LINKER_FLAGS_INIT "/STACK:10000000 /INCREMENTAL:NO")
#SET(CMAKE_EXE_LINKER_FLAGS "/STACK:10000000 /INCREMENTAL:NO")
#MESSAGE("MSVC_INCREMENTAL_YES_FLAG"+${MSVC_INCREMENTAL_YES_FLAG})
IF(MSVC)
IF (NOT USE_MSVC_INCREMENTAL_LINKING)
#MESSAGE("MSVC_INCREMENTAL_DEFAULT"+${MSVC_INCREMENTAL_DEFAULT})
SET( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:NO")
STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags ${CMAKE_EXE_LINKER_FLAGS_DEBUG})
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "/INCREMENTAL:NO ${replacementFlags}" )
MESSAGE("CMAKE_EXE_LINKER_FLAGS_DEBUG=${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
# STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags2 ${CMAKE_EXE_LINKER_FLAGS})
# SET(CMAKE_EXE_LINKER_FLAGS ${replacementFlag2})
# STRING(REPLACE "INCREMENTAL:YES" "" replacementFlags3 ${CMAKE_EXTRA_LINK_FLAGS})
# SET(CMAKE_EXTRA_LINK_FLAGS ${replacementFlag3})
STRING(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replacementFlags3 ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO})
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${replacementFlags3})
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/INCREMENTAL:NO ${replacementFlags3}" )
ENDIF (NOT USE_MSVC_INCREMENTAL_LINKING)
IF (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
#We statically link to reduce dependancies
FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
IF(${flag_var} MATCHES "/MD")
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
ENDIF(${flag_var} MATCHES "/MD")
IF(${flag_var} MATCHES "/MDd")
STRING(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
ENDIF(${flag_var} MATCHES "/MDd")
ENDFOREACH(flag_var)
ENDIF (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
OPTION(USE_MSVC_SSE "Use MSVC /arch:sse option" ON)
IF (USE_MSVC_SSE)
ADD_DEFINITIONS(/arch:SSE)
ENDIF()
OPTION(USE_MSVC_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON)
IF (USE_MSVC_FAST_FLOATINGPOINT)
ADD_DEFINITIONS(/fp:fast)
ENDIF()
ENDIF(MSVC)
IF (WIN32)
OPTION(INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES "Create MSVC projectfiles that can be distributed" OFF)
IF (INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
SET (LIBRARY_OUTPUT_PATH ${BULLET_PHYSICS_SOURCE_DIR}/lib CACHE PATH "Single output directory for building all libraries.")
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR})
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${BULLET_PHYSICS_SOURCE_DIR})
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${BULLET_PHYSICS_SOURCE_DIR})
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${BULLET_PHYSICS_SOURCE_DIR})
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${BULLET_PHYSICS_SOURCE_DIR})
ELSE()
SET (LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib CACHE PATH "Single output directory for building all libraries.")
ENDIF()
OPTION(INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES "Create MSVC projectfiles with relative paths" OFF)
OPTION(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES "Add MSVC postfix for executable names (_Debug)" OFF)
SET(CMAKE_DEBUG_POSTFIX "_Debug" CACHE STRING "Adds a postfix for debug-built libraries.")
SET(CMAKE_MINSIZEREL_POSTFIX "_MinsizeRel" CACHE STRING "Adds a postfix for MinsizeRelease-built libraries.")
SET(CMAKE_RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo" CACHE STRING "Adds a postfix for ReleaseWithDebug-built libraries.")
IF (INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES)
SET(CMAKE_SUPPRESS_REGENERATION 1)
SET(CMAKE_USE_RELATIVE_PATHS 1)
ENDIF(INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES)
ENDIF (WIN32)
OPTION(BUILD_CPU_DEMOS "Build original Bullet CPU demos" ON)
OPTION(INTERNAL_UPDATE_SERIALIZATION_STRUCTURES "Internal update serialization structures" OFF)
IF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
ADD_DEFINITIONS( -DBT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
ENDIF (INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
IF (USE_DOUBLE_PRECISION)
ADD_DEFINITIONS( -DBT_USE_DOUBLE_PRECISION)
SET( BULLET_DOUBLE_DEF "-DBT_USE_DOUBLE_PRECISION")
ENDIF (USE_DOUBLE_PRECISION)
IF(USE_GRAPHICAL_BENCHMARK)
ADD_DEFINITIONS( -DUSE_GRAPHICAL_BENCHMARK)
ENDIF (USE_GRAPHICAL_BENCHMARK)
IF (WIN32)
OPTION(USE_GLUT "Use Glut" ON)
ADD_DEFINITIONS( -D_IRR_STATIC_LIB_ )
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
ADD_DEFINITIONS( -D_CRT_SECURE_NO_DEPRECATE )
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
IF (USE_GLUT AND MSVC)
string (REPLACE "/D_WINDOWS" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
remove_definitions(-D_WINDOWS )
ENDIF()
ELSE(WIN32)
OPTION(USE_GLUT "Use Glut" ON)
ENDIF(WIN32)
IF(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
@ -21,52 +308,113 @@ ENDIF(COMMAND cmake_policy)
FIND_PACKAGE(OpenGL)
IF (OPENGL_FOUND)
MESSAGE("OPENGL FOUND")
MESSAGE(${OPENGL_LIBRARIES})
MESSAGE("OPENGL FOUND")
MESSAGE(${OPENGL_LIBRARIES})
ELSE (OPENGL_FOUND)
MESSAGE("OPENGL NOT FOUND")
SET(OPENGL_gl_LIBRARY opengl32)
SET(OPENGL_glu_LIBRARY glu32)
MESSAGE("OPENGL NOT FOUND")
SET(OPENGL_gl_LIBRARY opengl32)
SET(OPENGL_glu_LIBRARY glu32)
ENDIF (OPENGL_FOUND)
# ADD_DEFINITIONS(-DBT_USE_FREEGLUT)
FIND_PACKAGE(GLU)
FIND_PACKAGE(GLUT)
IF (GLUT_FOUND)
MESSAGE("GLUT FOUND")
MESSAGE(${GLUT_glut_LIBRARY})
ELSE (GLUT_FOUND)
IF (USE_GLUT)
FIND_PACKAGE(GLUT)
IF (GLUT_FOUND)
MESSAGE("GLUT FOUND")
MESSAGE(${GLUT_glut_LIBRARY})
ELSE (GLUT_FOUND)
IF (MINGW)
MESSAGE ("GLUT NOT FOUND not found, trying to use MINGW glut32")
SET(GLUT_glut_LIBRARY glut32)
#TODO add better GLUT detection for MinGW
SET(GLUT_FOUND TRUE)
ENDIF (MINGW)
IF (MSVC)
SET(GLUT_FOUND TRUE)
IF (CMAKE_CL_64)
message("Win64 using Glut/glut64.lib")
SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut64.lib)
ELSE(CMAKE_CL_64)
message("Win32 using Glut/glut32.lib")
SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut32.lib)
ENDIF (CMAKE_CL_64)
INCLUDE_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/Glut)
ELSE()
MESSAGE("GLUT NOT FOUND")
ENDIF (MSVC)
ENDIF (GLUT_FOUND)
IF (MINGW)
MESSAGE ("GLUT NOT FOUND not found, trying to use MINGW glut32")
SET(GLUT_glut_LIBRARY glut32)
ENDIF (MINGW)
IF (MSVC)
MESSAGE ("GLUT NOT FOUND, trying to use Bullet/Glut/glut32.lib for MSVC")
SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut32.lib)
ENDIF (MSVC)
ENDIF (GLUT_FOUND)
IF (WIN32)
INCLUDE_DIRECTORIES(${BULLET_PHYSICS_SOURCE_DIR}/Glut)
ELSE (WIN32)
# This is the lines for linux. This should always work if everything is installed and working fine.
INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR})
ENDIF (WIN32)
IF(NOT WIN32)
# This is added for linux. This should always work if everything is installed and working fine.
INCLUDE_DIRECTORIES(/usr/include /usr/local/include)
ENDIF()
ENDIF(USE_GLUT)
OPTION(BUILD_DEMOS "Set when you want to build the demos" ON)
IF(BUILD_DEMOS)
SUBDIRS(Demos)
IF(EXISTS ${BULLET_PHYSICS_SOURCE_DIR}/Demos AND IS_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR}/Demos)
SUBDIRS(Demos)
ENDIF()
ENDIF(BUILD_DEMOS)
# "Demos_ps3")
IF (MSVC)
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
IF(EXISTS ${BULLET_PHYSICS_SOURCE_DIR}/Demos_ps3 AND IS_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR}/Demos_ps3)
MESSAGE("Demos_ps3 found")
SUBDIRS(Demos_ps3)
ENDIF()
ENDIF()
ENDIF(MSVC)
OPTION(BUILD_EXTRAS "Set when you want to build the extras" ON)
IF(BUILD_EXTRAS)
SUBDIRS(Extras)
ENDIF(BUILD_EXTRAS)
#Maya Dynamica plugin is moved to http://dynamica.googlecode.com
SUBDIRS(src)
IF("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
OPTION(INSTALL_LIBS "Set when you want to install libraries" ON)
ELSE()
IF(APPLE AND FRAMEWORK)
OPTION(INSTALL_LIBS "Set when you want to install libraries" ON)
ELSE()
#by default, don't enable the 'INSTALL' option for Xcode and MSVC projectfiles
OPTION(INSTALL_LIBS "Set when you want to install libraries" OFF)
ENDIF()
ENDIF()
IF(INSTALL_LIBS)
SET (LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
SET (LIB_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE STRING "Library directory name")
## the following are directories where stuff will be installed to
SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include/bullet/" CACHE PATH "The subdirectory to the header prefix")
SET(PKGCONFIG_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig/" CACHE STRING "Base directory for pkgconfig files")
IF(NOT WIN32)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/bullet.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/bullet.pc @ONLY)
INSTALL(
FILES
${CMAKE_CURRENT_BINARY_DIR}/bullet.pc
DESTINATION
${PKGCONFIG_INSTALL_PREFIX})
ENDIF(NOT WIN32)
ENDIF(INSTALL_LIBS)
#INSTALL of other files requires CMake 2.6
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
OPTION(INSTALL_EXTRA_LIBS "Set when you want extra libraries installed" OFF)
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
OPTION(BUILD_UNIT_TESTS "Build Unit Tests" OFF)
IF (BUILD_UNIT_TESTS)
SUBDIRS(UnitTests)
ENDIF()

View file

@ -1,11 +1,57 @@
Bullet Continuous Collision Detection and Physics Library
Primary author and maintainer: Erwin Coumans
Please see http://code.google.com/p/bullet/source/list for more complete log in Subversion
This ChangeLog is incomplete, for an up-to-date list of all fixed issues see http://bullet.googlecode.com
using http://tinyurl.com/yabmjjj
2012 September 10
- Bullet 2.81 release preparation
2011 September 15
- Bullet 2.79 release, revision 2433 (mainly a bugfix release)
- Revert a change in 2.78 related to speculative contacts (it has undesired side effects)
- Use HACD Hierachical Approximate Convex Decomposition (thanks to Khaled Mammou and Sujeon Kim)
- Add Intel cmake-build support for OpenCL accelerated cloth/particle
- add premake4 build system support to autogenerate visual studio project files that can be shipped (see msvc folder)
- preliminary build support for Google NativeClient, using premake4 (see msvc folder)
2011 April 8
- Bullet 2.78 release 2383
- Added FractureDemo
- Added Separatinx Axis Test and Polyhedral Clipping support (See InternalEdgeDemo)
- Added speculative contacts as CCD response method (See CcdPhysicsDemo)
- OpenCL and DirectCompute cloth as basic support for capsule collision
2010 September 7
- autotools now uses CamelCase naming for libraries just like cmake:
libbulletdynamics -> libBulletDynamics, libbulletmath -> libLinearMath
2010 July 21
- Preparing for Bullet 2.77 release, around revision r2135
- Added an OpenCL particle demo, running on NVidia, AMD and MiniCL
Thanks to NVidia for the original particle demo from their OpenCL SDK
- Added GPU deformable object solvers for OpenCL and DirectCompute, and a DirectX 11 cloth demo
Thanks to AMD
- Create a separate library for MiniCL,
MiniCL is a rudimentary OpenCL wrapper that allows to compile OpenCL kernels for multi-core CPU, using Win32 Threads or Posix
- Moved vectormath into Bullet/src, and added a SSE implementation
- Added a btParallelConstraintSolver, mainly for PlayStation 3 Cell SPUs (although it runs fine on CPU too)
2010 March 6
- Dynamica Maya plugin (and COLLADA support) is moved to http://dynamica.googlecode.com
2010 February
- Bullet 2.76 release, revision 2010
- support for the .bullet binary file format
- btInternalEdgeUtility to adjust unwanted collisions against internal triangle edges
- Improved Maya Dynamica plugin with better constraint authoring and .bullet file export
2009 September 17
- Minor update to Bullet 2.75 release, revision 1770
- Minor update to Bullet 2.75 release, revision 1776
- Support for btConvex2dShape, check out Bullet/Demos/Box2dDemo
- Fixes in build systems
- Minor fix in btGjkPairDetector
- Initialize world transform for btCollisionShape in constructor

View file

@ -13,6 +13,9 @@
# General configuration options
#---------------------------------------------------------------------------
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = "Bullet Collision Detection & Physics Library"
@ -399,7 +402,9 @@ HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = YES
HHC_LOCATION = "C:\Program Files\HTML Help Workshop\hhc.exe"
# HHC_LOCATION = "C:\Program Files\HTML Help Workshop\hhc.exe"
HHC_LOCATION = "C:\Program Files (x86)\HTML Help Workshop\hhc.exe"
HTML_FILE_EXTENSION = .html
HTML_HEADER =
@ -589,7 +594,7 @@ MACRO_EXPANSION = YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
@ -615,7 +620,14 @@ INCLUDE_FILE_PATTERNS =
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
PREDEFINED = "ATTRIBUTE_ALIGNED128(x)=x" \
"ATTRIBUTE_ALIGNED16(x)=x" \
"SIMD_FORCE_INLINE=inline" \
"VECTORMATH_FORCE_INLINE=inline" \
"USE_WIN32_THREADING=1"\
"USE_PTHREADS=1"\
"_WIN32=1"
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
@ -718,6 +730,11 @@ MAX_DOT_GRAPH_HEIGHT = 1024
GENERATE_LEGEND = YES
# delete intermediate dot files?
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------

View file

@ -1,24 +1,22 @@
Bullet Collision Detection and Physics Library
See also http://bulletphysics.org/mediawiki-1.5.8/index.php/Creating_a_project_from_scratch
** Windows Compilation **
Under Windows, projectfiles for Visual Studio version 6,7,7.1 and 8 are
available in msvc/<version>. For example, for Visual Studio 2005, open
msvc/8/wksbullet.sln
Open the Microsoft Visual Studio solution in msvc/20xx/BULLET_PHYSICS.sln
The ColladaDemo and ConvexDecomposition demo needs to be able to locate the
data files (jenga.dae and file.obj) in the current directory. Make sure Visual
Studio points to the right folder (..\..).
Alternatively use CMake to autogenerate a build system for Windows:
Alternatively, use CMake to autogenerate a build system for Windows:
- Download/install CMake from www.cmake.org or package manager
- Use cmake-gui or
- List available build systems by running 'cmake' in the Bullet root folder
- Use cmake-gui
- Create a build system using the -G option for example:
cmake . -G "Visual Studio 9 2008" or
cmake . -G "Visual Studio 9 2008 Win64"
** Linux Compilation **
@ -26,6 +24,11 @@ Alternatively use CMake to autogenerate a build system for Windows:
CMake is like autoconf in that it will create build scripts which are then
used for the actual compilation
- List available build systems by running 'cmake' in the Bullet root folder
- Create a build system using the -G option for example:
cmake . -G "Unix Makefiles"
- There are some options for cmake builds:
BUILD_SHARED_LIBS: default 'OFF', set to 'ON' to build .so libraries
BUILD_EXTRAS: default 'ON', compiles additional libraries in 'Extras'
@ -33,6 +36,8 @@ Alternatively use CMake to autogenerate a build system for Windows:
CMAKE_INSTALL_PREFIX: default '/usr/local', the installation path.
CMAKE_INSTALL_RPATH: if you install outside a standard ld search path,
then you should set this to the installation lib path.
CMAKE_BUILD_TYPE: default 'Release', can include debug symbols with
either 'Debug' or 'RelWithDebInfo'.
Other options may be discovered by 'cmake --help-variable-list' and
'cmake --help-variable OPTION'
@ -41,7 +46,7 @@ Alternatively use CMake to autogenerate a build system for Windows:
also produce Eclipse or KDevelop project files. See 'cmake --help' to see
what "generators" are available in your environment, selected via '-G'.
For example:
cmake -DBUILD_SHARED_LIBS=ON
cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=RelWithDebugInfo
- Assuming using the default Makefile output from cmake, run 'make' to
build, and then 'make install' if you wish to install.
@ -53,6 +58,12 @@ Alternatively use CMake to autogenerate a build system for Windows:
CMake is like autoconf in that it will create build scripts which are then
used for the actual compilation
- List available build systems by running 'cmake' in the Bullet root folder
- Create a build system using the -G option for example:
cmake . -G Xcode
cmake . -G "Unix Makefiles"
- There are some options for cmake builds:
BUILD_SHARED_LIBS: default 'OFF', set to 'ON' to build .dylib libraries
BUILD_EXTRAS: default 'ON', compiles additional libraries in 'Extras'
@ -60,6 +71,10 @@ Alternatively use CMake to autogenerate a build system for Windows:
CMAKE_INSTALL_PREFIX: default '/usr/local', the installation path.
CMAKE_INSTALL_NAME_DIR: if you install outside a standard ld search
path, then you should set this to the installation lib/framework path.
CMAKE_OSX_ARCHITECTURES: defaults to the native architecture, but can be
set to a semicolon separated list for fat binaries, e.g. ppc;i386;x86_64
CMAKE_BUILD_TYPE: default 'Release', can include debug symbols with
either 'Debug' or 'RelWithDebInfo'.
To build framework bundles:
FRAMEWORK: default 'OFF', also requires 'BUILD_SHARED_LIBS' set ON
@ -78,23 +93,19 @@ Alternatively use CMake to autogenerate a build system for Windows:
For example:
cmake -DBUILD_SHARED_LIBS=ON -DFRAMEWORK=ON \
-DCMAKE_INSTALL_PREFIX=/Library/Frameworks \
-DCMAKE_INSTALL_NAME_DIR=/Library/Frameworks
-DCMAKE_INSTALL_NAME_DIR=/Library/Frameworks \
-DCMAKE_OSX_ARCHITECTURES='ppc;i386;x86_64' \
-DCMAKE_BUILD_TYPE=RelWithDebugInfo
- Assuming using the default Makefile output from cmake, run 'make' to build
and then 'make install'.
** Alternative Mac OS X and Linux via 'jam' or autoconf/make **
** Alternative Mac OS X and Linux via autoconf/make **
- at the command line:
./autogen.sh
./configure
- 'jam' or 'make' depending on preference
- If jam is not available for your system, you can compile it, jam sources
are included with the Bullet sources in jam-2.5
- compiling jam:
cd jam-2.5
make
sudo make install
make
** For more help, visit http://www.bulletphysics.com **
** For more help, visit http://www.bulletphysics.org **

View file

@ -1,66 +0,0 @@
TOP ?= "@top_srcdir@" ;
BUILDTOP ?= "@top_builddir@" ;
SubDir TOP ;
IncludeDir ;
IncludeDir src ;
IncludeDir $(BUILDTOP) : : literal transient ;
CleanDir clean :
out ;
Clean distclean :
aclocal.m4
config.h
config.h.in~
config.log
config.status
config.status.lineno
config.cache
configure.lineno
Jamconfig
Jamfile ;
CleanDir distclean :
autom4te.cache ;
Depends distclean : clean ;
Clean maintainerclean :
config.h.in
configure ;
Depends maintainerclean : distclean ;
Help distclean : "Remove built targets and configuration" ;
Help maintainerclean :
"Remove built targets, configuration, and generated files." ;
ApplicationIconDefault win32 : all : bullet_ico.ico : $(TOP) msvc ;
MsvcGenSubDir TOP msvc : common ;
MsvcGenSubDir TOP msvc 6 : 6 ;
MsvcGenSubDir TOP msvc 7 : 7 ;
MsvcGenSubDir TOP msvc 71 : 71 ;
MsvcGenSubDir TOP msvc sn71 : sn71 ;
MsvcGenSubDir TOP msvc 8 : 8 ;
MsvcGenSubDir TOP msvc xenon8 : xenon8 ;
MsvcGenTemplateDir TOP mk msvcgen ;
MsvcGenWorkspace bullet : : "grp.+_(?!bullet$)" ;
MsvcGenWorkspace bullet_corelib : libbulletcollision libbulletdynamics libbulletmath libbulletmultithreaded : "grp.+_(?!bullet_corelib$)" ;
# Set project-specific compiler and linker options for msvcgen.
MsvcGenConfig GL.AVAILABLE : yes ;
MsvcGenConfig GL.LFLAGS : ;
MsvcGenConfig GL.LIBS : opengl32.lib ;
MsvcGenConfig GLUT.AVAILABLE : yes ;
MsvcGenConfig GLUT.CFLAGS : ;
MsvcGenConfig GLUT.LFLAGS : ;
MsvcGenConfig GLUT.INCDIRS : "../../Glut" ;
MsvcGenConfig GLUT.LIBDIRS : "../../Glut" ;
MsvcGenConfig GLUT.LIBS : glut32.lib ;
MsvcGenConfig GLEW.LIBS : glew32.lib ;
SubInclude TOP src ;
SubInclude TOP Extras ;
SubInclude TOP Demos ;
Depends install_config : [ DoInstall bullet.pc : $(libdir)/pkgconfig ] ;

View file

@ -1,21 +0,0 @@
if ! $(BUILDTOP)
{
BUILDTOP = . ;
}
# Include configuration.
JAMCONFIG ?= $(BUILDTOP)/Jamconfig ;
include $(JAMCONFIG) ;
# Set up compiler flags.
# Unfortunately, we can not use FDefines here since Boost Jam does not have it,
# and we have not yet included mk/jam/build.jam which provides an emulation
# layer for Boost. We can not include build.jam earlier because these flags
# need to be defined before build.jam is included. :-(
COMPILER.CFLAGS += -Wall -Wno-unknown-pragmas ;
COMPILER.CFLAGS.optimize += -O3 -fomit-frame-pointer -ffast-math ;
COMPILER.CFLAGS.debug += -g3 ;
COMPILER.CFLAGS.profile += -gp -O3 ;
# Include CS build rules
include $(TOP)/mk/jam/build.jam ;

View file

@ -1,19 +0,0 @@
/*
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.
*/
All files in the Bullet/src folder are under this Zlib license.
Optional Extras/GIMPACT and Extras/GIMPACTBullet is also under ZLib license. Other optional external libraries in Extras/Demos have own license,see respective files.
This means Bullet can freely be used in any software, including commercial and console software. A Playstation 3 optimized version is available through Sony.

View file

@ -1,7 +1,7 @@
if CONDITIONAL_BUILD_DEMOS
SUBDIRS=src Extras Demos
else
SUBDIRS=src Extras
SUBDIRS=src
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = bullet.pc

View file

@ -1,4 +1,5 @@
For news, visit the Bullet Physics Forum at
http://www.continuousphysics.com/Bullet/phpBB2/viewforum.php?f=9
For news, visit the Bullet Physics forums at
http://www.bulletphysics.org and http://bullet.googlecode.com

View file

@ -1,7 +1,6 @@
Bullet is a 3D Collision Detection and Rigid Body Dynamics Library for games and animation.
Free for commercial use, including Playstation 3, open source under the ZLib License.
Discrete and continuous collision detection, integrated into Blender 3D, and COLLADA 1.4 Physics import.
See the Bullet_User_Manual.pdf for more info and visit the Bullet Physics Forum at
http://bulletphysics.com
http://bulletphysics.org

View file

@ -1 +1 @@
2.75
2.81

View file

@ -1416,7 +1416,6 @@ AC_DEFUN([CS_CHECK_TEMPLATE_TOOLKIT2],
#-----------------------------------------------------------------------------
AC_DEFUN([CS_PROG_CC],[
CFLAGS="$CFLAGS" # Filter undesired flags
AC_PROG_CC
AS_IF([test -n "$CC"],[
CS_EMIT_BUILD_PROPERTY([CMD.CC], [$CC])
CS_EMIT_BUILD_PROPERTY([COMPILER.CFLAGS], [$CPPFLAGS $CFLAGS], [+])
@ -1429,7 +1428,6 @@ AC_DEFUN([CS_PROG_CC],[
AC_DEFUN([CS_PROG_CXX],[
CXXFLAGS="$CXXFLAGS" # Filter undesired flags
AC_PROG_CXX
AS_IF([test -n "$CXX"],[
CS_EMIT_BUILD_PROPERTY([CMD.C++], [$CXX])

View file

@ -7,5 +7,5 @@ Name: bullet
Description: Bullet Continuous Collision Detection and Physics Library
Requires:
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lbulletdynamics -lbulletcollision -lbulletmath
Libs: -L${libdir} -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath
Cflags: -I${includedir}/bullet

View file

@ -1,5 +1,8 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* Architecture is PowerPC */
#undef ARCH_PPC
@ -9,27 +12,27 @@
/* Architecture is x86-64 */
#undef ARCH_X86_64
/* Define when compiling for MacOS/X */
#undef CS_PLATFORM_MACOSX
/* Define when compiling for Unix and Unix-like (i.e. MacOS/X) */
#undef CS_PLATFORM_UNIX
/* Define when compiling for Win32 */
#undef CS_PLATFORM_WIN32
/* Use the Apple OpenGL framework. */
#undef HAVE_APPLE_OPENGL_FRAMEWORK
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <GL/glext.h> header file. */
#undef HAVE_GL_GLEXT_H
/* Define to 1 if you have the <GL/glut.h> header file. */
#undef HAVE_GL_GLUT_H
/* Define to 1 if you have the <GL/glu.h> header file. */
#undef HAVE_GL_GLU_H
/* Define to 1 if you have the <GL/gl.h> header file. */
#undef HAVE_GL_GL_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `mx' library (-lmx). */
#undef HAVE_LIBMX
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@ -51,19 +54,16 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Whether the int32 type is available */
#undef HAVE_TYPE_INT32
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <windows.h> header file. */
#undef HAVE_WINDOWS_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Name of package */
#undef PACKAGE
@ -79,6 +79,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@ -97,12 +100,14 @@
/* Version number of package */
#undef VERSION
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to 1 if the X Window System is missing or not being used. */
#undef X_DISPLAY_MISSING
/* Avoid problem caused by missing <Carbon/CarbonSound.h> */
#undef __CARBONSOUND__
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif

View file

@ -9,16 +9,12 @@ AC_PREREQ([2.54])
#----------------------------------------------------------------------------
AC_INIT(
[bullet],
[2.75],
[2.81],
[bullet@erwincoumans.com])
AC_CANONICAL_HOST
CS_PACKAGEINFO(
[Bullet Continuous Collision Detection and Physics Library],
[Copyright (c) 2005-2008 Erwin Coumans],
[http://www.bulletphysics.com])
AC_CONFIG_SRCDIR([configure.ac])
AM_INIT_AUTOMAKE
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CXX
AC_PROG_LIBTOOL
@ -34,6 +30,7 @@ case "$host" in
PLATFORM_STRING="Linux"
;;
*-*-darwin*)
AC_MSG_WARN([Hello])
AC_DEFINE(PLATFORM_APPLE, 1, [Platform is Apple])
opengl_LIBS="-framework AGL -framework OpenGL -framework GLUT"
PLATFORM_STRING="Apple"
@ -56,6 +53,7 @@ case "$host" in
ARCH_STRING="X86-64"
;;
ppc-* | powerpc-*)
AC_MSG_WARN([HI THERE!])
AC_DEFINE(ARCH_PPC, 1, [Architecture is PowerPC])
ARCH_SPECIFIC_CFLAGS=""
ARCH_STRING="PowerPC"
@ -71,63 +69,6 @@ AC_C_BIGENDIAN
# Setup for the configuration header.
#----------------------------------------------------------------------------
AC_CONFIG_HEADERS([config.h])
#----------------------------------------------------------------------------
# Check for tools.
#----------------------------------------------------------------------------
CS_PROG_CC
AS_IF([test -z "$CC"],
[AC_MSG_ERROR([Could not find a usable C compiler.])])
CS_PROG_CXX
AS_IF([test -z "$CXX"],
[AC_MSG_ERROR([Could not find a usable C++ compiler.])])
CS_PROG_LINK
CS_CHECK_COMMON_TOOLS_LINK
CS_CHECK_COMMON_TOOLS_BASIC
CS_CHECK_COMMON_TOOLS_DOC_DOXYGEN
CS_CHECK_PROGS([PERL], [perl5 perl])
CS_EMIT_BUILD_PROPERTY([PERL], [$PERL])
CS_CHECK_TEMPLATE_TOOLKIT2([emit])
#----------------------------------------------------------------------------
# Check if C++ exceptions can be disabled.
#----------------------------------------------------------------------------
CS_EMIT_BUILD_FLAGS([how to disable C++ exceptions],
[cs_cv_prog_cxx_disable_exceptions], [CS_CREATE_TUPLE([-fno-exceptions])],
[C++], [COMPILER.C++FLAGS.EXCEPTIONS.DISABLE], [],
[CS_EMIT_BUILD_PROPERTY([COMPILER.C++FLAGS],
[$cs_cv_prog_cxx_disable_exceptions], [+])])
#----------------------------------------------------------------------------
# Determine system type
#----------------------------------------------------------------------------
CS_CHECK_HOST
#----------------------------------------------------------------------------
# Check for syntax problems / header files
#----------------------------------------------------------------------------
# Nothing yet.
#----------------------------------------------------------------------------
# Check for GLUT.
#----------------------------------------------------------------------------
AS_IF([test $cs_host_family = windows],
[# Tack the GLUT that comes with bullet onto compiler & linker flags.
_AC_SRCDIRS(["."])
glut_cflags="-I$ac_top_srcdir/Glut"
glut_lflags="-L$ac_top_srcdir/Glut"
CFLAGS="$CFLAGS $glut_cflags"
LDFLAGS="$LDFLAGS $glut_lflags"
CS_EMIT_BUILD_PROPERTY([COMPILER.CFLAGS], [$glut_cflags], [+])
CS_EMIT_BUILD_PROPERTY([COMPILER.LFLAGS], [$glut_lflags], [+])
])
CS_CHECK_GLUT
#----------------------------------------------------------------------------
# Package configuration switches.
#----------------------------------------------------------------------------
@ -142,10 +83,63 @@ AM_CONDITIONAL([CONDITIONAL_BUILD_MULTITHREADED], [test "$build_multithreaded" =
AC_ARG_ENABLE([demos],
[AS_HELP_STRING([--disable-demos],
[disable Bullet demos])],
[disable Bullet demos])],
[],
[enable_demos=yes])
AM_CONDITIONAL([CONDITIONAL_BUILD_DEMOS], [false])
dnl Check for OpenGL and GLUT
case "$host" in
*-*-darwin*)
AC_DEFINE([HAVE_APPLE_OPENGL_FRAMEWORK], [1],
[Use the Apple OpenGL framework.])
GL_LIBS="-framework GLUT -framework OpenGL -framework Carbon -framework AGL"
have_glut=yes
have_glu=yes
have_gl=yes
;;
*)
have_gl_headers=yes
AC_CHECK_HEADERS(GL/gl.h GL/glu.h GL/glext.h GL/glut.h, ,
[have_gl_headers=no],
[[#ifdef WIN32
#include <windows.h>
#endif
#if HAVE_GL_GL_H
#include <GL/gl.h>
#endif
#if HAVE_GL_GLU_H
#include <GL/glu.h>
#endif
]])
have_gl=no
have_glu=no
have_glut=no
TEMP_LDFLAGS="$LDFLAGS"
AC_CHECK_LIB(GL, main, [GL_LIBS="-lGL"; have_gl=yes])
AC_CHECK_LIB(GLU, main, [GL_LIBS="-lGLU $GL_LIBS"; have_glu=yes], , -lGL)
AC_CHECK_LIB(GLUT, main, [GL_LIBS="-lGLUT -LGLU $GL_LIBS"; have_glut=yes], ,-lGLUT)
AC_CHECK_LIB(opengl32, main, [GL_LIBS="-lopengl32"; have_gl=yes])
AC_CHECK_LIB(glu32, main, [GL_LIBS="-lglu32 $GL_LIBS"; have_glu=yes], , -lopengl32)
LDFLAGS="$TEMP_LDFLAGS"
if test $have_gl = no -o $have_glu = no -o $have_gl_headers = no; then
if test x$enable_demos = xyes; then
AC_MSG_WARN([Demos and Extras will not be built because OpenGL and GLUT doesn't seem to work. See `config.log' for details.])
fi
enable_demos=no
else
AC_MSG_NOTICE([Found OpenGL])
fi
;;
esac
AC_SUBST(GL_LIBS)
if test "x$enable_demos" != xno; then
AC_MSG_NOTICE([Building Bullet demos])
AM_CONDITIONAL([CONDITIONAL_BUILD_DEMOS],[true])
@ -162,13 +156,6 @@ AC_MSG_CHECKING([build mode])
AS_IF([test $enable_debug = yes], [build_mode=debug], [build_mode=optimize])
AC_MSG_RESULT([$build_mode])
CS_EMIT_BUILD_PROPERTY([MODE], [$build_mode])
#-----------------------------------------------------------------------------
# Emit install paths and package information.
#-----------------------------------------------------------------------------
CS_OUTPUT_INSTALLDIRS
CS_EMIT_PACKAGEINFO
CFLAGS="$ARCH_SPECIFIC_CFLAGS $CFLAGS"
@ -176,17 +163,10 @@ CXXFLAGS="$ARCH_SPECIFIC_CFLAGS $CXXFLAGS $CFLAGS"
#----------------------------------------------------------------------------
# Emit generated files.
#----------------------------------------------------------------------------
CS_JAMCONFIG_OUTPUT([Jamconfig])
AC_CONFIG_FILES([bullet.pc Jamfile Makefile Demos/Makefile Demos/SoftDemo/Makefile Demos/AllBulletDemos/Makefile Demos/MultiThreadedDemo/Makefile Demos/ColladaDemo/Makefile Demos/OpenGL/Makefile Demos/BasicDemo/Makefile Demos/CcdPhysicsDemo/Makefile Demos/VehicleDemo/Makefile Demos/TerrainDemo/Makefile src/Makefile Extras/Makefile])
AC_CONFIG_FILES([bullet.pc Makefile Demos/Makefile Demos/SoftDemo/Makefile Demos/AllBulletDemos/Makefile Demos/MultiThreadedDemo/Makefile Demos/OpenGL/Makefile Demos/BasicDemo/Makefile Demos/CcdPhysicsDemo/Makefile Demos/VehicleDemo/Makefile Demos/TerrainDemo/Makefile src/Makefile Extras/Makefile])
AC_OUTPUT
AC_MSG_NOTICE([
You can type 'make' or 'jam' to build Bullet.
Alternatively, you can use cmake or use the wksbullet.sln visual studio x solutions in the msvc/x folder.
CMake home:http://cmake.org
Jam home: http://www.perforce.com/jam/jam.html
Jam source: ftp://ftp.perforce.com/jam/
Please type 'make' to build Bullet
])

View file

@ -65,7 +65,7 @@ extern "C" {
Create and Delete a Physics SDK
*/
extern plPhysicsSdkHandle plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.
extern plPhysicsSdkHandle plNewBulletSdk(void); //this could be also another sdk, like ODE, PhysX etc.
extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk);
/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
@ -116,16 +116,16 @@ extern "C" {
extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCompoundShape();
extern plCollisionShapeHandle plNewCompoundShape(void);
extern void plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
extern void plDeleteShape(plCollisionShapeHandle shape);
/* Convex Meshes */
extern plCollisionShapeHandle plNewConvexHullShape();
extern plCollisionShapeHandle plNewConvexHullShape(void);
extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
/* Concave static triangle meshes */
extern plMeshInterfaceHandle plNewMeshInterface();
extern plMeshInterfaceHandle plNewMeshInterface(void);
extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);

View file

@ -16,8 +16,8 @@
//
// 3. This notice may not be removed or altered from any source distribution.
#ifndef AXIS_SWEEP_3_H
#define AXIS_SWEEP_3_H
#ifndef BT_AXIS_SWEEP_3_H
#define BT_AXIS_SWEEP_3_H
#include "LinearMath/btVector3.h"
#include "btOverlappingPairCache.h"
@ -150,6 +150,8 @@ public:
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
@ -285,6 +287,31 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,cons
}
}
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
{
if (m_raycastAccelerator)
{
m_raycastAccelerator->aabbTest(aabbMin,aabbMax,callback);
} else
{
//choose axis?
BP_FP_INT_TYPE axis = 0;
//for each proxy
for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
{
if (m_pEdges[axis][i].IsMax())
{
Handle* handle = getHandle(m_pEdges[axis][i].m_handle);
if (TestAabbAgainstAabb2(aabbMin,aabbMax,handle->m_aabbMin,handle->m_aabbMax))
{
callback.process(handle);
}
}
}
}
}
template <typename BP_FP_INT_TYPE>
@ -588,7 +615,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,bt
}
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* dispatcher)
void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* /*dispatcher*/)
{
if (m_numHandles == 0)
{

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BROADPHASE_INTERFACE_H
#define BROADPHASE_INTERFACE_H
#ifndef BT_BROADPHASE_INTERFACE_H
#define BT_BROADPHASE_INTERFACE_H
@ -26,7 +26,14 @@ class btOverlappingPairCache;
struct btBroadphaseRayCallback
struct btBroadphaseAabbCallback
{
virtual ~btBroadphaseAabbCallback() {}
virtual bool process(const btBroadphaseProxy* proxy) = 0;
};
struct btBroadphaseRayCallback : public btBroadphaseAabbCallback
{
///added some cached data to accelerate ray-AABB tests
btVector3 m_rayDirectionInverse;
@ -34,7 +41,6 @@ struct btBroadphaseRayCallback
btScalar m_lambda_max;
virtual ~btBroadphaseRayCallback() {}
virtual bool process(const btBroadphaseProxy* proxy) = 0;
};
#include "LinearMath/btVector3.h"
@ -54,6 +60,8 @@ public:
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) = 0;
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0;
@ -65,10 +73,10 @@ public:
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
///reset broadphase internal structures, to ensure determinism/reproducability
virtual void resetPool(btDispatcher* dispatcher) {};
virtual void resetPool(btDispatcher* dispatcher) { (void) dispatcher; };
virtual void printStats() = 0;
};
#endif //BROADPHASE_INTERFACE_H
#endif //BT_BROADPHASE_INTERFACE_H

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BROADPHASE_PROXY_H
#define BROADPHASE_PROXY_H
#ifndef BT_BROADPHASE_PROXY_H
#define BT_BROADPHASE_PROXY_H
#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
#include "LinearMath/btVector3.h"
@ -141,6 +141,11 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
return (proxyType < CONCAVE_SHAPES_START_HERE);
}
static SIMD_FORCE_INLINE bool isNonMoving(int proxyType)
{
return (isConcave(proxyType) && !(proxyType==GIMPACT_SHAPE_PROXYTYPE));
}
static SIMD_FORCE_INLINE bool isConcave(int proxyType)
{
return ((proxyType > CONCAVE_SHAPES_START_HERE) &&
@ -150,6 +155,12 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
{
return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
}
static SIMD_FORCE_INLINE bool isSoftBody(int proxyType)
{
return (proxyType == SOFTBODY_SHAPE_PROXYTYPE);
}
static SIMD_FORCE_INLINE bool isInfinite(int proxyType)
{
return (proxyType == STATIC_PLANE_PROXYTYPE);
@ -235,7 +246,7 @@ class btBroadphasePairSortPredicate
{
public:
bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b ) const
{
const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1;
const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1;
@ -255,5 +266,5 @@ SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphaseP
}
#endif //BROADPHASE_PROXY_H
#endif //BT_BROADPHASE_PROXY_H

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_ALGORITHM_H
#define COLLISION_ALGORITHM_H
#ifndef BT_COLLISION_ALGORITHM_H
#define BT_COLLISION_ALGORITHM_H
#include "LinearMath/btScalar.h"
#include "LinearMath/btAlignedObjectArray.h"
@ -23,6 +23,7 @@ struct btBroadphaseProxy;
class btDispatcher;
class btManifoldResult;
class btCollisionObject;
struct btCollisionObjectWrapper;
struct btDispatcherInfo;
class btPersistentManifold;
@ -44,7 +45,7 @@ struct btCollisionAlgorithmConstructionInfo
btDispatcher* m_dispatcher1;
btPersistentManifold* m_manifold;
int getDispatcherId();
// int getDispatcherId();
};
@ -59,7 +60,7 @@ protected:
btDispatcher* m_dispatcher;
protected:
int getDispatcherId();
// int getDispatcherId();
public:
@ -69,7 +70,7 @@ public:
virtual ~btCollisionAlgorithm() {};
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
@ -77,4 +78,4 @@ public:
};
#endif //COLLISION_ALGORITHM_H
#endif //BT_COLLISION_ALGORITHM_H

View file

@ -61,7 +61,7 @@ static void getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth)
if(node->isinternal())
{
getmaxdepth(node->childs[0],depth+1,maxdepth);
getmaxdepth(node->childs[0],depth+1,maxdepth);
getmaxdepth(node->childs[1],depth+1,maxdepth);
} else maxdepth=btMax(maxdepth,depth);
}

View file

@ -32,7 +32,7 @@ subject to the following restrictions:
#define DBVT_IMPL_SSE 1 // SSE
// Template implementation of ICollide
#ifdef WIN32
#ifdef _WIN32
#if (defined (_MSC_VER) && _MSC_VER >= 1400)
#define DBVT_USE_TEMPLATE 1
#else
@ -57,7 +57,7 @@ subject to the following restrictions:
// Specific methods implementation
//SSE gives errors on a MSVC 7.1
#if defined (BT_USE_SSE) && defined (WIN32)
#if defined (BT_USE_SSE) //&& defined (_WIN32)
#define DBVT_SELECT_IMPL DBVT_IMPL_SSE
#define DBVT_MERGE_IMPL DBVT_IMPL_SSE
#define DBVT_INT0_IMPL DBVT_IMPL_SSE
@ -92,7 +92,7 @@ subject to the following restrictions:
#endif
#if DBVT_USE_MEMMOVE
#ifndef __CELLOS_LV2__
#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
#include <memory.h>
#endif
#include <string.h>
@ -160,6 +160,10 @@ struct btDbvtAabbMm
btDbvtAabbMm& r);
DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a,
const btDbvtAabbMm& b);
DBVT_INLINE btVector3& tMins() { return(mi); }
DBVT_INLINE btVector3& tMaxs() { return(mx); }
private:
DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
private:
@ -259,6 +263,7 @@ struct btDbvt
btAlignedObjectArray<sStkNN> m_stkStack;
mutable btAlignedObjectArray<const btDbvtNode*> m_rayTestStack;
// Methods
@ -319,7 +324,7 @@ struct btDbvt
DBVT_PREFIX
void collideTV( const btDbvtNode* root,
const btDbvtVolume& volume,
DBVT_IPOLICY);
DBVT_IPOLICY) const;
///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
DBVT_PREFIX
@ -518,7 +523,11 @@ DBVT_INLINE bool Intersect( const btDbvtAabbMm& a,
#if DBVT_INT0_IMPL == DBVT_IMPL_SSE
const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
_mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
#if defined (_WIN32)
const __int32* pu((const __int32*)&rt);
#else
const int* pu((const int*)&rt);
#endif
return((pu[0]|pu[1]|pu[2])==0);
#else
return( (a.mi.x()<=b.mx.x())&&
@ -567,7 +576,12 @@ DBVT_INLINE int Select( const btDbvtAabbMm& o,
const btDbvtAabbMm& b)
{
#if DBVT_SELECT_IMPL == DBVT_IMPL_SSE
#if defined (_WIN32)
static ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
#else
static ATTRIBUTE_ALIGNED16(const unsigned int) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x00000000 /*0x7fffffff*/};
#endif
///@todo: the intrinsic version is 11% slower
#if DBVT_USE_INTRINSIC_SSE
@ -907,7 +921,7 @@ inline void btDbvt::collideTT( const btDbvtNode* root0,
DBVT_PREFIX
inline void btDbvt::collideTV( const btDbvtNode* root,
const btDbvtVolume& vol,
DBVT_IPOLICY)
DBVT_IPOLICY) const
{
DBVT_CHECKTYPE
if(root)
@ -947,6 +961,7 @@ inline void btDbvt::rayTestInternal( const btDbvtNode* root,
const btVector3& aabbMax,
DBVT_IPOLICY) const
{
(void) rayTo;
DBVT_CHECKTYPE
if(root)
{
@ -954,15 +969,15 @@ inline void btDbvt::rayTestInternal( const btDbvtNode* root,
int depth=1;
int treshold=DOUBLE_STACKSIZE-2;
btAlignedObjectArray<const btDbvtNode*> stack;
btAlignedObjectArray<const btDbvtNode*>& stack = m_rayTestStack;
stack.resize(DOUBLE_STACKSIZE);
stack[0]=root;
btVector3 bounds[2];
do
{
const btDbvtNode* node=stack[--depth];
bounds[0] = node->volume.Mins()+aabbMin;
bounds[1] = node->volume.Maxs()+aabbMax;
bounds[0] = node->volume.Mins()-aabbMax;
bounds[1] = node->volume.Maxs()-aabbMin;
btScalar tmin=1.f,lambda_min=0.f;
unsigned int result1=false;
result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);

View file

@ -251,6 +251,33 @@ void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo,
}
struct BroadphaseAabbTester : btDbvt::ICollide
{
btBroadphaseAabbCallback& m_aabbCallback;
BroadphaseAabbTester(btBroadphaseAabbCallback& orgCallback)
:m_aabbCallback(orgCallback)
{
}
void Process(const btDbvtNode* leaf)
{
btDbvtProxy* proxy=(btDbvtProxy*)leaf->data;
m_aabbCallback.process(proxy);
}
};
void btDbvtBroadphase::aabbTest(const btVector3& aabbMin,const btVector3& aabbMax,btBroadphaseAabbCallback& aabbCallback)
{
BroadphaseAabbTester callback(aabbCallback);
const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(aabbMin,aabbMax);
//process all children, that overlap with the given AABB bounds
m_sets[0].collideTV(m_sets[0].m_root,bounds,callback);
m_sets[1].collideTV(m_sets[1].m_root,bounds,callback);
}
//
void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy,
const btVector3& aabbMin,
@ -318,6 +345,47 @@ void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy,
}
}
//
void btDbvtBroadphase::setAabbForceUpdate( btBroadphaseProxy* absproxy,
const btVector3& aabbMin,
const btVector3& aabbMax,
btDispatcher* /*dispatcher*/)
{
btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
bool docollide=false;
if(proxy->stage==STAGECOUNT)
{/* fixed -> dynamic set */
m_sets[1].remove(proxy->leaf);
proxy->leaf=m_sets[0].insert(aabb,proxy);
docollide=true;
}
else
{/* dynamic set */
++m_updates_call;
/* Teleporting */
m_sets[0].update(proxy->leaf,aabb);
++m_updates_done;
docollide=true;
}
listremove(proxy,m_stageRoots[proxy->stage]);
proxy->m_aabbMin = aabbMin;
proxy->m_aabbMax = aabbMax;
proxy->stage = m_stageCurrent;
listappend(proxy,m_stageRoots[m_stageCurrent]);
if(docollide)
{
m_needcleanup=true;
if(!m_deferedcollide)
{
btDbvtTreeCollider collider(this);
m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider);
m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider);
}
}
}
//
void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
{

View file

@ -102,20 +102,27 @@ struct btDbvtBroadphase : btBroadphaseInterface
~btDbvtBroadphase();
void collide(btDispatcher* dispatcher);
void optimize();
/* btBroadphaseInterface Implementation */
/* btBroadphaseInterface Implementation */
btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
void calculateOverlappingPairs(btDispatcher* dispatcher);
btOverlappingPairCache* getOverlappingPairCache();
const btOverlappingPairCache* getOverlappingPairCache() const;
void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
void printStats();
static void benchmark(btBroadphaseInterface*);
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
virtual btOverlappingPairCache* getOverlappingPairCache();
virtual const btOverlappingPairCache* getOverlappingPairCache() const;
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
virtual void printStats();
///reset broadphase internal structures, to ensure determinism/reproducability
virtual void resetPool(btDispatcher* dispatcher);
void performDeferredRemoval(btDispatcher* dispatcher);
void setVelocityPrediction(btScalar prediction)
{
m_prediction = prediction;
@ -124,11 +131,15 @@ struct btDbvtBroadphase : btBroadphaseInterface
{
return m_prediction;
}
void performDeferredRemoval(btDispatcher* dispatcher);
///reset broadphase internal structures, to ensure determinism/reproducability
virtual void resetPool(btDispatcher* dispatcher);
///this setAabbForceUpdate is similar to setAabb but always forces the aabb update.
///it is not part of the btBroadphaseInterface but specific to btDbvtBroadphase.
///it bypasses certain optimizations that prevent aabb updates (when the aabb shrinks), see
///http://code.google.com/p/bullet/issues/detail?id=223
void setAabbForceUpdate( btBroadphaseProxy* absproxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* /*dispatcher*/);
static void benchmark(btBroadphaseInterface*);
};

View file

@ -13,9 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _DISPATCHER_H
#define _DISPATCHER_H
#ifndef BT_DISPATCHER_H
#define BT_DISPATCHER_H
#include "LinearMath/btScalar.h"
class btCollisionAlgorithm;
@ -23,10 +22,11 @@ struct btBroadphaseProxy;
class btRigidBody;
class btCollisionObject;
class btOverlappingPairCache;
struct btCollisionObjectWrapper;
class btPersistentManifold;
class btStackAlloc;
class btPoolAllocator;
struct btDispatcherInfo
{
@ -40,7 +40,7 @@ struct btDispatcherInfo
m_stepCount(0),
m_dispatchFunc(DISPATCH_DISCRETE),
m_timeOfImpact(btScalar(1.)),
m_useContinuous(false),
m_useContinuous(true),
m_debugDraw(0),
m_enableSatConvex(false),
m_enableSPU(true),
@ -76,17 +76,17 @@ class btDispatcher
public:
virtual ~btDispatcher() ;
virtual btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold=0) = 0;
virtual btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold=0) = 0;
virtual btPersistentManifold* getNewManifold(void* body0,void* body1)=0;
virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1)=0;
virtual void releaseManifold(btPersistentManifold* manifold)=0;
virtual void clearManifold(btPersistentManifold* manifold)=0;
virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1) = 0;
virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1) = 0;
virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0;
virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1)=0;
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) =0;
@ -96,6 +96,10 @@ public:
virtual btPersistentManifold** getInternalManifoldPointer() = 0;
virtual btPoolAllocator* getInternalManifoldPool() = 0;
virtual const btPoolAllocator* getInternalManifoldPool() const = 0;
virtual void* allocateCollisionAlgorithm(int size) = 0;
virtual void freeCollisionAlgorithm(void* ptr) = 0;
@ -103,4 +107,4 @@ public:
};
#endif //_DISPATCHER_H
#endif //BT_DISPATCHER_H

View file

@ -341,7 +341,7 @@ class btMultiSapBroadphasePairSortPredicate
{
public:
bool operator() ( const btBroadphasePair& a1, const btBroadphasePair& b1 )
bool operator() ( const btBroadphasePair& a1, const btBroadphasePair& b1 ) const
{
btMultiSapBroadphase::btMultiSapProxy* aProxy0 = a1.m_pProxy0 ? (btMultiSapBroadphase::btMultiSapProxy*)a1.m_pProxy0->m_multiSapParentProxy : 0;
btMultiSapBroadphase::btMultiSapProxy* aProxy1 = a1.m_pProxy1 ? (btMultiSapBroadphase::btMultiSapProxy*)a1.m_pProxy1->m_multiSapParentProxy : 0;

View file

@ -240,7 +240,7 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
}*/
int count = m_overlappingPairArray.size();
int oldCapacity = m_overlappingPairArray.capacity();
void* mem = &m_overlappingPairArray.expand();
void* mem = &m_overlappingPairArray.expandNonInitializing();
//this is where we add an actual pair, so also call the 'ghost'
if (m_ghostPairCallback)
@ -467,7 +467,7 @@ btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseP
if (!needsBroadphaseCollision(proxy0,proxy1))
return 0;
void* mem = &m_overlappingPairArray.expand();
void* mem = &m_overlappingPairArray.expandNonInitializing();
btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
gOverlappingPairs++;

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OVERLAPPING_PAIR_CACHE_H
#define OVERLAPPING_PAIR_CACHE_H
#ifndef BT_OVERLAPPING_PAIR_CACHE_H
#define BT_OVERLAPPING_PAIR_CACHE_H
#include "btBroadphaseInterface.h"
@ -457,12 +457,13 @@ public:
virtual void sortOverlappingPairs(btDispatcher* dispatcher)
{
(void) dispatcher;
}
};
#endif //OVERLAPPING_PAIR_CACHE_H
#endif //BT_OVERLAPPING_PAIR_CACHE_H

View file

@ -17,6 +17,7 @@ subject to the following restrictions:
#include "LinearMath/btAabbUtil2.h"
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btSerializer.h"
#define RAYAABB2
@ -78,10 +79,10 @@ void btQuantizedBvh::buildInternal()
#ifdef DEBUG_PATCH_COLORS
btVector3 color[4]=
{
btVector3(255,0,0),
btVector3(0,255,0),
btVector3(0,0,255),
btVector3(0,255,255)
btVector3(1,0,0),
btVector3(0,1,0),
btVector3(0,0,1),
btVector3(0,1,1)
};
#endif //DEBUG_PATCH_COLORS
@ -493,8 +494,8 @@ void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall
bounds[0] = rootNode->m_aabbMinOrg;
bounds[1] = rootNode->m_aabbMaxOrg;
/* Add box cast extents */
bounds[0] += aabbMin;
bounds[1] += aabbMax;
bounds[0] -= aabbMax;
bounds[1] -= aabbMin;
aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
//perhaps profile if it is worth doing the aabbOverlap test first
@ -617,8 +618,8 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
bounds[0] = unQuantize(rootNode->m_quantizedAabbMin);
bounds[1] = unQuantize(rootNode->m_quantizedAabbMax);
/* Add box cast extents */
bounds[0] += aabbMin;
bounds[1] += aabbMax;
bounds[0] -= aabbMax;
bounds[1] -= aabbMin;
btVector3 normal;
#if 0
bool ra2 = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max);
@ -830,7 +831,7 @@ unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
}
unsigned btQuantizedBvh::calculateSerializeBufferSize()
unsigned btQuantizedBvh::calculateSerializeBufferSize() const
{
unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding();
baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
@ -841,7 +842,7 @@ unsigned btQuantizedBvh::calculateSerializeBufferSize()
return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode);
}
bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian)
bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const
{
btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
m_subtreeHeaderCount = m_SubtreeHeaders.size();
@ -1143,6 +1144,232 @@ m_bulletVersion(BT_BULLET_VERSION)
}
void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData)
{
m_bvhAabbMax.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMax);
m_bvhAabbMin.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMin);
m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization);
m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex;
m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0;
{
int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes;
m_contiguousNodes.resize(numElem);
if (numElem)
{
btOptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_contiguousNodes[i].m_aabbMaxOrg.deSerializeFloat(memPtr->m_aabbMaxOrg);
m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg);
m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
}
}
}
{
int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes;
m_quantizedContiguousNodes.resize(numElem);
if (numElem)
{
btQuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
}
}
}
m_traversalMode = btTraversalMode(quantizedBvhFloatData.m_traversalMode);
{
int numElem = quantizedBvhFloatData.m_numSubtreeHeaders;
m_SubtreeHeaders.resize(numElem);
if (numElem)
{
btBvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
}
}
}
}
void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData)
{
m_bvhAabbMax.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMax);
m_bvhAabbMin.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMin);
m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization);
m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex;
m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0;
{
int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes;
m_contiguousNodes.resize(numElem);
if (numElem)
{
btOptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_contiguousNodes[i].m_aabbMaxOrg.deSerializeDouble(memPtr->m_aabbMaxOrg);
m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg);
m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
}
}
}
{
int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes;
m_quantizedContiguousNodes.resize(numElem);
if (numElem)
{
btQuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
}
}
}
m_traversalMode = btTraversalMode(quantizedBvhDoubleData.m_traversalMode);
{
int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders;
m_SubtreeHeaders.resize(numElem);
if (numElem)
{
btBvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
}
}
}
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const
{
btQuantizedBvhData* quantizedData = (btQuantizedBvhData*)dataBuffer;
m_bvhAabbMax.serialize(quantizedData->m_bvhAabbMax);
m_bvhAabbMin.serialize(quantizedData->m_bvhAabbMin);
m_bvhQuantization.serialize(quantizedData->m_bvhQuantization);
quantizedData->m_curNodeIndex = m_curNodeIndex;
quantizedData->m_useQuantization = m_useQuantization;
quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size();
quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0);
if (quantizedData->m_contiguousNodesPtr)
{
int sz = sizeof(btOptimizedBvhNodeData);
int numElem = m_contiguousNodes.size();
btChunk* chunk = serializer->allocate(sz,numElem);
btOptimizedBvhNodeData* memPtr = (btOptimizedBvhNodeData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_contiguousNodes[i].m_aabbMaxOrg.serialize(memPtr->m_aabbMaxOrg);
m_contiguousNodes[i].m_aabbMinOrg.serialize(memPtr->m_aabbMinOrg);
memPtr->m_escapeIndex = m_contiguousNodes[i].m_escapeIndex;
memPtr->m_subPart = m_contiguousNodes[i].m_subPart;
memPtr->m_triangleIndex = m_contiguousNodes[i].m_triangleIndex;
}
serializer->finalizeChunk(chunk,"btOptimizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_contiguousNodes[0]);
}
quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size();
// printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes);
quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0);
if (quantizedData->m_quantizedContiguousNodesPtr)
{
int sz = sizeof(btQuantizedBvhNodeData);
int numElem = m_quantizedContiguousNodes.size();
btChunk* chunk = serializer->allocate(sz,numElem);
btQuantizedBvhNodeData* memPtr = (btQuantizedBvhNodeData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
memPtr->m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex;
memPtr->m_quantizedAabbMax[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[0];
memPtr->m_quantizedAabbMax[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[1];
memPtr->m_quantizedAabbMax[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[2];
memPtr->m_quantizedAabbMin[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[0];
memPtr->m_quantizedAabbMin[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[1];
memPtr->m_quantizedAabbMin[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[2];
}
serializer->finalizeChunk(chunk,"btQuantizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_quantizedContiguousNodes[0]);
}
quantizedData->m_traversalMode = int(m_traversalMode);
quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size();
quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0);
if (quantizedData->m_subTreeInfoPtr)
{
int sz = sizeof(btBvhSubtreeInfoData);
int numElem = m_SubtreeHeaders.size();
btChunk* chunk = serializer->allocate(sz,numElem);
btBvhSubtreeInfoData* memPtr = (btBvhSubtreeInfoData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
memPtr->m_quantizedAabbMax[0] = m_SubtreeHeaders[i].m_quantizedAabbMax[0];
memPtr->m_quantizedAabbMax[1] = m_SubtreeHeaders[i].m_quantizedAabbMax[1];
memPtr->m_quantizedAabbMax[2] = m_SubtreeHeaders[i].m_quantizedAabbMax[2];
memPtr->m_quantizedAabbMin[0] = m_SubtreeHeaders[i].m_quantizedAabbMin[0];
memPtr->m_quantizedAabbMin[1] = m_SubtreeHeaders[i].m_quantizedAabbMin[1];
memPtr->m_quantizedAabbMin[2] = m_SubtreeHeaders[i].m_quantizedAabbMin[2];
memPtr->m_rootNodeIndex = m_SubtreeHeaders[i].m_rootNodeIndex;
memPtr->m_subtreeSize = m_SubtreeHeaders[i].m_subtreeSize;
}
serializer->finalizeChunk(chunk,"btBvhSubtreeInfoData",BT_ARRAY_CODE,(void*)&m_SubtreeHeaders[0]);
}
return btQuantizedBvhDataName;
}

View file

@ -13,8 +13,10 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef QUANTIZED_BVH_H
#define QUANTIZED_BVH_H
#ifndef BT_QUANTIZED_BVH_H
#define BT_QUANTIZED_BVH_H
class btSerializer;
//#define DEBUG_CHECK_DEQUANTIZATION 1
#ifdef DEBUG_CHECK_DEQUANTIZATION
@ -29,6 +31,17 @@ subject to the following restrictions:
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedAllocator.h"
#ifdef BT_USE_DOUBLE_PRECISION
#define btQuantizedBvhData btQuantizedBvhDoubleData
#define btOptimizedBvhNodeData btOptimizedBvhNodeDoubleData
#define btQuantizedBvhDataName "btQuantizedBvhDoubleData"
#else
#define btQuantizedBvhData btQuantizedBvhFloatData
#define btOptimizedBvhNodeData btOptimizedBvhNodeFloatData
#define btQuantizedBvhDataName "btQuantizedBvhFloatData"
#endif
//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp
@ -65,8 +78,10 @@ ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode
int getTriangleIndex() const
{
btAssert(isLeafNode());
unsigned int x=0;
unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
// Get only the lower bits where the triangle index is stored
return (m_escapeIndexOrTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
return (m_escapeIndexOrTriangleIndex&~(y));
}
int getPartId() const
{
@ -94,9 +109,9 @@ ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode
//for child nodes
int m_subPart;
int m_triangleIndex;
int m_padding[5];//bad, due to alignment
//pad the size to 64 bytes
char m_padding[20];
};
@ -190,7 +205,7 @@ protected:
BvhSubtreeInfoArray m_SubtreeHeaders;
//This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
int m_subtreeHeaderCount;
mutable int m_subtreeHeaderCount;
@ -443,17 +458,32 @@ public:
return m_SubtreeHeaders;
}
////////////////////////////////////////////////////////////////////
/////Calculate space needed to store BVH for serialization
unsigned calculateSerializeBufferSize();
unsigned calculateSerializeBufferSize() const;
/// Data buffer MUST be 16 byte aligned
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian);
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const;
///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);
static unsigned int getAlignmentSerializationPadding();
//////////////////////////////////////////////////////////////////////
virtual int calculateSerializeBufferSizeNew() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
virtual void deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData);
virtual void deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData);
////////////////////////////////////////////////////////////////////
SIMD_FORCE_INLINE bool isQuantized()
{
@ -470,4 +500,82 @@ private:
;
#endif //QUANTIZED_BVH_H
struct btBvhSubtreeInfoData
{
int m_rootNodeIndex;
int m_subtreeSize;
unsigned short m_quantizedAabbMin[3];
unsigned short m_quantizedAabbMax[3];
};
struct btOptimizedBvhNodeFloatData
{
btVector3FloatData m_aabbMinOrg;
btVector3FloatData m_aabbMaxOrg;
int m_escapeIndex;
int m_subPart;
int m_triangleIndex;
char m_pad[4];
};
struct btOptimizedBvhNodeDoubleData
{
btVector3DoubleData m_aabbMinOrg;
btVector3DoubleData m_aabbMaxOrg;
int m_escapeIndex;
int m_subPart;
int m_triangleIndex;
char m_pad[4];
};
struct btQuantizedBvhNodeData
{
unsigned short m_quantizedAabbMin[3];
unsigned short m_quantizedAabbMax[3];
int m_escapeIndexOrTriangleIndex;
};
struct btQuantizedBvhFloatData
{
btVector3FloatData m_bvhAabbMin;
btVector3FloatData m_bvhAabbMax;
btVector3FloatData m_bvhQuantization;
int m_curNodeIndex;
int m_useQuantization;
int m_numContiguousLeafNodes;
int m_numQuantizedContiguousNodes;
btOptimizedBvhNodeFloatData *m_contiguousNodesPtr;
btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr;
btBvhSubtreeInfoData *m_subTreeInfoPtr;
int m_traversalMode;
int m_numSubtreeHeaders;
};
struct btQuantizedBvhDoubleData
{
btVector3DoubleData m_bvhAabbMin;
btVector3DoubleData m_bvhAabbMax;
btVector3DoubleData m_bvhQuantization;
int m_curNodeIndex;
int m_useQuantization;
int m_numContiguousLeafNodes;
int m_numQuantizedContiguousNodes;
btOptimizedBvhNodeDoubleData *m_contiguousNodesPtr;
btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr;
int m_traversalMode;
int m_numSubtreeHeaders;
btBvhSubtreeInfoData *m_subTreeInfoPtr;
};
SIMD_FORCE_INLINE int btQuantizedBvh::calculateSerializeBufferSizeNew() const
{
return sizeof(btQuantizedBvhData);
}
#endif //BT_QUANTIZED_BVH_H

View file

@ -20,6 +20,8 @@ subject to the following restrictions:
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include "LinearMath/btAabbUtil2.h"
#include <new>
extern int gOverlappingPairs;
@ -166,6 +168,23 @@ void btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo
}
void btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
{
for (int i=0; i <= m_LastHandleIndex; i++)
{
btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
if(!proxy->m_clientObject)
{
continue;
}
if (TestAabbAgainstAabb2(aabbMin,aabbMax,proxy->m_aabbMin,proxy->m_aabbMax))
{
callback.process(proxy);
}
}
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SIMPLE_BROADPHASE_H
#define SIMPLE_BROADPHASE_H
#ifndef BT_SIMPLE_BROADPHASE_H
#define BT_SIMPLE_BROADPHASE_H
#include "btOverlappingPairCache.h"
@ -136,6 +136,7 @@ public:
virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
btOverlappingPairCache* getOverlappingPairCache()
{
@ -166,5 +167,5 @@ public:
#endif //SIMPLE_BROADPHASE_H
#endif //BT_SIMPLE_BROADPHASE_H

View file

@ -1,4 +1,4 @@
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src } )
INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src )
SET(BulletCollision_SRCS
BroadphaseCollision/btAxisSweep3.cpp
@ -26,6 +26,8 @@ SET(BulletCollision_SRCS
CollisionDispatch/btDefaultCollisionConfiguration.cpp
CollisionDispatch/btEmptyCollisionAlgorithm.cpp
CollisionDispatch/btGhostObject.cpp
CollisionDispatch/btInternalEdgeUtility.cpp
CollisionDispatch/btInternalEdgeUtility.h
CollisionDispatch/btManifoldResult.cpp
CollisionDispatch/btSimulationIslandManager.cpp
CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
@ -44,6 +46,7 @@ SET(BulletCollision_SRCS
CollisionShapes/btConvexHullShape.cpp
CollisionShapes/btConvexInternalShape.cpp
CollisionShapes/btConvexPointCloudShape.cpp
CollisionShapes/btConvexPolyhedron.cpp
CollisionShapes/btConvexShape.cpp
CollisionShapes/btConvex2dShape.cpp
CollisionShapes/btConvexTriangleMeshShape.cpp
@ -90,6 +93,7 @@ SET(BulletCollision_SRCS
NarrowPhaseCollision/btRaycastCallback.cpp
NarrowPhaseCollision/btSubSimplexConvexCast.cpp
NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
NarrowPhaseCollision/btPolyhedralContactClipping.cpp
)
SET(Root_HDRS
@ -148,6 +152,7 @@ SET(CollisionShapes_HDRS
CollisionShapes/btConvexHullShape.h
CollisionShapes/btConvexInternalShape.h
CollisionShapes/btConvexPointCloudShape.h
CollisionShapes/btConvexPolyhedron.h
CollisionShapes/btConvexShape.h
CollisionShapes/btConvex2dShape.h
CollisionShapes/btConvexTriangleMeshShape.h
@ -170,6 +175,7 @@ SET(CollisionShapes_HDRS
CollisionShapes/btTriangleCallback.h
CollisionShapes/btTriangleIndexVertexArray.h
CollisionShapes/btTriangleIndexVertexMaterialArray.h
CollisionShapes/btTriangleInfoMap.h
CollisionShapes/btTriangleMesh.h
CollisionShapes/btTriangleMeshShape.h
CollisionShapes/btTriangleShape.h
@ -221,6 +227,7 @@ SET(NarrowPhaseCollision_HDRS
NarrowPhaseCollision/btSimplexSolverInterface.h
NarrowPhaseCollision/btSubSimplexConvexCast.h
NarrowPhaseCollision/btVoronoiSimplexSolver.h
NarrowPhaseCollision/btPolyhedralContactClipping.h
)
SET(BulletCollision_HDRS
@ -241,27 +248,32 @@ IF (BUILD_SHARED_LIBS)
ENDIF (BUILD_SHARED_LIBS)
#INSTALL of other files requires CMake 2.6
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
INSTALL(TARGETS BulletCollision DESTINATION .)
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
INSTALL(TARGETS BulletCollision DESTINATION lib)
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
SET_TARGET_PROPERTIES(BulletCollision PROPERTIES FRAMEWORK true)
SET_TARGET_PROPERTIES(BulletCollision PROPERTIES PUBLIC_HEADER "${Root_HDRS}")
# Have to list out sub-directories manually:
SET_PROPERTY(SOURCE ${BroadphaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/BroadphaseCollision)
SET_PROPERTY(SOURCE ${CollisionDispatch_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionDispatch)
SET_PROPERTY(SOURCE ${CollisionShapes_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionShapes)
SET_PROPERTY(SOURCE ${Gimpact_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Gimpact)
SET_PROPERTY(SOURCE ${NarrowPhaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/NarrowPhaseCollision)
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
IF (INSTALL_LIBS)
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
#INSTALL of other files requires CMake 2.6
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
INSTALL(TARGETS BulletCollision DESTINATION .)
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
INSTALL(TARGETS BulletCollision DESTINATION lib${LIB_SUFFIX})
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE PATTERN "CMakeFiles" EXCLUDE)
INSTALL(FILES ../btBulletCollisionCommon.h
DESTINATION ${INCLUDE_INSTALL_DIR}/BulletCollision)
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
SET_TARGET_PROPERTIES(BulletCollision PROPERTIES FRAMEWORK true)
SET_TARGET_PROPERTIES(BulletCollision PROPERTIES PUBLIC_HEADER "${Root_HDRS}")
# Have to list out sub-directories manually:
SET_PROPERTY(SOURCE ${BroadphaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/BroadphaseCollision)
SET_PROPERTY(SOURCE ${CollisionDispatch_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionDispatch)
SET_PROPERTY(SOURCE ${CollisionShapes_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionShapes)
SET_PROPERTY(SOURCE ${Gimpact_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Gimpact)
SET_PROPERTY(SOURCE ${NarrowPhaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/NarrowPhaseCollision)
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
ENDIF (INSTALL_LIBS)

View file

@ -57,8 +57,6 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
}
#define MAX_OVERLAP btScalar(0.)
// See also geometrictools.com
@ -93,48 +91,39 @@ bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* ve
return pointInTriangle(vertices, lnormal, &lp);
}
///combined discrete/continuous sphere-triangle
bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
{
const btVector3* vertices = &m_triangle->getVertexPtr(0);
const btVector3& c = sphereCenter;
btScalar r = m_sphere->getRadius();
btVector3 delta (0,0,0);
btScalar radius = m_sphere->getRadius();
btScalar radiusWithThreshold = radius + contactBreakingThreshold;
btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
normal.normalize();
btVector3 p1ToCentre = c - vertices[0];
btVector3 p1ToCentre = sphereCenter - vertices[0];
btScalar distanceFromPlane = p1ToCentre.dot(normal);
if (distanceFromPlane < btScalar(0.))
{
//triangle facing the other way
distanceFromPlane *= btScalar(-1.);
normal *= btScalar(-1.);
}
btScalar contactMargin = contactBreakingThreshold;
bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
bool isInsideShellPlane = distanceFromPlane < r;
bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold;
btScalar deltaDotNormal = delta.dot(normal);
if (!isInsideShellPlane && deltaDotNormal >= btScalar(0.0))
return false;
// Check for contact / intersection
bool hasContact = false;
btVector3 contactPoint;
if (isInsideContactPlane) {
if (facecontains(c,vertices,normal)) {
if (facecontains(sphereCenter,vertices,normal)) {
// Inside the contact wedge - touches a point on the shell plane
hasContact = true;
contactPoint = c - normal*distanceFromPlane;
contactPoint = sphereCenter - normal*distanceFromPlane;
} else {
// Could be inside one of the contact capsules
btScalar contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
btScalar contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold;
btVector3 nearestOnEdge;
for (int i = 0; i < m_triangle->getNumEdges(); i++) {
@ -143,7 +132,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
m_triangle->getEdge(i,pa,pb);
btScalar distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge);
btScalar distanceSqr = SegmentSqrDistance(pa,pb,sphereCenter, nearestOnEdge);
if (distanceSqr < contactCapsuleRadiusSqr) {
// Yep, we're inside a capsule
hasContact = true;
@ -155,24 +144,26 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
}
if (hasContact) {
btVector3 contactToCentre = c - contactPoint;
btVector3 contactToCentre = sphereCenter - contactPoint;
btScalar distanceSqr = contactToCentre.length2();
if (distanceSqr < (r - MAX_OVERLAP)*(r - MAX_OVERLAP)) {
btScalar distance = btSqrt(distanceSqr);
resultNormal = contactToCentre;
resultNormal.normalize();
point = contactPoint;
depth = -(r-distance);
if (distanceSqr < radiusWithThreshold*radiusWithThreshold)
{
if (distanceSqr>SIMD_EPSILON)
{
btScalar distance = btSqrt(distanceSqr);
resultNormal = contactToCentre;
resultNormal.normalize();
point = contactPoint;
depth = -(radius-distance);
} else
{
resultNormal = normal;
point = contactPoint;
depth = -radius;
}
return true;
}
if (delta.dot(contactToCentre) >= btScalar(0.0))
return false;
// Moving towards the contact point -> collision
point = contactPoint;
timeOfImpact = btScalar(0.0);
return true;
}
return false;

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_TRIANGLE_DETECTOR_H
#define SPHERE_TRIANGLE_DETECTOR_H
#ifndef BT_SPHERE_TRIANGLE_DETECTOR_H
#define BT_SPHERE_TRIANGLE_DETECTOR_H
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
@ -34,9 +34,11 @@ struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
virtual ~SphereTriangleDetector() {};
bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold);
private:
bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold);
bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);
@ -45,5 +47,5 @@ private:
btScalar m_contactBreakingThreshold;
};
#endif //SPHERE_TRIANGLE_DETECTOR_H
#endif //BT_SPHERE_TRIANGLE_DETECTOR_H

View file

@ -24,7 +24,7 @@ btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisio
//m_colObj1(0)
{
}
btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1)
btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* )
:btCollisionAlgorithm(ci)
//,
//m_colObj0(0),

View file

@ -28,7 +28,7 @@ public:
btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci);
btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1);
btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btActivatingCollisionAlgorithm();

View file

@ -22,17 +22,18 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionDispatch/btBoxBoxDetector.h"
#include "BulletCollision/CollisionShapes/btBox2dShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
#define USE_PERSISTENT_CONTACTS 1
btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
: btActivatingCollisionAlgorithm(ci,obj0,obj1),
btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* obj0Wrap,const btCollisionObjectWrapper* obj1Wrap)
: btActivatingCollisionAlgorithm(ci,obj0Wrap,obj1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf)
{
if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0Wrap->getCollisionObject(),obj1Wrap->getCollisionObject()))
{
m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
m_manifoldPtr = m_dispatcher->getNewManifold(obj0Wrap->getCollisionObject(),obj1Wrap->getCollisionObject());
m_ownManifold = true;
}
}
@ -52,19 +53,18 @@ btBox2dBox2dCollisionAlgorithm::~btBox2dBox2dCollisionAlgorithm()
void b2CollidePolygons(btManifoldResult* manifold, const btBox2dShape* polyA, const btTransform& xfA, const btBox2dShape* polyB, const btTransform& xfB);
//#include <stdio.h>
void btBox2dBox2dCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btBox2dBox2dCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
return;
btCollisionObject* col0 = body0;
btCollisionObject* col1 = body1;
btBox2dShape* box0 = (btBox2dShape*)col0->getCollisionShape();
btBox2dShape* box1 = (btBox2dShape*)col1->getCollisionShape();
const btBox2dShape* box0 = (const btBox2dShape*)body0Wrap->getCollisionShape();
const btBox2dShape* box1 = (const btBox2dShape*)body1Wrap->getCollisionShape();
resultOut->setPersistentManifold(m_manifoldPtr);
b2CollidePolygons(resultOut,box0,col0->getWorldTransform(),box1,col1->getWorldTransform());
b2CollidePolygons(resultOut,box0,body0Wrap->getWorldTransform(),box1,body1Wrap->getWorldTransform());
// refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added
if (m_ownManifold)
@ -135,14 +135,13 @@ static int ClipSegmentToLine(ClipVertex vOut[2], ClipVertex vIn[2],
static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1, int edge1,
const btBox2dShape* poly2, const btTransform& xf2)
{
int count1 = poly1->getVertexCount();
const btVector3* vertices1 = poly1->getVertices();
const btVector3* normals1 = poly1->getNormals();
int count2 = poly2->getVertexCount();
const btVector3* vertices2 = poly2->getVertices();
btAssert(0 <= edge1 && edge1 < count1);
btAssert(0 <= edge1 && edge1 < poly1->getVertexCount());
// Convert normal from poly1's frame into poly2's frame.
btVector3 normal1World = b2Mul(xf1.getBasis(), normals1[edge1]);
@ -152,15 +151,8 @@ static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1
int index = 0;
btScalar minDot = BT_LARGE_FLOAT;
for (int i = 0; i < count2; ++i)
{
btScalar dot = b2Dot(vertices2[i], normal1);
if (dot < minDot)
{
minDot = dot;
index = i;
}
}
if( count2 > 0 )
index = (int) normal1.minDot( vertices2, count2, minDot);
btVector3 v1 = b2Mul(xf1, vertices1[edge1]);
btVector3 v2 = b2Mul(xf2, vertices2[index]);
@ -182,16 +174,9 @@ static btScalar FindMaxSeparation(int* edgeIndex,
// Find edge normal on poly1 that has the largest projection onto d.
int edge = 0;
btScalar maxDot = -BT_LARGE_FLOAT;
for (int i = 0; i < count1; ++i)
{
btScalar dot = b2Dot(normals1[i], dLocal1);
if (dot > maxDot)
{
maxDot = dot;
edge = i;
}
}
btScalar maxDot;
if( count1 > 0 )
edge = (int) dLocal1.maxDot( normals1, count1, maxDot);
// Get the separation for the edge normal.
btScalar s = EdgeSeparation(poly1, xf1, edge, poly2, xf2);
@ -271,14 +256,13 @@ static void FindIncidentEdge(ClipVertex c[2],
const btBox2dShape* poly1, const btTransform& xf1, int edge1,
const btBox2dShape* poly2, const btTransform& xf2)
{
int count1 = poly1->getVertexCount();
const btVector3* normals1 = poly1->getNormals();
int count2 = poly2->getVertexCount();
const btVector3* vertices2 = poly2->getVertices();
const btVector3* normals2 = poly2->getNormals();
btAssert(0 <= edge1 && edge1 < count1);
btAssert(0 <= edge1 && edge1 < poly1->getVertexCount());
// Get the normal of the reference edge in poly2's frame.
btVector3 normal1 = b2MulT(xf2.getBasis(), b2Mul(xf1.getBasis(), normals1[edge1]));
@ -370,7 +354,7 @@ void b2CollidePolygons(btManifoldResult* manifold,
btVector3 v11 = vertices1[edge1];
btVector3 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0];
btVector3 dv = v12 - v11;
//btVector3 dv = v12 - v11;
btVector3 sideNormal = b2Mul(xf1.getBasis(), v12 - v11);
sideNormal.normalize();
btVector3 frontNormal = btCrossS(sideNormal, 1.0f);

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#define BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#ifndef BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#define BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@ -33,11 +33,11 @@ public:
btBox2dBox2dCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btActivatingCollisionAlgorithm(ci) {}
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btBox2dBox2dCollisionAlgorithm();
@ -52,15 +52,15 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
int bbsize = sizeof(btBox2dBox2dCollisionAlgorithm);
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
return new(ptr) btBox2dBox2dCollisionAlgorithm(0,ci,body0,body1);
return new(ptr) btBox2dBox2dCollisionAlgorithm(0,ci,body0Wrap,body1Wrap);
}
};
};
#endif //BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
#endif //BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H

View file

@ -18,17 +18,17 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btBoxShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "btBoxBoxDetector.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
#define USE_PERSISTENT_CONTACTS 1
btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
: btActivatingCollisionAlgorithm(ci,obj0,obj1),
btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf)
{
if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
if (!m_manifoldPtr && m_dispatcher->needsCollision(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()))
{
m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
m_ownManifold = true;
}
}
@ -42,15 +42,14 @@ btBoxBoxCollisionAlgorithm::~btBoxBoxCollisionAlgorithm()
}
}
void btBoxBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btBoxBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
return;
btCollisionObject* col0 = body0;
btCollisionObject* col1 = body1;
btBoxShape* box0 = (btBoxShape*)col0->getCollisionShape();
btBoxShape* box1 = (btBoxShape*)col1->getCollisionShape();
const btBoxShape* box0 = (btBoxShape*)body0Wrap->getCollisionShape();
const btBoxShape* box1 = (btBoxShape*)body1Wrap->getCollisionShape();
@ -62,8 +61,8 @@ void btBoxBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCo
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
input.m_transformA = body0Wrap->getWorldTransform();
input.m_transformB = body1Wrap->getWorldTransform();
btBoxBoxDetector detector(box0,box1);
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BOX_BOX__COLLISION_ALGORITHM_H
#define BOX_BOX__COLLISION_ALGORITHM_H
#ifndef BT_BOX_BOX__COLLISION_ALGORITHM_H
#define BT_BOX_BOX__COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@ -33,11 +33,11 @@ public:
btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btActivatingCollisionAlgorithm(ci) {}
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btBoxBoxCollisionAlgorithm();
@ -52,15 +52,15 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
int bbsize = sizeof(btBoxBoxCollisionAlgorithm);
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
return new(ptr) btBoxBoxCollisionAlgorithm(0,ci,body0,body1);
return new(ptr) btBoxBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap);
}
};
};
#endif //BOX_BOX__COLLISION_ALGORITHM_H
#endif //BT_BOX_BOX__COLLISION_ALGORITHM_H

View file

@ -1,4 +1,3 @@
/*
* Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith
* Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.
@ -25,7 +24,7 @@ subject to the following restrictions:
#include <float.h>
#include <string.h>
btBoxBoxDetector::btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2)
btBoxBoxDetector::btBoxBoxDetector(const btBoxShape* box1,const btBoxShape* box2)
: m_box1(box1),
m_box2(box2)
{
@ -333,9 +332,9 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
#undef TST
#define TST(expr1,expr2,n1,n2,n3,cc) \
s2 = btFabs(expr1) - (expr2); \
if (s2 > 0) return 0; \
if (s2 > SIMD_EPSILON) return 0; \
l = btSqrt((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \
if (l > 0) { \
if (l > SIMD_EPSILON) { \
s2 /= l; \
if (s2*fudge_factor > s) { \
s = s2; \
@ -346,6 +345,20 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
} \
}
btScalar fudge2 (1.0e-5f);
Q11 += fudge2;
Q12 += fudge2;
Q13 += fudge2;
Q21 += fudge2;
Q22 += fudge2;
Q23 += fudge2;
Q31 += fudge2;
Q32 += fudge2;
Q33 += fudge2;
// separating axis = u1 x (v1,v2,v3)
TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7);
TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8);
@ -424,6 +437,7 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
output.addContactPoint(-normal,pointInWorld,-*depth);
#else
output.addContactPoint(-normal,pb,-*depth);
#endif //
*return_code = code;
}
@ -593,21 +607,30 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
if (maxc < 1) maxc = 1;
if (cnum <= maxc) {
if (code<4)
{
// we have less contacts than we need, so we use them all
for (j=0; j < cnum; j++) {
//AddContactPoint...
//dContactGeom *con = CONTACT(contact,skip*j);
//for (i=0; i<3; i++) con->pos[i] = point[j*3+i] + pa[i];
//con->depth = dep[j];
for (j=0; j < cnum; j++)
{
btVector3 pointInWorld;
for (i=0; i<3; i++)
pointInWorld[i] = point[j*3+i] + pa[i];
output.addContactPoint(-normal,pointInWorld,-dep[j]);
}
} else
{
// we have less contacts than we need, so we use them all
for (j=0; j < cnum; j++)
{
btVector3 pointInWorld;
for (i=0; i<3; i++)
pointInWorld[i] = point[j*3+i] + pa[i]-normal[i]*dep[j];
//pointInWorld[i] = point[j*3+i] + pa[i];
output.addContactPoint(-normal,pointInWorld,-dep[j]);
}
}
}
else {
// we have more contacts than are wanted, some of them must be culled.
@ -632,7 +655,13 @@ int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
btVector3 posInWorld;
for (i=0; i<3; i++)
posInWorld[i] = point[iret[j]*3+i] + pa[i];
output.addContactPoint(-normal,posInWorld,-dep[iret[j]]);
if (code<4)
{
output.addContactPoint(-normal,posInWorld,-dep[iret[j]]);
} else
{
output.addContactPoint(-normal,posInWorld-normal*dep[iret[j]],-dep[iret[j]]);
}
}
cnum = maxc;
}

View file

@ -16,8 +16,8 @@ subject to the following restrictions:
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 BOX_BOX_DETECTOR_H
#define BOX_BOX_DETECTOR_H
#ifndef BT_BOX_BOX_DETECTOR_H
#define BT_BOX_BOX_DETECTOR_H
class btBoxShape;
@ -28,12 +28,12 @@ class btBoxShape;
/// re-distributed under the Zlib license with permission from Russell L. Smith
struct btBoxBoxDetector : public btDiscreteCollisionDetectorInterface
{
btBoxShape* m_box1;
btBoxShape* m_box2;
const btBoxShape* m_box1;
const btBoxShape* m_box2;
public:
btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2);
btBoxBoxDetector(const btBoxShape* box1,const btBoxShape* box2);
virtual ~btBoxBoxDetector() {};

View file

@ -15,6 +15,7 @@ subject to the following restrictions:
#ifndef BT_COLLISION_CONFIGURATION
#define BT_COLLISION_CONFIGURATION
struct btCollisionAlgorithmCreateFunc;
class btStackAlloc;

View file

@ -13,13 +13,13 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_CREATE_FUNC
#define COLLISION_CREATE_FUNC
#ifndef BT_COLLISION_CREATE_FUNC
#define BT_COLLISION_CREATE_FUNC
#include "LinearMath/btAlignedObjectArray.h"
class btCollisionAlgorithm;
class btCollisionObject;
struct btCollisionObjectWrapper;
struct btCollisionAlgorithmConstructionInfo;
///Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm
@ -33,13 +33,13 @@ struct btCollisionAlgorithmCreateFunc
}
virtual ~btCollisionAlgorithmCreateFunc(){};
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
(void)body0;
(void)body1;
(void)body0Wrap;
(void)body1Wrap;
return 0;
}
};
#endif //COLLISION_CREATE_FUNC
#endif //BT_COLLISION_CREATE_FUNC

View file

@ -25,6 +25,7 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include "LinearMath/btPoolAllocator.h"
#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
int gNumManifold = 0;
@ -34,9 +35,7 @@ int gNumManifold = 0;
btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration):
m_count(0),
m_useIslands(true),
m_staticWarningReported(false),
m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD),
m_collisionConfiguration(collisionConfiguration)
{
int i;
@ -69,31 +68,39 @@ btCollisionDispatcher::~btCollisionDispatcher()
{
}
btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
btPersistentManifold* btCollisionDispatcher::getNewManifold(const btCollisionObject* body0,const btCollisionObject* body1)
{
gNumManifold++;
//btAssert(gNumManifold < 65535);
btCollisionObject* body0 = (btCollisionObject*)b0;
btCollisionObject* body1 = (btCollisionObject*)b1;
//test for Bullet 2.74: use a relative contact breaking threshold without clamping against 'gContactBreakingThreshold'
//btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold()));
btScalar contactBreakingThreshold = btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold());
//optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance)
btScalar contactBreakingThreshold = (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ?
btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold) , body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold))
: gContactBreakingThreshold ;
btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
void* mem = 0;
void* mem = 0;
if (m_persistentManifoldPoolAllocator->getFreeCount())
{
mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold));
} else
{
mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
//we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert.
if ((m_dispatcherFlags&CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION)==0)
{
mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
} else
{
btAssert(0);
//make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration
return 0;
}
}
btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold);
manifold->m_index1a = m_manifoldsPtr.size();
@ -135,14 +142,14 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold)
btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold)
{
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher1 = this;
ci.m_manifold = sharedManifold;
btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0,body1);
btCollisionAlgorithm* algo = m_doubleDispatch[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0Wrap,body1Wrap);
return algo;
}
@ -150,7 +157,7 @@ btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* bo
bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
bool btCollisionDispatcher::needsResponse(const btCollisionObject* body0,const btCollisionObject* body1)
{
//here you can do filtering
bool hasResponse =
@ -161,7 +168,7 @@ bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionOb
return hasResponse;
}
bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1)
bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0,const btCollisionObject* body1)
{
btAssert(body0);
btAssert(body1);
@ -169,13 +176,12 @@ bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionO
bool needsCollision = true;
#ifdef BT_DEBUG
if (!m_staticWarningReported)
if (!(m_dispatcherFlags & btCollisionDispatcher::CD_STATIC_STATIC_REPORTED))
{
//broadphase filtering already deals with this
if ((body0->isStaticObject() || body0->isKinematicObject()) &&
(body1->isStaticObject() || body1->isKinematicObject()))
if (body0->isStaticOrKinematicObject() && body1->isStaticOrKinematicObject())
{
m_staticWarningReported = true;
m_dispatcherFlags |= btCollisionDispatcher::CD_STATIC_STATIC_REPORTED;
printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
}
}
@ -252,20 +258,25 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair,
if (dispatcher.needsCollision(colObj0,colObj1))
{
btCollisionObjectWrapper obj0Wrap(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform());
btCollisionObjectWrapper obj1Wrap(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform());
//dispatcher will keep algorithms persistent in the collision pair
if (!collisionPair.m_algorithm)
{
collisionPair.m_algorithm = dispatcher.findAlgorithm(colObj0,colObj1);
collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap);
}
if (collisionPair.m_algorithm)
{
btManifoldResult contactPointResult(colObj0,colObj1);
btManifoldResult contactPointResult(&obj0Wrap,&obj1Wrap);
if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE)
{
//discrete collision detection query
collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult);
collisionPair.m_algorithm->processCollision(&obj0Wrap,&obj1Wrap,dispatchInfo,&contactPointResult);
} else
{
//continuous collision detection query, time of impact (toi)

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION__DISPATCHER_H
#define COLLISION__DISPATCHER_H
#ifndef BT_COLLISION__DISPATCHER_H
#define BT_COLLISION__DISPATCHER_H
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
@ -42,14 +42,13 @@ typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispa
///Time of Impact, Closest Points and Penetration Depth.
class btCollisionDispatcher : public btDispatcher
{
int m_count;
protected:
int m_dispatcherFlags;
btAlignedObjectArray<btPersistentManifold*> m_manifoldsPtr;
bool m_useIslands;
bool m_staticWarningReported;
btManifoldResult m_defaultManifoldResult;
btNearCallback m_nearCallback;
@ -59,13 +58,29 @@ class btCollisionDispatcher : public btDispatcher
btPoolAllocator* m_persistentManifoldPoolAllocator;
btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
btCollisionConfiguration* m_collisionConfiguration;
public:
enum DispatcherFlags
{
CD_STATIC_STATIC_REPORTED = 1,
CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD = 2,
CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION = 4
};
int getDispatcherFlags() const
{
return m_dispatcherFlags;
}
void setDispatcherFlags(int flags)
{
m_dispatcherFlags = flags;
}
///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc);
@ -76,7 +91,7 @@ public:
btPersistentManifold** getInternalManifoldPointer()
{
return &m_manifoldsPtr[0];
return m_manifoldsPtr.size()? &m_manifoldsPtr[0] : 0;
}
btPersistentManifold* getManifoldByIndexInternal(int index)
@ -93,19 +108,18 @@ public:
virtual ~btCollisionDispatcher();
virtual btPersistentManifold* getNewManifold(void* b0,void* b1);
virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1);
virtual void releaseManifold(btPersistentManifold* manifold);
virtual void clearManifold(btPersistentManifold* manifold);
btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0);
btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold = 0);
virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1);
virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1);
virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1);
virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1);
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ;
@ -141,7 +155,17 @@ public:
m_collisionConfiguration = config;
}
virtual btPoolAllocator* getInternalManifoldPool()
{
return m_persistentManifoldPoolAllocator;
}
virtual const btPoolAllocator* getInternalManifoldPool() const
{
return m_persistentManifoldPoolAllocator;
}
};
#endif //COLLISION__DISPATCHER_H
#endif //BT_COLLISION__DISPATCHER_H

View file

@ -15,6 +15,7 @@ subject to the following restrictions:
#include "btCollisionObject.h"
#include "LinearMath/btSerializer.h"
btCollisionObject::btCollisionObject()
: m_anisotropicFriction(1.f,1.f,1.f),
@ -22,6 +23,7 @@ btCollisionObject::btCollisionObject()
m_contactProcessingThreshold(BT_LARGE_FLOAT),
m_broadphaseHandle(0),
m_collisionShape(0),
m_extensionPointer(0),
m_rootCollisionShape(0),
m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT),
m_islandTag1(-1),
@ -29,9 +31,10 @@ btCollisionObject::btCollisionObject()
m_activationState1(1),
m_deactivationTime(btScalar(0.)),
m_friction(btScalar(0.5)),
m_rollingFriction(0.0f),
m_restitution(btScalar(0.)),
m_userObjectPointer(0),
m_internalType(CO_COLLISION_OBJECT),
m_userObjectPointer(0),
m_hitFraction(btScalar(1.)),
m_ccdSweptSphereRadius(btScalar(0.)),
m_ccdMotionThreshold(btScalar(0.)),
@ -44,18 +47,18 @@ btCollisionObject::~btCollisionObject()
{
}
void btCollisionObject::setActivationState(int newState)
void btCollisionObject::setActivationState(int newState) const
{
if ( (m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION))
m_activationState1 = newState;
}
void btCollisionObject::forceActivationState(int newState)
void btCollisionObject::forceActivationState(int newState) const
{
m_activationState1 = newState;
}
void btCollisionObject::activate(bool forceActivation)
void btCollisionObject::activate(bool forceActivation) const
{
if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT)))
{
@ -64,5 +67,50 @@ void btCollisionObject::activate(bool forceActivation)
}
}
const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* serializer) const
{
btCollisionObjectData* dataOut = (btCollisionObjectData*)dataBuffer;
m_worldTransform.serialize(dataOut->m_worldTransform);
m_interpolationWorldTransform.serialize(dataOut->m_interpolationWorldTransform);
m_interpolationLinearVelocity.serialize(dataOut->m_interpolationLinearVelocity);
m_interpolationAngularVelocity.serialize(dataOut->m_interpolationAngularVelocity);
m_anisotropicFriction.serialize(dataOut->m_anisotropicFriction);
dataOut->m_hasAnisotropicFriction = m_hasAnisotropicFriction;
dataOut->m_contactProcessingThreshold = m_contactProcessingThreshold;
dataOut->m_broadphaseHandle = 0;
dataOut->m_collisionShape = serializer->getUniquePointer(m_collisionShape);
dataOut->m_rootCollisionShape = 0;//@todo
dataOut->m_collisionFlags = m_collisionFlags;
dataOut->m_islandTag1 = m_islandTag1;
dataOut->m_companionId = m_companionId;
dataOut->m_activationState1 = m_activationState1;
dataOut->m_deactivationTime = m_deactivationTime;
dataOut->m_friction = m_friction;
dataOut->m_rollingFriction = m_rollingFriction;
dataOut->m_restitution = m_restitution;
dataOut->m_internalType = m_internalType;
char* name = (char*) serializer->findNameForPointer(this);
dataOut->m_name = (char*)serializer->getUniquePointer(name);
if (dataOut->m_name)
{
serializer->serializeName(name);
}
dataOut->m_hitFraction = m_hitFraction;
dataOut->m_ccdSweptSphereRadius = m_ccdSweptSphereRadius;
dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
dataOut->m_checkCollideWith = m_checkCollideWith;
return btCollisionObjectDataName;
}
void btCollisionObject::serializeSingleObject(class btSerializer* serializer) const
{
int len = calculateSerializeBufferSize();
btChunk* chunk = serializer->allocate(len,1);
const char* structType = serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_COLLISIONOBJECT_CODE,(void*)this);
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_OBJECT_H
#define COLLISION_OBJECT_H
#ifndef BT_COLLISION_OBJECT_H
#define BT_COLLISION_OBJECT_H
#include "LinearMath/btTransform.h"
@ -27,13 +27,21 @@ subject to the following restrictions:
struct btBroadphaseProxy;
class btCollisionShape;
struct btCollisionShapeData;
#include "LinearMath/btMotionState.h"
#include "LinearMath/btAlignedAllocator.h"
#include "LinearMath/btAlignedObjectArray.h"
typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
#ifdef BT_USE_DOUBLE_PRECISION
#define btCollisionObjectData btCollisionObjectDoubleData
#define btCollisionObjectDataName "btCollisionObjectDoubleData"
#else
#define btCollisionObjectData btCollisionObjectFloatData
#define btCollisionObjectDataName "btCollisionObjectFloatData"
#endif
/// 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.
@ -53,12 +61,14 @@ protected:
btVector3 m_interpolationLinearVelocity;
btVector3 m_interpolationAngularVelocity;
btVector3 m_anisotropicFriction;
bool m_hasAnisotropicFriction;
btScalar m_contactProcessingThreshold;
btVector3 m_anisotropicFriction;
int m_hasAnisotropicFriction;
btScalar m_contactProcessingThreshold;
btBroadphaseProxy* m_broadphaseHandle;
btCollisionShape* m_collisionShape;
///m_extensionPointer is used by some internal low-level Bullet extensions.
void* m_extensionPointer;
///m_rootCollisionShape is temporarily used to store the original collision shape
///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
@ -70,19 +80,20 @@ protected:
int m_islandTag1;
int m_companionId;
int m_activationState1;
btScalar m_deactivationTime;
mutable int m_activationState1;
mutable btScalar m_deactivationTime;
btScalar m_friction;
btScalar m_restitution;
///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
void* m_userObjectPointer;
btScalar m_rollingFriction;
///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
///do not assign your own m_internalType unless you write a new dynamics object class.
int m_internalType;
///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
void* m_userObjectPointer;
///time of impact calculation
btScalar m_hitFraction;
@ -93,11 +104,9 @@ protected:
btScalar m_ccdMotionThreshold;
/// If some object should have elaborate collision filtering by sub-classes
bool m_checkCollideWith;
int m_checkCollideWith;
char m_pad[7];
virtual bool checkCollideWithOverride(btCollisionObject* /* co */)
virtual bool checkCollideWithOverride(const btCollisionObject* /* co */) const
{
return true;
}
@ -112,18 +121,28 @@ public:
CF_KINEMATIC_OBJECT= 2,
CF_NO_CONTACT_RESPONSE = 4,
CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
CF_CHARACTER_OBJECT = 16
CF_CHARACTER_OBJECT = 16,
CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing
CF_DISABLE_SPU_COLLISION_PROCESSING = 64//disable parallel/SPU processing
};
enum CollisionObjectTypes
{
CO_COLLISION_OBJECT =1,
CO_RIGID_BODY,
CO_RIGID_BODY=2,
///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
///It is useful for collision sensors, explosion objects, character controller etc.
CO_GHOST_OBJECT,
CO_SOFT_BODY,
CO_HF_FLUID
CO_GHOST_OBJECT=4,
CO_SOFT_BODY=8,
CO_HF_FLUID=16,
CO_USER_TYPE=32
};
enum AnisotropicFrictionFlags
{
CF_ANISOTROPIC_FRICTION_DISABLED=0,
CF_ANISOTROPIC_FRICTION = 1,
CF_ANISOTROPIC_ROLLING_FRICTION = 2
};
SIMD_FORCE_INLINE bool mergesSimulationIslands() const
@ -136,14 +155,15 @@ public:
{
return m_anisotropicFriction;
}
void setAnisotropicFriction(const btVector3& anisotropicFriction)
void setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION)
{
m_anisotropicFriction = anisotropicFriction;
m_hasAnisotropicFriction = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);
bool isUnity = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);
m_hasAnisotropicFriction = isUnity?frictionMode : 0;
}
bool hasAnisotropicFriction() const
bool hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const
{
return m_hasAnisotropicFriction;
return (m_hasAnisotropicFriction&frictionMode)!=0;
}
///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
@ -196,26 +216,26 @@ public:
return m_collisionShape;
}
SIMD_FORCE_INLINE const btCollisionShape* getRootCollisionShape() const
{
return m_rootCollisionShape;
}
SIMD_FORCE_INLINE btCollisionShape* getRootCollisionShape()
{
return m_rootCollisionShape;
}
///Avoid using this internal API call
///internalSetTemporaryCollisionShape is used to temporary replace the actual collision shape by a child collision shape.
void internalSetTemporaryCollisionShape(btCollisionShape* collisionShape)
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
void* internalGetExtensionPointer() const
{
m_collisionShape = collisionShape;
return m_extensionPointer;
}
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions
///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
void internalSetExtensionPointer(void* pointer)
{
m_extensionPointer = pointer;
}
SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;}
void setActivationState(int newState);
void setActivationState(int newState) const;
void setDeactivationTime(btScalar time)
{
@ -226,9 +246,9 @@ public:
return m_deactivationTime;
}
void forceActivationState(int newState);
void forceActivationState(int newState) const;
void activate(bool forceActivation = false);
void activate(bool forceActivation = false) const;
SIMD_FORCE_INLINE bool isActive() const
{
@ -252,6 +272,16 @@ public:
return m_friction;
}
void setRollingFriction(btScalar frict)
{
m_rollingFriction = frict;
}
btScalar getRollingFriction() const
{
return m_rollingFriction;
}
///reserved for Bullet internal usage
int getInternalType() const
{
@ -409,13 +439,96 @@ public:
}
inline bool checkCollideWith(btCollisionObject* co)
inline bool checkCollideWith(const btCollisionObject* co) const
{
if (m_checkCollideWith)
return checkCollideWithOverride(co);
return true;
}
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const;
virtual void serializeSingleObject(class btSerializer* serializer) const;
};
#endif //COLLISION_OBJECT_H
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btCollisionObjectDoubleData
{
void *m_broadphaseHandle;
void *m_collisionShape;
btCollisionShapeData *m_rootCollisionShape;
char *m_name;
btTransformDoubleData m_worldTransform;
btTransformDoubleData m_interpolationWorldTransform;
btVector3DoubleData m_interpolationLinearVelocity;
btVector3DoubleData m_interpolationAngularVelocity;
btVector3DoubleData m_anisotropicFriction;
double m_contactProcessingThreshold;
double m_deactivationTime;
double m_friction;
double m_rollingFriction;
double m_restitution;
double m_hitFraction;
double m_ccdSweptSphereRadius;
double m_ccdMotionThreshold;
int m_hasAnisotropicFriction;
int m_collisionFlags;
int m_islandTag1;
int m_companionId;
int m_activationState1;
int m_internalType;
int m_checkCollideWith;
char m_padding[4];
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btCollisionObjectFloatData
{
void *m_broadphaseHandle;
void *m_collisionShape;
btCollisionShapeData *m_rootCollisionShape;
char *m_name;
btTransformFloatData m_worldTransform;
btTransformFloatData m_interpolationWorldTransform;
btVector3FloatData m_interpolationLinearVelocity;
btVector3FloatData m_interpolationAngularVelocity;
btVector3FloatData m_anisotropicFriction;
float m_contactProcessingThreshold;
float m_deactivationTime;
float m_friction;
float m_rollingFriction;
float m_restitution;
float m_hitFraction;
float m_ccdSweptSphereRadius;
float m_ccdMotionThreshold;
int m_hasAnisotropicFriction;
int m_collisionFlags;
int m_islandTag1;
int m_companionId;
int m_activationState1;
int m_internalType;
int m_checkCollideWith;
char m_padding[4];
};
SIMD_FORCE_INLINE int btCollisionObject::calculateSerializeBufferSize() const
{
return sizeof(btCollisionObjectData);
}
#endif //BT_COLLISION_OBJECT_H

View file

@ -0,0 +1,40 @@
#ifndef BT_COLLISION_OBJECT_WRAPPER_H
#define BT_COLLISION_OBJECT_WRAPPER_H
///btCollisionObjectWrapperis an internal data structure.
///Most users can ignore this and use btCollisionObject and btCollisionShape instead
class btCollisionShape;
class btCollisionObject;
class btTransform;
#include "LinearMath/btScalar.h" // for SIMD_FORCE_INLINE definition
#define BT_DECLARE_STACK_ONLY_OBJECT \
private: \
void* operator new(size_t size); \
void operator delete(void*);
struct btCollisionObjectWrapper;
struct btCollisionObjectWrapper
{
BT_DECLARE_STACK_ONLY_OBJECT
private:
btCollisionObjectWrapper(const btCollisionObjectWrapper&); // not implemented. Not allowed.
btCollisionObjectWrapper* operator=(const btCollisionObjectWrapper&);
public:
const btCollisionObjectWrapper* m_parent;
const btCollisionShape* m_shape;
const btCollisionObject* m_collisionObject;
const btTransform& m_worldTransform;
btCollisionObjectWrapper(const btCollisionObjectWrapper* parent, const btCollisionShape* shape, const btCollisionObject* collisionObject, const btTransform& worldTransform)
: m_parent(parent), m_shape(shape), m_collisionObject(collisionObject), m_worldTransform(worldTransform)
{}
SIMD_FORCE_INLINE const btTransform& getWorldTransform() const { return m_worldTransform; }
SIMD_FORCE_INLINE const btCollisionObject* getCollisionObject() const { return m_collisionObject; }
SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { return m_shape; }
};
#endif //BT_COLLISION_OBJECT_WRAPPER_H

View file

@ -22,6 +22,7 @@ subject to the following restrictions:
*
* Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ).
*
* The main documentation is Bullet_User_Manual.pdf, included in the source code distribution.
* There is the Physics Forum for feedback and general Collision Detection and Physics discussions.
* Please visit http://www.bulletphysics.com
*
@ -29,14 +30,16 @@ subject to the following restrictions:
*
* @subsection step1 Step 1: Download
* You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
*
* @subsection step2 Step 2: Building
* Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8.
* The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version).
*
* Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org , or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
* So if you are not using MSVC or cmake, you can run ./autogen.sh ./configure to create both Makefile and Jamfile and then run make or jam.
* Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files.
* If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/jam
* Bullet main build system for all platforms is cmake, you can download http://www.cmake.org
* cmake can autogenerate projectfiles for Microsoft Visual Studio, Apple Xcode, KDevelop and Unix Makefiles.
* The easiest is to run the CMake cmake-gui graphical user interface and choose the options and generate projectfiles.
* You can also use cmake in the command-line. Here are some examples for various platforms:
* cmake . -G "Visual Studio 9 2008"
* cmake . -G Xcode
* cmake . -G "Unix Makefiles"
* Although cmake is recommended, you can also use autotools for UNIX: ./autogen.sh ./configure to create a Makefile and then run make.
*
* @subsection step3 Step 3: Testing demos
* Try to run and experiment with BasicDemo executable as a starting point.
@ -53,21 +56,21 @@ 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-2008 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, John McCutchan, Nathanael Presson, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
* Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt.
* For up-to-data information and copyright and contributors list check out the Bullet_User_Manual.pdf
*
*/
#ifndef COLLISION_WORLD_H
#define COLLISION_WORLD_H
#ifndef BT_COLLISION_WORLD_H
#define BT_COLLISION_WORLD_H
class btStackAlloc;
class btCollisionShape;
class btConvexShape;
class btBroadphaseInterface;
class btSerializer;
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "btCollisionObject.h"
@ -98,6 +101,8 @@ protected:
///it is true by default, because it is error-prone (setting the position of static objects wouldn't update their AABB)
bool m_forceUpdateAllAabbs;
void serializeCollisionObjects(btSerializer* serializer);
public:
//this constructor doesn't own the dispatcher and paircache/broadphase
@ -139,6 +144,11 @@ public:
void updateSingleAabb(btCollisionObject* colObj);
virtual void updateAabbs();
///the computeOverlappingPairs is usually already called by performDiscreteCollisionDetection (or stepSimulation)
///it can be useful to use if you perform ray tests without collision detection/simulation
virtual void computeOverlappingPairs();
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
{
@ -150,6 +160,10 @@ public:
return m_debugDrawer;
}
virtual void debugDrawWorld();
virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
///LocalShapeInfo gives extra information for complex shapes
///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart
@ -164,7 +178,7 @@ public:
struct LocalRayResult
{
LocalRayResult(btCollisionObject* collisionObject,
LocalRayResult(const btCollisionObject* collisionObject,
LocalShapeInfo* localShapeInfo,
const btVector3& hitNormalLocal,
btScalar hitFraction)
@ -175,7 +189,7 @@ public:
{
}
btCollisionObject* m_collisionObject;
const btCollisionObject* m_collisionObject;
LocalShapeInfo* m_localShapeInfo;
btVector3 m_hitNormalLocal;
btScalar m_hitFraction;
@ -186,11 +200,11 @@ public:
struct RayResultCallback
{
btScalar m_closestHitFraction;
btCollisionObject* m_collisionObject;
const btCollisionObject* m_collisionObject;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
//@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback
unsigned int m_flags;
//@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback.h. Apply any of the EFlags defined there on m_flags here to invoke.
unsigned int m_flags;
virtual ~RayResultCallback()
{
@ -205,8 +219,8 @@ public:
m_collisionObject(0),
m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
m_collisionFilterMask(btBroadphaseProxy::AllFilter),
//@BP Mod
m_flags(0)
//@BP Mod
m_flags(0)
{
}
@ -255,10 +269,49 @@ public:
}
};
struct AllHitsRayResultCallback : public RayResultCallback
{
AllHitsRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld)
:m_rayFromWorld(rayFromWorld),
m_rayToWorld(rayToWorld)
{
}
btAlignedObjectArray<const btCollisionObject*> m_collisionObjects;
btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction
btVector3 m_rayToWorld;
btAlignedObjectArray<btVector3> m_hitNormalWorld;
btAlignedObjectArray<btVector3> m_hitPointWorld;
btAlignedObjectArray<btScalar> m_hitFractions;
virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
{
m_collisionObject = rayResult.m_collisionObject;
m_collisionObjects.push_back(rayResult.m_collisionObject);
btVector3 hitNormalWorld;
if (normalInWorldSpace)
{
hitNormalWorld = rayResult.m_hitNormalLocal;
} else
{
///need to transform normal into worldspace
hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
}
m_hitNormalWorld.push_back(hitNormalWorld);
btVector3 hitPointWorld;
hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction);
m_hitPointWorld.push_back(hitPointWorld);
m_hitFractions.push_back(rayResult.m_hitFraction);
return m_closestHitFraction;
}
};
struct LocalConvexResult
{
LocalConvexResult(btCollisionObject* hitCollisionObject,
LocalConvexResult(const btCollisionObject* hitCollisionObject,
LocalShapeInfo* localShapeInfo,
const btVector3& hitNormalLocal,
const btVector3& hitPointLocal,
@ -272,7 +325,7 @@ public:
{
}
btCollisionObject* m_hitCollisionObject;
const btCollisionObject* m_hitCollisionObject;
LocalShapeInfo* m_localShapeInfo;
btVector3 m_hitNormalLocal;
btVector3 m_hitPointLocal;
@ -328,7 +381,7 @@ public:
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
btCollisionObject* m_hitCollisionObject;
const btCollisionObject* m_hitCollisionObject;
virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace)
{
@ -350,6 +403,34 @@ public:
}
};
///ContactResultCallback is used to report contact points
struct ContactResultCallback
{
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
ContactResultCallback()
:m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
m_collisionFilterMask(btBroadphaseProxy::AllFilter)
{
}
virtual ~ContactResultCallback()
{
}
virtual bool needsCollision(btBroadphaseProxy* proxy0) const
{
bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) = 0;
};
int getNumCollisionObjects() const
{
return int(m_collisionObjects.size());
@ -357,12 +438,20 @@ 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) const;
virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const;
// convexTest performs a swept convex cast 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 return by the callback.
/// convexTest performs a swept convex cast 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 return by the callback.
void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const;
///contactTest performs a discrete collision test between colObj against all objects in the btCollisionWorld, and calls the resultCallback.
///it reports one or more contact points for every overlapping object (including the one with deepest penetration)
void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback);
///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
///it reports one or more contact points (including the one with deepest penetration)
void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback);
/// 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.
@ -373,6 +462,10 @@ public:
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback);
static void rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans,
const btCollisionObjectWrapper* collisionObjectWrap,
RayResultCallback& resultCallback);
/// 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,
@ -380,6 +473,10 @@ public:
const btTransform& colObjWorldTransform,
ConvexResultCallback& resultCallback, btScalar allowedPenetration);
static void objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
const btCollisionObjectWrapper* colObjWrap,
ConvexResultCallback& resultCallback, btScalar allowedPenetration);
virtual void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
btCollisionObjectArray& getCollisionObjectArray()
@ -416,7 +513,10 @@ public:
m_forceUpdateAllAabbs = forceUpdateAllAabbs;
}
///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bullet/Demos/SerializeDemo)
virtual void serialize(btSerializer* serializer);
};
#endif //COLLISION_WORLD_H
#endif //BT_COLLISION_WORLD_H

View file

@ -20,30 +20,32 @@ subject to the following restrictions:
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btAabbUtil2.h"
#include "btManifoldResult.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
:btActivatingCollisionAlgorithm(ci,body0,body1),
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped)
:btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_isSwapped(isSwapped),
m_sharedManifold(ci.m_manifold)
{
m_ownsManifold = false;
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btAssert (colObj->getCollisionShape()->isCompound());
const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap;
btAssert (colObjWrap->getCollisionShape()->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(colObjWrap->getCollisionShape());
m_compoundShapeRevision = compoundShape->getUpdateRevision();
preallocateChildAlgorithms(body0,body1);
preallocateChildAlgorithms(body0Wrap,body1Wrap);
}
void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1)
void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
btAssert (colObj->getCollisionShape()->isCompound());
const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap;
const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap;
btAssert (colObjWrap->getCollisionShape()->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(colObjWrap->getCollisionShape());
int numChildren = compoundShape->getNumChildShapes();
int i;
@ -56,11 +58,11 @@ void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(btCollisionObject*
m_childCollisionAlgorithms[i] = 0;
} else
{
btCollisionShape* tmpShape = colObj->getCollisionShape();
btCollisionShape* childShape = compoundShape->getChildShape(i);
colObj->internalSetTemporaryCollisionShape( childShape );
m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(colObj,otherObj,m_sharedManifold);
colObj->internalSetTemporaryCollisionShape( tmpShape );
const btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionObjectWrapper childWrap(colObjWrap,childShape,colObjWrap->getCollisionObject(),colObjWrap->getWorldTransform());//wrong child trans, but unused (hopefully)
m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(&childWrap,otherObjWrap,m_sharedManifold);
}
}
}
@ -92,19 +94,16 @@ struct btCompoundLeafCallback : btDbvt::ICollide
public:
btCollisionObject* m_compoundColObj;
btCollisionObject* m_otherObj;
const btCollisionObjectWrapper* m_compoundColObjWrap;
const btCollisionObjectWrapper* m_otherObjWrap;
btDispatcher* m_dispatcher;
const btDispatcherInfo& m_dispatchInfo;
btManifoldResult* m_resultOut;
btCollisionAlgorithm** m_childCollisionAlgorithms;
btPersistentManifold* m_sharedManifold;
btCompoundLeafCallback (btCollisionObject* compoundObj,btCollisionObject* otherObj,btDispatcher* dispatcher,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut,btCollisionAlgorithm** childCollisionAlgorithms,btPersistentManifold* sharedManifold)
:m_compoundColObj(compoundObj),m_otherObj(otherObj),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
btCompoundLeafCallback (const btCollisionObjectWrapper* compoundObjWrap,const btCollisionObjectWrapper* otherObjWrap,btDispatcher* dispatcher,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut,btCollisionAlgorithm** childCollisionAlgorithms,btPersistentManifold* sharedManifold)
:m_compoundColObjWrap(compoundObjWrap),m_otherObjWrap(otherObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
m_childCollisionAlgorithms(childCollisionAlgorithms),
m_sharedManifold(sharedManifold)
{
@ -112,72 +111,89 @@ public:
}
void ProcessChildShape(btCollisionShape* childShape,int index)
void ProcessChildShape(const btCollisionShape* childShape,int index)
{
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
btAssert(index>=0);
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(m_compoundColObjWrap->getCollisionShape());
btAssert(index<compoundShape->getNumChildShapes());
//backup
btTransform orgTrans = m_compoundColObj->getWorldTransform();
btTransform orgInterpolationTrans = m_compoundColObj->getInterpolationWorldTransform();
btTransform orgTrans = m_compoundColObjWrap->getWorldTransform();
btTransform orgInterpolationTrans = m_compoundColObjWrap->getWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(index);
btTransform newChildWorldTrans = orgTrans*childTrans ;
//perform an AABB check first
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
m_otherObj->getCollisionShape()->getAabb(m_otherObj->getWorldTransform(),aabbMin1,aabbMax1);
m_otherObjWrap->getCollisionShape()->getAabb(m_otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1);
if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
{
m_compoundColObj->setWorldTransform( newChildWorldTrans);
m_compoundColObj->setInterpolationWorldTransform(newChildWorldTrans);
btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap,childShape,m_compoundColObjWrap->getCollisionObject(),newChildWorldTrans);
//the contactpoint is still projected back using the original inverted worldtrans
btCollisionShape* tmpShape = m_compoundColObj->getCollisionShape();
m_compoundColObj->internalSetTemporaryCollisionShape( childShape );
if (!m_childCollisionAlgorithms[index])
m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(m_compoundColObj,m_otherObj,m_sharedManifold);
m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(&compoundWrap,m_otherObjWrap,m_sharedManifold);
const btCollisionObjectWrapper* tmpWrap = 0;
///detect swapping case
if (m_resultOut->getBody0Internal() == m_compoundColObj)
if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject())
{
tmpWrap = m_resultOut->getBody0Wrap();
m_resultOut->setBody0Wrap(&compoundWrap);
m_resultOut->setShapeIdentifiersA(-1,index);
} else
{
tmpWrap = m_resultOut->getBody1Wrap();
m_resultOut->setBody1Wrap(&compoundWrap);
m_resultOut->setShapeIdentifiersB(-1,index);
}
m_childCollisionAlgorithms[index]->processCollision(m_compoundColObj,m_otherObj,m_dispatchInfo,m_resultOut);
m_childCollisionAlgorithms[index]->processCollision(&compoundWrap,m_otherObjWrap,m_dispatchInfo,m_resultOut);
#if 0
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 worldAabbMin,worldAabbMax;
m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1));
m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1));
}
#endif
if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject())
{
m_resultOut->setBody0Wrap(tmpWrap);
} else
{
m_resultOut->setBody1Wrap(tmpWrap);
}
//revert back transform
m_compoundColObj->internalSetTemporaryCollisionShape( tmpShape);
m_compoundColObj->setWorldTransform( orgTrans );
m_compoundColObj->setInterpolationWorldTransform(orgInterpolationTrans);
}
}
void Process(const btDbvtNode* leaf)
{
int index = leaf->dataAsInt;
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
btCollisionShape* childShape = compoundShape->getChildShape(index);
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(m_compoundColObjWrap->getCollisionShape());
const btCollisionShape* childShape = compoundShape->getChildShape(index);
#if 0
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 worldAabbMin,worldAabbMax;
btTransform orgTrans = m_compoundColObj->getWorldTransform();
btTransform orgTrans = m_compoundColObjWrap->getWorldTransform();
btTransformAabb(leaf->volume.Mins(),leaf->volume.Maxs(),0.,orgTrans,worldAabbMin,worldAabbMax);
m_dispatchInfo.m_debugDraw->drawAabb(worldAabbMin,worldAabbMax,btVector3(1,0,0));
}
#endif
ProcessChildShape(childShape,index);
}
@ -188,15 +204,13 @@ public:
void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap;
const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap;
btAssert (colObj->getCollisionShape()->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
btAssert (colObjWrap->getCollisionShape()->isCompound());
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(colObjWrap->getCollisionShape());
///btCompoundShape might have changed:
////make sure the internal child collision algorithm caches are still valid
@ -205,13 +219,13 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
///clear and update all
removeChildAlgorithms();
preallocateChildAlgorithms(body0,body1);
preallocateChildAlgorithms(body0Wrap,body1Wrap);
}
btDbvt* tree = compoundShape->getDynamicAabbTree();
const btDbvt* tree = compoundShape->getDynamicAabbTree();
//use a dynamic aabb tree to cull potential child-overlaps
btCompoundLeafCallback callback(colObj,otherObj,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
btCompoundLeafCallback callback(colObjWrap,otherObjWrap,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
///we need to refresh all contact manifolds
///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep
@ -233,7 +247,7 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
resultOut->setPersistentManifold(0);//??necessary?
}
}
manifoldArray.clear();
manifoldArray.resize(0);
}
}
}
@ -243,8 +257,8 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
btVector3 localAabbMin,localAabbMax;
btTransform otherInCompoundSpace;
otherInCompoundSpace = colObj->getWorldTransform().inverse() * otherObj->getWorldTransform();
otherObj->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax);
otherInCompoundSpace = colObjWrap->getWorldTransform().inverse() * otherObjWrap->getWorldTransform();
otherObjWrap->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax);
const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
//process all children, that overlap with the given AABB bounds
@ -266,22 +280,26 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
int numChildren = m_childCollisionAlgorithms.size();
int i;
btManifoldArray manifoldArray;
const btCollisionShape* childShape = 0;
btTransform orgTrans;
btTransform orgInterpolationTrans;
btTransform newChildWorldTrans;
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
for (i=0;i<numChildren;i++)
{
if (m_childCollisionAlgorithms[i])
{
btCollisionShape* childShape = compoundShape->getChildShape(i);
childShape = compoundShape->getChildShape(i);
//if not longer overlapping, remove the algorithm
btTransform orgTrans = colObj->getWorldTransform();
btTransform orgInterpolationTrans = colObj->getInterpolationWorldTransform();
orgTrans = colObjWrap->getWorldTransform();
orgInterpolationTrans = colObjWrap->getWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(i);
btTransform newChildWorldTrans = orgTrans*childTrans ;
newChildWorldTrans = orgTrans*childTrans ;
//perform an AABB check first
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
otherObj->getCollisionShape()->getAabb(otherObj->getWorldTransform(),aabbMin1,aabbMax1);
otherObjWrap->getCollisionShape()->getAabb(otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1);
if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
{
@ -289,19 +307,15 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
m_childCollisionAlgorithms[i] = 0;
}
}
}
}
}
btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
btAssert(0);
//needs to be fixed, using btCollisionObjectWrapper and NOT modifying internal data structures
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
@ -320,27 +334,28 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
int numChildren = m_childCollisionAlgorithms.size();
int i;
btTransform orgTrans;
btScalar frac;
for (i=0;i<numChildren;i++)
{
//temporarily exchange parent btCollisionShape with childShape, and recurse
btCollisionShape* childShape = compoundShape->getChildShape(i);
//btCollisionShape* childShape = compoundShape->getChildShape(i);
//backup
btTransform orgTrans = colObj->getWorldTransform();
orgTrans = colObj->getWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(i);
//btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( orgTrans*childTrans );
btCollisionShape* tmpShape = colObj->getCollisionShape();
colObj->internalSetTemporaryCollisionShape( childShape );
btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
//btCollisionShape* tmpShape = colObj->getCollisionShape();
//colObj->internalSetTemporaryCollisionShape( childShape );
frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
if (frac<hitFraction)
{
hitFraction = frac;
}
//revert back
colObj->internalSetTemporaryCollisionShape( tmpShape);
//colObj->internalSetTemporaryCollisionShape( tmpShape);
colObj->setWorldTransform( orgTrans);
}
return hitFraction;

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COMPOUND_COLLISION_ALGORITHM_H
#define COMPOUND_COLLISION_ALGORITHM_H
#ifndef BT_COMPOUND_COLLISION_ALGORITHM_H
#define BT_COMPOUND_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
@ -41,15 +41,15 @@ class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
void removeChildAlgorithms();
void preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1);
void preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
public:
btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
virtual ~btCompoundCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -65,22 +65,22 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,false);
return new(mem) btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,false);
}
};
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,true);
return new(mem) btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,true);
}
};
};
#endif //COMPOUND_COLLISION_ALGORITHM_H
#endif //BT_COMPOUND_COLLISION_ALGORITHM_H

View file

@ -43,7 +43,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
{
@ -57,8 +57,8 @@ btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc()
{
}
btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
: btActivatingCollisionAlgorithm(ci,body0,body1),
btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_simplexSolver(simplexSolver),
m_pdSolver(pdSolver),
m_ownManifold (false),
@ -67,8 +67,8 @@ m_lowLevelOfDetail(false),
m_numPerturbationIterations(numPerturbationIterations),
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
{
(void)body0;
(void)body1;
(void)body0Wrap;
(void)body1Wrap;
}
@ -96,13 +96,13 @@ extern btScalar gContactBreakingThreshold;
//
// Convex-Convex collision algorithm
//
void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btConvex2dConvex2dAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
{
//swapped?
m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
m_ownManifold = true;
}
resultOut->setPersistentManifold(m_manifoldPtr);
@ -111,8 +111,8 @@ void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,bt
//resultOut->getPersistentManifold()->clearManifold();
btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
const btConvexShape* min0 = static_cast<const btConvexShape*>(body0Wrap->getCollisionShape());
const btConvexShape* min1 = static_cast<const btConvexShape*>(body1Wrap->getCollisionShape());
btVector3 normalOnB;
btVector3 pointOnBWorld;
@ -133,8 +133,8 @@ void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,bt
}
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
input.m_transformA = body0Wrap->getWorldTransform();
input.m_transformB = body1Wrap->getWorldTransform();
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_2D_CONVEX_2D_ALGORITHM_H
#define CONVEX_2D_CONVEX_2D_ALGORITHM_H
#ifndef BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H
#define BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H
#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
@ -45,12 +45,12 @@ class btConvex2dConvex2dAlgorithm : public btActivatingCollisionAlgorithm
public:
btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
virtual ~btConvex2dConvex2dAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -82,14 +82,14 @@ public:
virtual ~CreateFunc();
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvex2dConvex2dAlgorithm));
return new(mem) btConvex2dConvex2dAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
return new(mem) btConvex2dConvex2dAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
};
};
#endif //CONVEX_2D_CONVEX_2D_ALGORITHM_H
#endif //BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H

View file

@ -25,11 +25,12 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "LinearMath/btIDebugDraw.h"
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
: btActivatingCollisionAlgorithm(ci,body0,body1),
btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped)
: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_isSwapped(isSwapped),
m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
m_btConvexTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped)
{
}
@ -46,17 +47,17 @@ void btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray&
}
btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped):
m_dispatcher(dispatcher),
m_dispatchInfoPtr(0)
{
m_convexBody = isSwapped? body1:body0;
m_triBody = isSwapped? body0:body1;
m_convexBodyWrap = isSwapped? body1Wrap:body0Wrap;
m_triBodyWrap = isSwapped? body0Wrap:body1Wrap;
//
// create the manifold from the dispatcher 'manifold pool'
//
m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody);
m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBodyWrap->getCollisionObject(),m_triBodyWrap->getCollisionObject());
clearCache();
}
@ -88,66 +89,78 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher1 = m_dispatcher;
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
//const btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());
#if 0
///debug drawing of the overlapping triangles
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
{
btVector3 color(255,255,0);
btVector3 color(1,1,0);
btTransform& tr = ob->getWorldTransform();
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
//btVector3 center = triangle[0] + triangle[1]+triangle[2];
//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);
}
//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
#endif
if (m_convexBody->getCollisionShape()->isConvex())
if (m_convexBodyWrap->getCollisionShape()->isConvex())
{
btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
tm.setMargin(m_collisionMarginTriangle);
btCollisionShape* tmpShape = ob->getCollisionShape();
ob->internalSetTemporaryCollisionShape( &tm );
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
///this should use the btDispatcher, so the actual registered algorithm is used
// btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
btCollisionObjectWrapper triObWrap(m_triBodyWrap,&tm,m_triBodyWrap->getCollisionObject(),m_triBodyWrap->getWorldTransform());//correct transform?
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap,&triObWrap,m_manifoldPtr);
m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
const btCollisionObjectWrapper* tmpWrap = 0;
if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
{
tmpWrap = m_resultOut->getBody0Wrap();
m_resultOut->setBody0Wrap(&triObWrap);
m_resultOut->setShapeIdentifiersA(partId,triangleIndex);
}
else
{
tmpWrap = m_resultOut->getBody1Wrap();
m_resultOut->setBody1Wrap(&triObWrap);
m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
}
// cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
colAlgo->processCollision(m_convexBodyWrap,&triObWrap,*m_dispatchInfoPtr,m_resultOut);
if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
{
m_resultOut->setBody0Wrap(tmpWrap);
} else
{
m_resultOut->setBody1Wrap(tmpWrap);
}
colAlgo->~btCollisionAlgorithm();
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
ob->internalSetTemporaryCollisionShape( tmpShape);
}
}
void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut)
{
m_convexBodyWrap = convexBodyWrap;
m_triBodyWrap = triBodyWrap;
m_dispatchInfoPtr = &dispatchInfo;
m_collisionMarginTriangle = collisionMarginTriangle;
m_resultOut = resultOut;
//recalc aabbs
btTransform convexInTriangleSpace;
convexInTriangleSpace = m_triBody->getWorldTransform().inverse() * m_convexBody->getWorldTransform();
btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->getCollisionShape());
convexInTriangleSpace = m_triBodyWrap->getWorldTransform().inverse() * m_convexBodyWrap->getWorldTransform();
const btCollisionShape* convexShape = static_cast<const btCollisionShape*>(m_convexBodyWrap->getCollisionShape());
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
btScalar extraMargin = collisionMarginTriangle;
@ -164,35 +177,34 @@ void btConvexConcaveCollisionAlgorithm::clearCache()
}
void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
btCollisionObject* convexBody = m_isSwapped ? body1 : body0;
btCollisionObject* triBody = m_isSwapped ? body0 : body1;
const btCollisionObjectWrapper* convexBodyWrap = m_isSwapped ? body1Wrap : body0Wrap;
const btCollisionObjectWrapper* triBodyWrap = m_isSwapped ? body0Wrap : body1Wrap;
if (triBody->getCollisionShape()->isConcave())
if (triBodyWrap->getCollisionShape()->isConcave())
{
btCollisionObject* triOb = triBody;
btConcaveShape* concaveShape = static_cast<btConcaveShape*>( triOb->getCollisionShape());
if (convexBody->getCollisionShape()->isConvex())
const btConcaveShape* concaveShape = static_cast<const btConcaveShape*>( triBodyWrap->getCollisionShape());
if (convexBodyWrap->getCollisionShape()->isConvex())
{
btScalar collisionMarginTriangle = concaveShape->getMargin();
resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,convexBodyWrap,triBodyWrap,resultOut);
//Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
//m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);
m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBodyWrap->getCollisionObject(),triBodyWrap->getCollisionObject());
concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax());
resultOut->refreshContactPoints();
m_btConvexTriangleCallback.clearWrapperData();
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#ifndef BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#define BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
@ -28,8 +28,8 @@ class btDispatcher;
///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
class btConvexTriangleCallback : public btTriangleCallback
{
btCollisionObject* m_convexBody;
btCollisionObject* m_triBody;
const btCollisionObjectWrapper* m_convexBodyWrap;
const btCollisionObjectWrapper* m_triBodyWrap;
btVector3 m_aabbMin;
btVector3 m_aabbMax ;
@ -45,10 +45,15 @@ int m_triangleCount;
btPersistentManifold* m_manifoldPtr;
btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
btConvexTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut);
void clearWrapperData()
{
m_convexBodyWrap = 0;
m_triBodyWrap = 0;
}
virtual ~btConvexTriangleCallback();
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
@ -81,11 +86,11 @@ class btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm
public:
btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
virtual ~btConvexConcaveCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -95,22 +100,22 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,false);
}
};
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,true);
}
};
};
#endif //CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#endif //BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H

View file

@ -17,6 +17,7 @@ subject to the following restrictions:
///If you experience problems with capsule-capsule collision, try to define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER and report it in the Bullet forums
///with reproduction case
//define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER 1
//#define ZERO_MARGIN
#include "btConvexConvexAlgorithm.h"
@ -26,6 +27,8 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
@ -48,8 +51,8 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
///////////
@ -188,8 +191,8 @@ btConvexConvexAlgorithm::CreateFunc::~CreateFunc()
{
}
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
: btActivatingCollisionAlgorithm(ci,body0,body1),
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_simplexSolver(simplexSolver),
m_pdSolver(pdSolver),
m_ownManifold (false),
@ -202,8 +205,8 @@ m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngu
m_numPerturbationIterations(numPerturbationIterations),
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
{
(void)body0;
(void)body1;
(void)body0Wrap;
(void)body1Wrap;
}
@ -238,8 +241,8 @@ struct btPerturbedContactResult : public btManifoldResult
:m_originalManifoldResult(originalResult),
m_transformA(transformA),
m_transformB(transformB),
m_perturbA(perturbA),
m_unPerturbedTransform(unPerturbedTransform),
m_perturbA(perturbA),
m_debugDrawer(debugDrawer)
{
}
@ -286,13 +289,13 @@ extern btScalar gContactBreakingThreshold;
//
// Convex-Convex collision algorithm
//
void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
{
//swapped?
m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
m_ownManifold = true;
}
resultOut->setPersistentManifold(m_manifoldPtr);
@ -301,8 +304,8 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
//resultOut->getPersistentManifold()->clearManifold();
btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
const btConvexShape* min0 = static_cast<const btConvexShape*>(body0Wrap->getCollisionShape());
const btConvexShape* min1 = static_cast<const btConvexShape*>(body1Wrap->getCollisionShape());
btVector3 normalOnB;
btVector3 pointOnBWorld;
@ -311,14 +314,14 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
{
btCapsuleShape* capsuleA = (btCapsuleShape*) min0;
btCapsuleShape* capsuleB = (btCapsuleShape*) min1;
btVector3 localScalingA = capsuleA->getLocalScaling();
btVector3 localScalingB = capsuleB->getLocalScaling();
// btVector3 localScalingA = capsuleA->getLocalScaling();
// btVector3 localScalingB = capsuleB->getLocalScaling();
btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld,capsuleA->getHalfHeight(),capsuleA->getRadius(),
capsuleB->getHalfHeight(),capsuleB->getRadius(),capsuleA->getUpAxis(),capsuleB->getUpAxis(),
body0->getWorldTransform(),body1->getWorldTransform(),threshold);
body0Wrap->getWorldTransform(),body1Wrap->getWorldTransform(),threshold);
if (dist<threshold)
{
@ -331,8 +334,14 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
#ifdef USE_SEPDISTANCE_UTIL2
m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
if (dispatchInfo.m_useConvexConservativeDistanceUtil)
{
m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
}
if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
#endif //USE_SEPDISTANCE_UTIL2
@ -353,18 +362,23 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
} else
#endif //USE_SEPDISTANCE_UTIL2
{
//if (dispatchInfo.m_convexMaxDistanceUseCPT)
//{
// input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
//} else
//{
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
// }
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
}
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
input.m_transformA = body0Wrap->getWorldTransform();
input.m_transformB = body1Wrap->getWorldTransform();
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
btVector3 v0,v1;
btVector3 sepNormalWorldSpace;
#ifdef USE_SEPDISTANCE_UTIL2
@ -376,73 +390,278 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
{
sepDist += dispatchInfo.m_convexConservativeDistanceThreshold;
//now perturbe directions to get multiple contact points
sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
btPlaneSpace1(sepNormalWorldSpace,v0,v1);
}
}
#endif //USE_SEPDISTANCE_UTIL2
if (min0->isPolyhedral() && min1->isPolyhedral())
{
struct btDummyResult : public btDiscreteCollisionDetectorInterface::Result
{
virtual void setShapeIdentifiersA(int partId0,int index0){}
virtual void setShapeIdentifiersB(int partId1,int index1){}
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
}
};
struct btWithoutMarginResult : public btDiscreteCollisionDetectorInterface::Result
{
btDiscreteCollisionDetectorInterface::Result* m_originalResult;
btVector3 m_reportedNormalOnWorld;
btScalar m_marginOnA;
btScalar m_marginOnB;
btScalar m_reportedDistance;
bool m_foundResult;
btWithoutMarginResult(btDiscreteCollisionDetectorInterface::Result* result, btScalar marginOnA, btScalar marginOnB)
:m_originalResult(result),
m_marginOnA(marginOnA),
m_marginOnB(marginOnB),
m_foundResult(false)
{
}
virtual void setShapeIdentifiersA(int partId0,int index0){}
virtual void setShapeIdentifiersB(int partId1,int index1){}
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorldOrg,btScalar depthOrg)
{
m_reportedDistance = depthOrg;
m_reportedNormalOnWorld = normalOnBInWorld;
btVector3 adjustedPointB = pointInWorldOrg - normalOnBInWorld*m_marginOnB;
m_reportedDistance = depthOrg+(m_marginOnA+m_marginOnB);
if (m_reportedDistance<0.f)
{
m_foundResult = true;
}
m_originalResult->addContactPoint(normalOnBInWorld,adjustedPointB,m_reportedDistance);
}
};
btDummyResult dummy;
///btBoxShape is an exception: its vertices are created WITH margin so don't subtract it
btScalar min0Margin = min0->getShapeType()==BOX_SHAPE_PROXYTYPE? 0.f : min0->getMargin();
btScalar min1Margin = min1->getShapeType()==BOX_SHAPE_PROXYTYPE? 0.f : min1->getMargin();
btWithoutMarginResult withoutMargin(resultOut, min0Margin,min1Margin);
btPolyhedralConvexShape* polyhedronA = (btPolyhedralConvexShape*) min0;
btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1;
if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron())
{
btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
btScalar minDist = -1e30f;
btVector3 sepNormalWorldSpace;
bool foundSepAxis = true;
if (dispatchInfo.m_enableSatConvex)
{
foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
*polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0Wrap->getWorldTransform(),
body1Wrap->getWorldTransform(),
sepNormalWorldSpace,*resultOut);
} else
{
#ifdef ZERO_MARGIN
gjkPairDetector.setIgnoreMargin(true);
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
#else
gjkPairDetector.getClosestPoints(input,withoutMargin,dispatchInfo.m_debugDraw);
//gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw);
#endif //ZERO_MARGIN
//btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
//if (l2>SIMD_EPSILON)
{
sepNormalWorldSpace = withoutMargin.m_reportedNormalOnWorld;//gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
//minDist = -1e30f;//gjkPairDetector.getCachedSeparatingDistance();
minDist = withoutMargin.m_reportedDistance;//gjkPairDetector.getCachedSeparatingDistance()+min0->getMargin()+min1->getMargin();
#ifdef ZERO_MARGIN
foundSepAxis = true;//gjkPairDetector.getCachedSeparatingDistance()<0.f;
#else
foundSepAxis = withoutMargin.m_foundResult && minDist<0;//-(min0->getMargin()+min1->getMargin());
#endif
}
}
if (foundSepAxis)
{
// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0Wrap->getWorldTransform(),
body1Wrap->getWorldTransform(), minDist-threshold, threshold, *resultOut);
}
if (m_ownManifold)
{
resultOut->refreshContactPoints();
}
return;
} else
{
//we can also deal with convex versus triangle (without connectivity data)
if (polyhedronA->getConvexPolyhedron() && polyhedronB->getShapeType()==TRIANGLE_SHAPE_PROXYTYPE)
{
btVertexArray vertices;
btTriangleShape* tri = (btTriangleShape*)polyhedronB;
vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[0]);
vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[1]);
vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[2]);
//tri->initializePolyhedralFeatures();
btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
btVector3 sepNormalWorldSpace;
btScalar minDist =-1e30f;
btScalar maxDist = threshold;
bool foundSepAxis = false;
if (0)
{
polyhedronB->initializePolyhedralFeatures();
foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
*polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0Wrap->getWorldTransform(),
body1Wrap->getWorldTransform(),
sepNormalWorldSpace,*resultOut);
// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
} else
{
#ifdef ZERO_MARGIN
gjkPairDetector.setIgnoreMargin(true);
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
#else
gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw);
#endif//ZERO_MARGIN
btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
if (l2>SIMD_EPSILON)
{
sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
//minDist = gjkPairDetector.getCachedSeparatingDistance();
//maxDist = threshold;
minDist = gjkPairDetector.getCachedSeparatingDistance()-min0->getMargin()-min1->getMargin();
foundSepAxis = true;
}
}
if (foundSepAxis)
{
btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(),
body0Wrap->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut);
}
if (m_ownManifold)
{
resultOut->refreshContactPoints();
}
return;
}
}
}
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
//now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
//perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
if (resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
if (m_numPerturbationIterations && resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
{
int i;
bool perturbeA = true;
const btScalar angleLimit = 0.125f * SIMD_PI;
btScalar perturbeAngle;
btScalar radiusA = min0->getAngularMotionDisc();
btScalar radiusB = min1->getAngularMotionDisc();
if (radiusA < radiusB)
btVector3 v0,v1;
btVector3 sepNormalWorldSpace;
btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
if (l2>SIMD_EPSILON)
{
perturbeAngle = gContactBreakingThreshold /radiusA;
perturbeA = true;
} else
{
perturbeAngle = gContactBreakingThreshold / radiusB;
perturbeA = false;
}
if ( perturbeAngle > angleLimit )
perturbeAngle = angleLimit;
btTransform unPerturbedTransform;
if (perturbeA)
{
unPerturbedTransform = input.m_transformA;
} else
{
unPerturbedTransform = input.m_transformB;
}
for ( i=0;i<m_numPerturbationIterations;i++)
{
btQuaternion perturbeRot(v0,perturbeAngle);
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
if (perturbeA)
btPlaneSpace1(sepNormalWorldSpace,v0,v1);
bool perturbeA = true;
const btScalar angleLimit = 0.125f * SIMD_PI;
btScalar perturbeAngle;
btScalar radiusA = min0->getAngularMotionDisc();
btScalar radiusB = min1->getAngularMotionDisc();
if (radiusA < radiusB)
{
input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
input.m_transformB = body1->getWorldTransform();
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
#endif //DEBUG_CONTACTS
perturbeAngle = gContactBreakingThreshold /radiusA;
perturbeA = true;
} else
{
input.m_transformA = body0->getWorldTransform();
input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
#endif
perturbeAngle = gContactBreakingThreshold / radiusB;
perturbeA = false;
}
if ( perturbeAngle > angleLimit )
perturbeAngle = angleLimit;
btTransform unPerturbedTransform;
if (perturbeA)
{
unPerturbedTransform = input.m_transformA;
} else
{
unPerturbedTransform = input.m_transformB;
}
btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
for ( i=0;i<m_numPerturbationIterations;i++)
{
if (v0.length2()>SIMD_EPSILON)
{
btQuaternion perturbeRot(v0,perturbeAngle);
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
if (perturbeA)
{
input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0Wrap->getWorldTransform().getBasis());
input.m_transformB = body1Wrap->getWorldTransform();
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
#endif //DEBUG_CONTACTS
} else
{
input.m_transformA = body0Wrap->getWorldTransform();
input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1Wrap->getWorldTransform().getBasis());
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
#endif
}
btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
}
}
}
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_CONVEX_ALGORITHM_H
#define CONVEX_CONVEX_ALGORITHM_H
#ifndef BT_CONVEX_CONVEX_ALGORITHM_H
#define BT_CONVEX_CONVEX_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
@ -32,7 +32,7 @@ class btConvexPenetrationDepthSolver;
///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util
///for certain pairs that have a small size ratio
#define USE_SEPDISTANCE_UTIL2 1
//#define USE_SEPDISTANCE_UTIL2 1
///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects.
///Multiple contact points are calculated by perturbing the orientation of the smallest object orthogonal to the separating normal.
@ -59,12 +59,11 @@ class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
public:
btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
virtual ~btConvexConvexAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -96,14 +95,14 @@ public:
virtual ~CreateFunc();
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm));
return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
};
};
#endif //CONVEX_CONVEX_ALGORITHM_H
#endif //BT_CONVEX_CONVEX_ALGORITHM_H

View file

@ -19,10 +19,11 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
//#include <stdio.h>
btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold)
btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold)
: btCollisionAlgorithm(ci),
m_ownManifold(false),
m_manifoldPtr(mf),
@ -30,12 +31,12 @@ m_isSwapped(isSwapped),
m_numPerturbationIterations(numPerturbationIterations),
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
{
btCollisionObject* convexObj = m_isSwapped? col1 : col0;
btCollisionObject* planeObj = m_isSwapped? col0 : col1;
const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? col1Wrap : col0Wrap;
const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? col0Wrap : col1Wrap;
if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj))
if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObjWrap->getCollisionObject(),planeObjWrap->getCollisionObject()))
{
m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj);
m_manifoldPtr = m_dispatcher->getNewManifold(convexObjWrap->getCollisionObject(),planeObjWrap->getCollisionObject());
m_ownManifold = true;
}
}
@ -50,25 +51,25 @@ btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm()
}
}
void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
btCollisionObject* planeObj = m_isSwapped? body0: body1;
const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? body1Wrap : body0Wrap;
const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? body0Wrap: body1Wrap;
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
btConvexShape* convexShape = (btConvexShape*) convexObjWrap->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObjWrap->getCollisionShape();
bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant();
btTransform convexWorldTransform = convexObj->getWorldTransform();
btTransform convexWorldTransform = convexObjWrap->getWorldTransform();
btTransform convexInPlaneTrans;
convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexWorldTransform;
convexInPlaneTrans= planeObjWrap->getWorldTransform().inverse() * convexWorldTransform;
//now perturbe the convex-world transform
convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot);
btTransform planeInConvex;
planeInConvex= convexWorldTransform.inverse() * planeObj->getWorldTransform();
planeInConvex= convexWorldTransform.inverse() * planeObjWrap->getWorldTransform();
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
@ -76,43 +77,61 @@ void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion&
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
btVector3 vtxInPlaneWorld = planeObj->getWorldTransform() * vtxInPlaneProjected;
btVector3 vtxInPlaneWorld = planeObjWrap->getWorldTransform() * vtxInPlaneProjected;
hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold();
resultOut->setPersistentManifold(m_manifoldPtr);
if (hasCollision)
{
/// report a contact. internally this will be kept persistent, and contact reduction is done
btVector3 normalOnSurfaceB = planeObj->getWorldTransform().getBasis() * planeNormal;
btVector3 normalOnSurfaceB = planeObjWrap->getWorldTransform().getBasis() * planeNormal;
btVector3 pOnB = vtxInPlaneWorld;
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
}
}
void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btConvexPlaneCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
if (!m_manifoldPtr)
return;
btCollisionObject* convexObj = m_isSwapped? body1 : body0;
btCollisionObject* planeObj = m_isSwapped? body0: body1;
const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? body1Wrap : body0Wrap;
const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? body0Wrap: body1Wrap;
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
btConvexShape* convexShape = (btConvexShape*) convexObjWrap->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObjWrap->getCollisionShape();
bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
//const btScalar& planeConstant = planeShape->getPlaneConstant();
const btScalar& planeConstant = planeShape->getPlaneConstant();
btTransform planeInConvex;
planeInConvex= convexObjWrap->getWorldTransform().inverse() * planeObjWrap->getWorldTransform();
btTransform convexInPlaneTrans;
convexInPlaneTrans= planeObjWrap->getWorldTransform().inverse() * convexObjWrap->getWorldTransform();
//first perform a collision query with the non-perturbated collision objects
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
btVector3 vtxInPlane = convexInPlaneTrans(vtx);
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
btVector3 vtxInPlaneWorld = planeObjWrap->getWorldTransform() * vtxInPlaneProjected;
hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold();
resultOut->setPersistentManifold(m_manifoldPtr);
if (hasCollision)
{
btQuaternion rotq(0,0,0,1);
collideSingleContact(rotq,body0,body1,dispatchInfo,resultOut);
/// report a contact. internally this will be kept persistent, and contact reduction is done
btVector3 normalOnSurfaceB = planeObjWrap->getWorldTransform().getBasis() * planeNormal;
btVector3 pOnB = vtxInPlaneWorld;
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
}
if (resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)
//the perturbation algorithm doesn't work well with implicit surfaces such as spheres, cylinder and cones:
//they keep on rolling forever because of the additional off-center contact points
//so only enable the feature for polyhedral shapes (btBoxShape, btConvexHullShape etc)
if (convexShape->isPolyhedral() && resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)
{
btVector3 v0,v1;
btPlaneSpace1(planeNormal,v0,v1);
@ -130,7 +149,7 @@ void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0
{
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
btQuaternion rotq(planeNormal,iterationAngle);
collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0,body1,dispatchInfo,resultOut);
collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0Wrap,body1Wrap,dispatchInfo,resultOut);
}
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONVEX_PLANE_COLLISION_ALGORITHM_H
#define CONVEX_PLANE_COLLISION_ALGORITHM_H
#ifndef BT_CONVEX_PLANE_COLLISION_ALGORITHM_H
#define BT_CONVEX_PLANE_COLLISION_ALGORITHM_H
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@ -36,13 +36,13 @@ class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm
public:
btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold);
btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold);
virtual ~btConvexPlaneCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
void collideSingleContact (const btQuaternion& perturbeRot, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -61,24 +61,24 @@ public:
CreateFunc()
: m_numPerturbationIterations(1),
m_minimumPointsPerturbationThreshold(1)
m_minimumPointsPerturbationThreshold(0)
{
}
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm));
if (!m_swapped)
{
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
} else
{
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
}
};
};
#endif //CONVEX_PLANE_COLLISION_ALGORITHM_H
#endif //BT_CONVEX_PLANE_COLLISION_ALGORITHM_H

View file

@ -296,3 +296,14 @@ void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int nu
convexConvex->m_numPerturbationIterations = numPerturbationIterations;
convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
}
void btDefaultCollisionConfiguration::setPlaneConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
{
btConvexPlaneCollisionAlgorithm::CreateFunc* cpCF = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_convexPlaneCF;
cpCF->m_numPerturbationIterations = numPerturbationIterations;
cpCF->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
btConvexPlaneCollisionAlgorithm::CreateFunc* pcCF = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_planeConvexCF;
pcCF->m_numPerturbationIterations = numPerturbationIterations;
pcCF->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
}

View file

@ -78,10 +78,8 @@ protected:
btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
btCollisionAlgorithmCreateFunc* m_sphereSphereCF;
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
btCollisionAlgorithmCreateFunc* m_sphereBoxCF;
btCollisionAlgorithmCreateFunc* m_boxSphereCF;
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
btCollisionAlgorithmCreateFunc* m_boxBoxCF;
btCollisionAlgorithmCreateFunc* m_sphereTriangleCF;
@ -112,6 +110,11 @@ public:
return m_stackAlloc;
}
virtual btVoronoiSimplexSolver* getSimplexSolver()
{
return m_simplexSolver;
}
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
@ -124,6 +127,8 @@ public:
///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection.
void setConvexConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3);
void setPlaneConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3);
};
#endif //BT_DEFAULT_COLLISION_CONFIGURATION

View file

@ -22,7 +22,7 @@ btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& c
{
}
void btEmptyAlgorithm::processCollision (btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* )
void btEmptyAlgorithm::processCollision (const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* ,const btDispatcherInfo& ,btManifoldResult* )
{
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EMPTY_ALGORITH
#define EMPTY_ALGORITH
#ifndef BT_EMPTY_ALGORITH
#define BT_EMPTY_ALGORITH
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
#include "btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h"
@ -30,7 +30,7 @@ public:
btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci);
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -40,10 +40,10 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
(void)body0;
(void)body1;
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
(void)body0Wrap;
(void)body1Wrap;
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm));
return new(mem) btEmptyAlgorithm(ci);
}
@ -51,4 +51,4 @@ public:
} ATTRIBUTE_ALIGNED(16);
#endif //EMPTY_ALGORITH
#endif //BT_EMPTY_ALGORITH

View file

@ -160,7 +160,7 @@ public:
return 0;
}
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher)
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
{
btAssert(0);
//need to keep track of all ghost objects and call them here
@ -171,4 +171,5 @@ public:
};
#endif
#endif

View file

@ -0,0 +1,842 @@
#include "btInternalEdgeUtility.h"
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
#include "LinearMath/btIDebugDraw.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
//#define DEBUG_INTERNAL_EDGE
#ifdef DEBUG_INTERNAL_EDGE
#include <stdio.h>
#endif //DEBUG_INTERNAL_EDGE
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
static btIDebugDraw* gDebugDrawer = 0;
void btSetDebugDrawer(btIDebugDraw* debugDrawer)
{
gDebugDrawer = debugDrawer;
}
static void btDebugDrawLine(const btVector3& from,const btVector3& to, const btVector3& color)
{
if (gDebugDrawer)
gDebugDrawer->drawLine(from,to,color);
}
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
static int btGetHash(int partId, int triangleIndex)
{
int hash = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
return hash;
}
static btScalar btGetAngle(const btVector3& edgeA, const btVector3& normalA,const btVector3& normalB)
{
const btVector3 refAxis0 = edgeA;
const btVector3 refAxis1 = normalA;
const btVector3 swingAxis = normalB;
btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1));
return angle;
}
struct btConnectivityProcessor : public btTriangleCallback
{
int m_partIdA;
int m_triangleIndexA;
btVector3* m_triangleVerticesA;
btTriangleInfoMap* m_triangleInfoMap;
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
{
//skip self-collisions
if ((m_partIdA == partId) && (m_triangleIndexA == triangleIndex))
return;
//skip duplicates (disabled for now)
//if ((m_partIdA <= partId) && (m_triangleIndexA <= triangleIndex))
// return;
//search for shared vertices and edges
int numshared = 0;
int sharedVertsA[3]={-1,-1,-1};
int sharedVertsB[3]={-1,-1,-1};
///skip degenerate triangles
btScalar crossBSqr = ((triangle[1]-triangle[0]).cross(triangle[2]-triangle[0])).length2();
if (crossBSqr < m_triangleInfoMap->m_equalVertexThreshold)
return;
btScalar crossASqr = ((m_triangleVerticesA[1]-m_triangleVerticesA[0]).cross(m_triangleVerticesA[2]-m_triangleVerticesA[0])).length2();
///skip degenerate triangles
if (crossASqr< m_triangleInfoMap->m_equalVertexThreshold)
return;
#if 0
printf("triangle A[0] = (%f,%f,%f)\ntriangle A[1] = (%f,%f,%f)\ntriangle A[2] = (%f,%f,%f)\n",
m_triangleVerticesA[0].getX(),m_triangleVerticesA[0].getY(),m_triangleVerticesA[0].getZ(),
m_triangleVerticesA[1].getX(),m_triangleVerticesA[1].getY(),m_triangleVerticesA[1].getZ(),
m_triangleVerticesA[2].getX(),m_triangleVerticesA[2].getY(),m_triangleVerticesA[2].getZ());
printf("partId=%d, triangleIndex=%d\n",partId,triangleIndex);
printf("triangle B[0] = (%f,%f,%f)\ntriangle B[1] = (%f,%f,%f)\ntriangle B[2] = (%f,%f,%f)\n",
triangle[0].getX(),triangle[0].getY(),triangle[0].getZ(),
triangle[1].getX(),triangle[1].getY(),triangle[1].getZ(),
triangle[2].getX(),triangle[2].getY(),triangle[2].getZ());
#endif
for (int i=0;i<3;i++)
{
for (int j=0;j<3;j++)
{
if ( (m_triangleVerticesA[i]-triangle[j]).length2() < m_triangleInfoMap->m_equalVertexThreshold)
{
sharedVertsA[numshared] = i;
sharedVertsB[numshared] = j;
numshared++;
///degenerate case
if(numshared >= 3)
return;
}
}
///degenerate case
if(numshared >= 3)
return;
}
switch (numshared)
{
case 0:
{
break;
}
case 1:
{
//shared vertex
break;
}
case 2:
{
//shared edge
//we need to make sure the edge is in the order V2V0 and not V0V2 so that the signs are correct
if (sharedVertsA[0] == 0 && sharedVertsA[1] == 2)
{
sharedVertsA[0] = 2;
sharedVertsA[1] = 0;
int tmp = sharedVertsB[1];
sharedVertsB[1] = sharedVertsB[0];
sharedVertsB[0] = tmp;
}
int hash = btGetHash(m_partIdA,m_triangleIndexA);
btTriangleInfo* info = m_triangleInfoMap->find(hash);
if (!info)
{
btTriangleInfo tmp;
m_triangleInfoMap->insert(hash,tmp);
info = m_triangleInfoMap->find(hash);
}
int sumvertsA = sharedVertsA[0]+sharedVertsA[1];
int otherIndexA = 3-sumvertsA;
btVector3 edge(m_triangleVerticesA[sharedVertsA[1]]-m_triangleVerticesA[sharedVertsA[0]]);
btTriangleShape tA(m_triangleVerticesA[0],m_triangleVerticesA[1],m_triangleVerticesA[2]);
int otherIndexB = 3-(sharedVertsB[0]+sharedVertsB[1]);
btTriangleShape tB(triangle[sharedVertsB[1]],triangle[sharedVertsB[0]],triangle[otherIndexB]);
//btTriangleShape tB(triangle[0],triangle[1],triangle[2]);
btVector3 normalA;
btVector3 normalB;
tA.calcNormal(normalA);
tB.calcNormal(normalB);
edge.normalize();
btVector3 edgeCrossA = edge.cross(normalA).normalize();
{
btVector3 tmp = m_triangleVerticesA[otherIndexA]-m_triangleVerticesA[sharedVertsA[0]];
if (edgeCrossA.dot(tmp) < 0)
{
edgeCrossA*=-1;
}
}
btVector3 edgeCrossB = edge.cross(normalB).normalize();
{
btVector3 tmp = triangle[otherIndexB]-triangle[sharedVertsB[0]];
if (edgeCrossB.dot(tmp) < 0)
{
edgeCrossB*=-1;
}
}
btScalar angle2 = 0;
btScalar ang4 = 0.f;
btVector3 calculatedEdge = edgeCrossA.cross(edgeCrossB);
btScalar len2 = calculatedEdge.length2();
btScalar correctedAngle(0);
btVector3 calculatedNormalB = normalA;
bool isConvex = false;
if (len2<m_triangleInfoMap->m_planarEpsilon)
{
angle2 = 0.f;
ang4 = 0.f;
} else
{
calculatedEdge.normalize();
btVector3 calculatedNormalA = calculatedEdge.cross(edgeCrossA);
calculatedNormalA.normalize();
angle2 = btGetAngle(calculatedNormalA,edgeCrossA,edgeCrossB);
ang4 = SIMD_PI-angle2;
btScalar dotA = normalA.dot(edgeCrossB);
///@todo: check if we need some epsilon, due to floating point imprecision
isConvex = (dotA<0.);
correctedAngle = isConvex ? ang4 : -ang4;
btQuaternion orn2(calculatedEdge,-correctedAngle);
calculatedNormalB = btMatrix3x3(orn2)*normalA;
}
//alternatively use
//btVector3 calculatedNormalB2 = quatRotate(orn,normalA);
switch (sumvertsA)
{
case 1:
{
btVector3 edge = m_triangleVerticesA[0]-m_triangleVerticesA[1];
btQuaternion orn(edge,-correctedAngle);
btVector3 computedNormalB = quatRotate(orn,normalA);
btScalar bla = computedNormalB.dot(normalB);
if (bla<0)
{
computedNormalB*=-1;
info->m_flags |= TRI_INFO_V0V1_SWAP_NORMALB;
}
#ifdef DEBUG_INTERNAL_EDGE
if ((computedNormalB-normalB).length()>0.0001)
{
printf("warning: normals not identical\n");
}
#endif//DEBUG_INTERNAL_EDGE
info->m_edgeV0V1Angle = -correctedAngle;
if (isConvex)
info->m_flags |= TRI_INFO_V0V1_CONVEX;
break;
}
case 2:
{
btVector3 edge = m_triangleVerticesA[2]-m_triangleVerticesA[0];
btQuaternion orn(edge,-correctedAngle);
btVector3 computedNormalB = quatRotate(orn,normalA);
if (computedNormalB.dot(normalB)<0)
{
computedNormalB*=-1;
info->m_flags |= TRI_INFO_V2V0_SWAP_NORMALB;
}
#ifdef DEBUG_INTERNAL_EDGE
if ((computedNormalB-normalB).length()>0.0001)
{
printf("warning: normals not identical\n");
}
#endif //DEBUG_INTERNAL_EDGE
info->m_edgeV2V0Angle = -correctedAngle;
if (isConvex)
info->m_flags |= TRI_INFO_V2V0_CONVEX;
break;
}
case 3:
{
btVector3 edge = m_triangleVerticesA[1]-m_triangleVerticesA[2];
btQuaternion orn(edge,-correctedAngle);
btVector3 computedNormalB = quatRotate(orn,normalA);
if (computedNormalB.dot(normalB)<0)
{
info->m_flags |= TRI_INFO_V1V2_SWAP_NORMALB;
computedNormalB*=-1;
}
#ifdef DEBUG_INTERNAL_EDGE
if ((computedNormalB-normalB).length()>0.0001)
{
printf("warning: normals not identical\n");
}
#endif //DEBUG_INTERNAL_EDGE
info->m_edgeV1V2Angle = -correctedAngle;
if (isConvex)
info->m_flags |= TRI_INFO_V1V2_CONVEX;
break;
}
}
break;
}
default:
{
// printf("warning: duplicate triangle\n");
}
}
}
};
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap)
{
//the user pointer shouldn't already be used for other purposes, we intend to store connectivity info there!
if (trimeshShape->getTriangleInfoMap())
return;
trimeshShape->setTriangleInfoMap(triangleInfoMap);
btStridingMeshInterface* meshInterface = trimeshShape->getMeshInterface();
const btVector3& meshScaling = meshInterface->getScaling();
for (int partId = 0; partId< meshInterface->getNumSubParts();partId++)
{
const unsigned char *vertexbase = 0;
int numverts = 0;
PHY_ScalarType type = PHY_INTEGER;
int stride = 0;
const unsigned char *indexbase = 0;
int indexstride = 0;
int numfaces = 0;
PHY_ScalarType indicestype = PHY_INTEGER;
//PHY_ScalarType indexType=0;
btVector3 triangleVerts[3];
meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
btVector3 aabbMin,aabbMax;
for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
{
unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
if (type == PHY_FLOAT)
{
float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = btVector3(
graphicsbase[0]*meshScaling.getX(),
graphicsbase[1]*meshScaling.getY(),
graphicsbase[2]*meshScaling.getZ());
}
else
{
double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ()));
}
}
aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
aabbMin.setMin(triangleVerts[0]);
aabbMax.setMax(triangleVerts[0]);
aabbMin.setMin(triangleVerts[1]);
aabbMax.setMax(triangleVerts[1]);
aabbMin.setMin(triangleVerts[2]);
aabbMax.setMax(triangleVerts[2]);
btConnectivityProcessor connectivityProcessor;
connectivityProcessor.m_partIdA = partId;
connectivityProcessor.m_triangleIndexA = triangleIndex;
connectivityProcessor.m_triangleVerticesA = &triangleVerts[0];
connectivityProcessor.m_triangleInfoMap = triangleInfoMap;
trimeshShape->processAllTriangles(&connectivityProcessor,aabbMin,aabbMax);
}
}
}
// Given a point and a line segment (defined by two points), compute the closest point
// in the line. Cap the point at the endpoints of the line segment.
void btNearestPointInLineSegment(const btVector3 &point, const btVector3& line0, const btVector3& line1, btVector3& nearestPoint)
{
btVector3 lineDelta = line1 - line0;
// Handle degenerate lines
if ( lineDelta.fuzzyZero())
{
nearestPoint = line0;
}
else
{
btScalar delta = (point-line0).dot(lineDelta) / (lineDelta).dot(lineDelta);
// Clamp the point to conform to the segment's endpoints
if ( delta < 0 )
delta = 0;
else if ( delta > 1 )
delta = 1;
nearestPoint = line0 + lineDelta*delta;
}
}
bool btClampNormal(const btVector3& edge,const btVector3& tri_normal_org,const btVector3& localContactNormalOnB, btScalar correctedEdgeAngle, btVector3 & clampedLocalNormal)
{
btVector3 tri_normal = tri_normal_org;
//we only have a local triangle normal, not a local contact normal -> only normal in world space...
//either compute the current angle all in local space, or all in world space
btVector3 edgeCross = edge.cross(tri_normal).normalize();
btScalar curAngle = btGetAngle(edgeCross,tri_normal,localContactNormalOnB);
if (correctedEdgeAngle<0)
{
if (curAngle < correctedEdgeAngle)
{
btScalar diffAngle = correctedEdgeAngle-curAngle;
btQuaternion rotation(edge,diffAngle );
clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB;
return true;
}
}
if (correctedEdgeAngle>=0)
{
if (curAngle > correctedEdgeAngle)
{
btScalar diffAngle = correctedEdgeAngle-curAngle;
btQuaternion rotation(edge,diffAngle );
clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB;
return true;
}
}
return false;
}
/// Changes a btManifoldPoint collision normal to the normal from the mesh.
void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,const btCollisionObjectWrapper* colObj1Wrap, int partId0, int index0, int normalAdjustFlags)
{
//btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE);
if (colObj0Wrap->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE)
return;
btBvhTriangleMeshShape* trimesh = 0;
if( colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE )
trimesh = ((btScaledBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape())->getChildShape();
else
trimesh = (btBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape();
btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*) trimesh->getTriangleInfoMap();
if (!triangleInfoMapPtr)
return;
int hash = btGetHash(partId0,index0);
btTriangleInfo* info = triangleInfoMapPtr->find(hash);
if (!info)
return;
btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE)==0? 1.f : -1.f;
const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0Wrap->getCollisionShape());
btVector3 v0,v1,v2;
tri_shape->getVertex(0,v0);
tri_shape->getVertex(1,v1);
tri_shape->getVertex(2,v2);
//btVector3 center = (v0+v1+v2)*btScalar(1./3.);
btVector3 red(1,0,0), green(0,1,0),blue(0,0,1),white(1,1,1),black(0,0,0);
btVector3 tri_normal;
tri_shape->calcNormal(tri_normal);
//btScalar dot = tri_normal.dot(cp.m_normalWorldOnB);
btVector3 nearest;
btNearestPointInLineSegment(cp.m_localPointB,v0,v1,nearest);
btVector3 contact = cp.m_localPointB;
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
const btTransform& tr = colObj0->getWorldTransform();
btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,red);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
bool isNearEdge = false;
int numConcaveEdgeHits = 0;
int numConvexEdgeHits = 0;
btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
localContactNormalOnB.normalize();//is this necessary?
// Get closest edge
int bestedge=-1;
btScalar disttobestedge=BT_LARGE_FLOAT;
//
// Edge 0 -> 1
if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
btVector3 nearest;
btNearestPointInLineSegment( cp.m_localPointB, v0, v1, nearest );
btScalar len=(contact-nearest).length();
//
if( len < disttobestedge )
{
bestedge=0;
disttobestedge=len;
}
}
// Edge 1 -> 2
if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
btVector3 nearest;
btNearestPointInLineSegment( cp.m_localPointB, v1, v2, nearest );
btScalar len=(contact-nearest).length();
//
if( len < disttobestedge )
{
bestedge=1;
disttobestedge=len;
}
}
// Edge 2 -> 0
if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
btVector3 nearest;
btNearestPointInLineSegment( cp.m_localPointB, v2, v0, nearest );
btScalar len=(contact-nearest).length();
//
if( len < disttobestedge )
{
bestedge=2;
disttobestedge=len;
}
}
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btVector3 upfix=tri_normal * btVector3(0.1f,0.1f,0.1f);
btDebugDrawLine(tr * v0 + upfix, tr * v1 + upfix, red );
#endif
if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
#endif
btScalar len = (contact-nearest).length();
if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
if( bestedge==0 )
{
btVector3 edge(v0-v1);
isNearEdge = true;
if (info->m_edgeV0V1Angle==btScalar(0))
{
numConcaveEdgeHits++;
} else
{
bool isEdgeConvex = (info->m_flags & TRI_INFO_V0V1_CONVEX);
btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
btVector3 nA = swapFactor * tri_normal;
btQuaternion orn(edge,info->m_edgeV0V1Angle);
btVector3 computedNormalB = quatRotate(orn,tri_normal);
if (info->m_flags & TRI_INFO_V0V1_SWAP_NORMALB)
computedNormalB*=-1;
btVector3 nB = swapFactor*computedNormalB;
btScalar NdotA = localContactNormalOnB.dot(nA);
btScalar NdotB = localContactNormalOnB.dot(nB);
bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
#ifdef DEBUG_INTERNAL_EDGE
{
btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
}
#endif //DEBUG_INTERNAL_EDGE
if (backFacingNormal)
{
numConcaveEdgeHits++;
}
else
{
numConvexEdgeHits++;
btVector3 clampedLocalNormal;
bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV0V1Angle,clampedLocalNormal);
if (isClamped)
{
if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
{
btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
cp.m_normalWorldOnB = newNormal;
// Reproject collision point along normal. (what about cp.m_distance1?)
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
}
}
}
}
}
btNearestPointInLineSegment(contact,v1,v2,nearest);
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,green);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr * v1 + upfix, tr * v2 + upfix , green );
#endif
if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
btScalar len = (contact-nearest).length();
if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
if( bestedge==1 )
{
isNearEdge = true;
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
btVector3 edge(v1-v2);
isNearEdge = true;
if (info->m_edgeV1V2Angle == btScalar(0))
{
numConcaveEdgeHits++;
} else
{
bool isEdgeConvex = (info->m_flags & TRI_INFO_V1V2_CONVEX)!=0;
btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
btVector3 nA = swapFactor * tri_normal;
btQuaternion orn(edge,info->m_edgeV1V2Angle);
btVector3 computedNormalB = quatRotate(orn,tri_normal);
if (info->m_flags & TRI_INFO_V1V2_SWAP_NORMALB)
computedNormalB*=-1;
btVector3 nB = swapFactor*computedNormalB;
#ifdef DEBUG_INTERNAL_EDGE
{
btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
}
#endif //DEBUG_INTERNAL_EDGE
btScalar NdotA = localContactNormalOnB.dot(nA);
btScalar NdotB = localContactNormalOnB.dot(nB);
bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
if (backFacingNormal)
{
numConcaveEdgeHits++;
}
else
{
numConvexEdgeHits++;
btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
btVector3 clampedLocalNormal;
bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal);
if (isClamped)
{
if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
{
btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
cp.m_normalWorldOnB = newNormal;
// Reproject collision point along normal.
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
}
}
}
}
}
btNearestPointInLineSegment(contact,v2,v0,nearest);
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,blue);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr * v2 + upfix, tr * v0 + upfix , blue );
#endif
if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold)
{
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
btScalar len = (contact-nearest).length();
if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
if( bestedge==2 )
{
isNearEdge = true;
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
btVector3 edge(v2-v0);
if (info->m_edgeV2V0Angle==btScalar(0))
{
numConcaveEdgeHits++;
} else
{
bool isEdgeConvex = (info->m_flags & TRI_INFO_V2V0_CONVEX)!=0;
btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
btVector3 nA = swapFactor * tri_normal;
btQuaternion orn(edge,info->m_edgeV2V0Angle);
btVector3 computedNormalB = quatRotate(orn,tri_normal);
if (info->m_flags & TRI_INFO_V2V0_SWAP_NORMALB)
computedNormalB*=-1;
btVector3 nB = swapFactor*computedNormalB;
#ifdef DEBUG_INTERNAL_EDGE
{
btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
}
#endif //DEBUG_INTERNAL_EDGE
btScalar NdotA = localContactNormalOnB.dot(nA);
btScalar NdotB = localContactNormalOnB.dot(nB);
bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
if (backFacingNormal)
{
numConcaveEdgeHits++;
}
else
{
numConvexEdgeHits++;
// printf("hitting convex edge\n");
btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
btVector3 clampedLocalNormal;
bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal);
if (isClamped)
{
if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
{
btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
cp.m_normalWorldOnB = newNormal;
// Reproject collision point along normal.
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
}
}
}
}
}
#ifdef DEBUG_INTERNAL_EDGE
{
btVector3 color(0,1,1);
btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+cp.m_normalWorldOnB*10,color);
}
#endif //DEBUG_INTERNAL_EDGE
if (isNearEdge)
{
if (numConcaveEdgeHits>0)
{
if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_DOUBLE_SIDED)!=0)
{
//fix tri_normal so it pointing the same direction as the current local contact normal
if (tri_normal.dot(localContactNormalOnB) < 0)
{
tri_normal *= -1;
}
cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis()*tri_normal;
} else
{
btVector3 newNormal = tri_normal *frontFacing;
//if the tri_normal is pointing opposite direction as the current local contact normal, skip it
btScalar d = newNormal.dot(localContactNormalOnB) ;
if (d< 0)
{
return;
}
//modify the normal to be the triangle normal (or backfacing normal)
cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis() *newNormal;
}
// Reproject collision point along normal.
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
}
}

View file

@ -0,0 +1,47 @@
#ifndef BT_INTERNAL_EDGE_UTILITY_H
#define BT_INTERNAL_EDGE_UTILITY_H
#include "LinearMath/btHashMap.h"
#include "LinearMath/btVector3.h"
#include "BulletCollision/CollisionShapes/btTriangleInfoMap.h"
///The btInternalEdgeUtility helps to avoid or reduce artifacts due to wrong collision normals caused by internal edges.
///See also http://code.google.com/p/bullet/issues/detail?id=27
class btBvhTriangleMeshShape;
class btCollisionObject;
struct btCollisionObjectWrapper;
class btManifoldPoint;
class btIDebugDraw;
enum btInternalEdgeAdjustFlags
{
BT_TRIANGLE_CONVEX_BACKFACE_MODE = 1,
BT_TRIANGLE_CONCAVE_DOUBLE_SIDED = 2, //double sided options are experimental, single sided is recommended
BT_TRIANGLE_CONVEX_DOUBLE_SIDED = 4
};
///Call btGenerateInternalEdgeInfo to create triangle info, store in the shape 'userInfo'
void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap);
///Call the btFixMeshNormal to adjust the collision normal, using the triangle info map (generated using btGenerateInternalEdgeInfo)
///If this info map is missing, or the triangle is not store in this map, nothing will be done
void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* trimeshColObj0Wrap,const btCollisionObjectWrapper* otherColObj1Wrap, int partId0, int index0, int normalAdjustFlags = 0);
///Enable the BT_INTERNAL_EDGE_DEBUG_DRAW define and call btSetDebugDrawer, to get visual info to see if the internal edge utility works properly.
///If the utility doesn't work properly, you might have to adjust the threshold values in btTriangleInfoMap
//#define BT_INTERNAL_EDGE_DEBUG_DRAW
#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
void btSetDebugDrawer(btIDebugDraw* debugDrawer);
#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
#endif //BT_INTERNAL_EDGE_UTILITY_H

View file

@ -17,13 +17,30 @@ subject to the following restrictions:
#include "btManifoldResult.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
///This is to allow MaterialCombiner/Custom Friction/Restitution values
ContactAddedCallback gContactAddedCallback=0;
///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1)
inline btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1)
{
btScalar friction = body0->getRollingFriction() * body1->getRollingFriction();
const btScalar MAX_FRICTION = btScalar(10.);
if (friction < -MAX_FRICTION)
friction = -MAX_FRICTION;
if (friction > MAX_FRICTION)
friction = MAX_FRICTION;
return friction;
}
///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
btScalar btManifoldResult::calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1)
{
btScalar friction = body0->getFriction() * body1->getFriction();
@ -36,17 +53,17 @@ inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const b
}
inline btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1)
btScalar btManifoldResult::calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1)
{
return body0->getRestitution() * body1->getRestitution();
}
btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* body1)
btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
:m_manifoldPtr(0),
m_body0(body0),
m_body1(body1)
m_body0Wrap(body0Wrap),
m_body1Wrap(body1Wrap)
#ifdef DEBUG_PART_INDEX
,m_partId0(-1),
m_partId1(-1),
@ -54,8 +71,6 @@ btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* b
m_index1(-1)
#endif //DEBUG_PART_INDEX
{
m_rootTransA = body0->getWorldTransform();
m_rootTransB = body1->getWorldTransform();
}
@ -63,11 +78,12 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
{
btAssert(m_manifoldPtr);
//order in manifold needs to match
if (depth > m_manifoldPtr->getContactBreakingThreshold())
// if (depth > m_manifoldPtr->getContactProcessingThreshold())
return;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
@ -76,12 +92,12 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
if (isSwapped)
{
localA = m_rootTransB.invXform(pointA );
localB = m_rootTransA.invXform(pointInWorld);
localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
} else
{
localA = m_rootTransA.invXform(pointA );
localB = m_rootTransB.invXform(pointInWorld);
localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
}
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
@ -90,9 +106,13 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1);
newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1);
newPt.m_combinedFriction = calculateCombinedFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
newPt.m_combinedRollingFriction = calculateCombinedRollingFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
btPlaneSpace1(newPt.m_normalWorldOnB,newPt.m_lateralFrictionDir1,newPt.m_lateralFrictionDir2);
//BP mod, store contact triangles.
if (isSwapped)
{
@ -121,13 +141,13 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
//User can override friction and/or restitution
if (gContactAddedCallback &&
//and if either of the two bodies requires custom material
((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
(m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
(m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
{
//experimental feature info, for per-triangle material etc.
btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
(*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0,newPt.m_partId0,newPt.m_index0,obj1,newPt.m_partId1,newPt.m_index1);
const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
(*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
}
}

View file

@ -14,18 +14,22 @@ subject to the following restrictions:
*/
#ifndef MANIFOLD_RESULT_H
#define MANIFOLD_RESULT_H
#ifndef BT_MANIFOLD_RESULT_H
#define BT_MANIFOLD_RESULT_H
class btCollisionObject;
struct btCollisionObjectWrapper;
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
class btManifoldPoint;
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "LinearMath/btTransform.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1);
extern ContactAddedCallback gContactAddedCallback;
//#define DEBUG_PART_INDEX 1
@ -34,14 +38,12 @@ extern ContactAddedCallback gContactAddedCallback;
///btManifoldResult is a helper class to manage contact results.
class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
{
protected:
btPersistentManifold* m_manifoldPtr;
//we need this for compounds
btTransform m_rootTransA;
btTransform m_rootTransB;
btCollisionObject* m_body0;
btCollisionObject* m_body1;
const btCollisionObjectWrapper* m_body0Wrap;
const btCollisionObjectWrapper* m_body1Wrap;
int m_partId0;
int m_partId1;
int m_index0;
@ -61,7 +63,7 @@ public:
{
}
btManifoldResult(btCollisionObject* body0,btCollisionObject* body1);
btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btManifoldResult() {};
@ -100,27 +102,49 @@ public:
if (!m_manifoldPtr->getNumContacts())
return;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
if (isSwapped)
{
m_manifoldPtr->refreshContactPoints(m_rootTransB,m_rootTransA);
m_manifoldPtr->refreshContactPoints(m_body1Wrap->getCollisionObject()->getWorldTransform(),m_body0Wrap->getCollisionObject()->getWorldTransform());
} else
{
m_manifoldPtr->refreshContactPoints(m_rootTransA,m_rootTransB);
m_manifoldPtr->refreshContactPoints(m_body0Wrap->getCollisionObject()->getWorldTransform(),m_body1Wrap->getCollisionObject()->getWorldTransform());
}
}
const btCollisionObjectWrapper* getBody0Wrap() const
{
return m_body0Wrap;
}
const btCollisionObjectWrapper* getBody1Wrap() const
{
return m_body1Wrap;
}
void setBody0Wrap(const btCollisionObjectWrapper* obj0Wrap)
{
m_body0Wrap = obj0Wrap;
}
void setBody1Wrap(const btCollisionObjectWrapper* obj1Wrap)
{
m_body1Wrap = obj1Wrap;
}
const btCollisionObject* getBody0Internal() const
{
return m_body0;
return m_body0Wrap->getCollisionObject();
}
const btCollisionObject* getBody1Internal() const
{
return m_body1;
return m_body1Wrap->getCollisionObject();
}
/// in the future we can let the user override the methods to combine restitution and friction
static btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1);
static btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1);
};
#endif //MANIFOLD_RESULT_H
#endif //BT_MANIFOLD_RESULT_H

View file

@ -1,3 +1,4 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
@ -44,10 +45,14 @@ void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btColl
{
{
for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
btOverlappingPairCache* pairCachePtr = colWorld->getPairCache();
const int numOverlappingPairs = pairCachePtr->getNumOverlappingPairs();
if (numOverlappingPairs)
{
btBroadphasePair* pairPtr = pairCachePtr->getOverlappingPairArrayPtr();
for (int i=0;i<numOverlappingPairs;i++)
{
btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
const btBroadphasePair& collisionPair = pairPtr[i];
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
@ -60,18 +65,73 @@ void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btColl
(colObj1)->getIslandTag());
}
}
}
}
}
#ifdef STATIC_SIMULATION_ISLAND_OPTIMIZATION
void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher)
{
// put the index into m_controllers into m_tag
int index = 0;
{
int i;
for (i=0;i<colWorld->getCollisionObjectArray().size(); i++)
{
btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
//Adding filtering here
if (!collisionObject->isStaticOrKinematicObject())
{
collisionObject->setIslandTag(index++);
}
collisionObject->setCompanionId(-1);
collisionObject->setHitFraction(btScalar(1.));
}
}
// do the union find
initUnionFind( index );
findUnions(dispatcher,colWorld);
}
void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld)
{
// put the islandId ('find' value) into m_tag
{
int index = 0;
int i;
for (i=0;i<colWorld->getCollisionObjectArray().size();i++)
{
btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
if (!collisionObject->isStaticOrKinematicObject())
{
collisionObject->setIslandTag( m_unionFind.find(index) );
//Set the correct object offset in Collision Object Array
m_unionFind.getElement(index).m_sz = i;
collisionObject->setCompanionId(-1);
index++;
} else
{
collisionObject->setIslandTag(-1);
collisionObject->setCompanionId(-2);
}
}
}
}
#else //STATIC_SIMULATION_ISLAND_OPTIMIZATION
void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher)
{
initUnionFind( int (colWorld->getCollisionObjectArray().size()));
// put the index into m_controllers into m_tag
{
int index = 0;
int i;
for (i=0;i<colWorld->getCollisionObjectArray().size(); i++)
@ -81,26 +141,20 @@ void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld
collisionObject->setCompanionId(-1);
collisionObject->setHitFraction(btScalar(1.));
index++;
}
}
// do the union find
findUnions(dispatcher,colWorld);
}
void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld)
{
// put the islandId ('find' value) into m_tag
{
int index = 0;
int i;
for (i=0;i<colWorld->getCollisionObjectArray().size();i++)
@ -120,6 +174,8 @@ void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* col
}
}
#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION
inline int getIslandId(const btPersistentManifold* lhs)
{
int islandId;
@ -137,7 +193,7 @@ class btPersistentManifoldSortPredicate
{
public:
SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs )
SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs ) const
{
return getIslandId(lhs) < getIslandId(rhs);
}
@ -263,8 +319,8 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
{
btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
btCollisionObject* colObj0 = static_cast<btCollisionObject*>(manifold->getBody0());
btCollisionObject* colObj1 = static_cast<btCollisionObject*>(manifold->getBody1());
const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
///@todo: check sleeping conditions!
if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
@ -274,11 +330,13 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
//kinematic objects don't merge islands, but wake up all connected objects
if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
{
colObj1->activate();
if (colObj0->hasContactResponse())
colObj1->activate();
}
if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
{
colObj0->activate();
if (colObj1->hasContactResponse())
colObj0->activate();
}
if(m_splitIslands)
{
@ -309,7 +367,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
{
btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
int maxNumManifolds = dispatcher->getNumManifolds();
callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
callback->processIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
}
else
{
@ -319,8 +377,10 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
int numManifolds = int (m_islandmanifold.size());
//we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
//tried a radix sort, but quicksort/heapsort seems still faster
//@todo rewrite island management
m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());
//m_islandmanifold.heapSort(btPersistentManifoldSortPredicate());
//now process all active islands (sets of manifolds for now)
@ -339,15 +399,15 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
int islandId = getUnionFind().getElement(startIslandIndex).m_id;
bool islandSleeping = false;
bool islandSleeping = true;
for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
{
int i = getUnionFind().getElement(endIslandIndex).m_sz;
btCollisionObject* colObj0 = collisionObjects[i];
m_islandBodies.push_back(colObj0);
if (!colObj0->isActive())
islandSleeping = true;
if (colObj0->isActive())
islandSleeping = false;
}
@ -374,7 +434,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
if (!islandSleeping)
{
callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
callback->processIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
// printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SIMULATION_ISLAND_MANAGER_H
#define SIMULATION_ISLAND_MANAGER_H
#ifndef BT_SIMULATION_ISLAND_MANAGER_H
#define BT_SIMULATION_ISLAND_MANAGER_H
#include "BulletCollision/CollisionDispatch/btUnionFind.h"
#include "btCollisionCreateFunc.h"
@ -59,7 +59,7 @@ public:
{
virtual ~IslandCallback() {};
virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,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,btCollisionWorld* collisionWorld, IslandCallback* callback);
@ -77,5 +77,5 @@ public:
};
#endif //SIMULATION_ISLAND_MANAGER_H
#endif //BT_SIMULATION_ISLAND_MANAGER_H

View file

@ -18,20 +18,21 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionShapes/btBoxShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
//#include <stdio.h>
btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
: btActivatingCollisionAlgorithm(ci,col0,col1),
btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped)
: btActivatingCollisionAlgorithm(ci,col0Wrap,col1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf),
m_isSwapped(isSwapped)
{
btCollisionObject* sphereObj = m_isSwapped? col1 : col0;
btCollisionObject* boxObj = m_isSwapped? col0 : col1;
const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped? col1Wrap : col0Wrap;
const btCollisionObjectWrapper* boxObjWrap = m_isSwapped? col0Wrap : col1Wrap;
if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObj,boxObj))
if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObjWrap->getCollisionObject(),boxObjWrap->getCollisionObject()))
{
m_manifoldPtr = m_dispatcher->getNewManifold(sphereObj,boxObj);
m_manifoldPtr = m_dispatcher->getNewManifold(sphereObjWrap->getCollisionObject(),boxObjWrap->getCollisionObject());
m_ownManifold = true;
}
}
@ -48,36 +49,31 @@ btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm()
void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btSphereBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut)
{
(void)dispatchInfo;
(void)resultOut;
if (!m_manifoldPtr)
return;
btCollisionObject* sphereObj = m_isSwapped? body1 : body0;
btCollisionObject* boxObj = m_isSwapped? body0 : body1;
const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped? body1Wrap : body0Wrap;
const btCollisionObjectWrapper* boxObjWrap = m_isSwapped? body0Wrap : body1Wrap;
btSphereShape* sphere0 = (btSphereShape*)sphereObj->getCollisionShape();
btVector3 pOnBox;
btVector3 normalOnSurfaceB;
btVector3 pOnBox,pOnSphere;
btVector3 sphereCenter = sphereObj->getWorldTransform().getOrigin();
btScalar penetrationDepth;
btVector3 sphereCenter = sphereObjWrap->getWorldTransform().getOrigin();
const btSphereShape* sphere0 = (const btSphereShape*)sphereObjWrap->getCollisionShape();
btScalar radius = sphere0->getRadius();
btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
btScalar maxContactDistance = m_manifoldPtr->getContactBreakingThreshold();
resultOut->setPersistentManifold(m_manifoldPtr);
if (dist < SIMD_EPSILON)
if (getSphereDistance(boxObjWrap, pOnBox, normalOnSurfaceB, penetrationDepth, sphereCenter, radius, maxContactDistance))
{
btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize();
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist);
resultOut->addContactPoint(normalOnSurfaceB, pOnBox, penetrationDepth);
}
if (m_ownManifold)
@ -102,159 +98,117 @@ btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
}
btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* boxObj, btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius )
bool btSphereBoxCollisionAlgorithm::getSphereDistance(const btCollisionObjectWrapper* boxObjWrap, btVector3& pointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& sphereCenter, btScalar fRadius, btScalar maxContactDistance )
{
const btBoxShape* boxShape= (const btBoxShape*)boxObjWrap->getCollisionShape();
btVector3 const &boxHalfExtent = boxShape->getHalfExtentsWithoutMargin();
btScalar boxMargin = boxShape->getMargin();
penetrationDepth = 1.0f;
btScalar margins;
btVector3 bounds[2];
btBoxShape* boxShape= (btBoxShape*)boxObj->getCollisionShape();
// convert the sphere position to the box's local space
btTransform const &m44T = boxObjWrap->getWorldTransform();
btVector3 sphereRelPos = m44T.invXform(sphereCenter);
// Determine the closest point to the sphere center in the box
btVector3 closestPoint = sphereRelPos;
closestPoint.setX( btMin(boxHalfExtent.getX(), closestPoint.getX()) );
closestPoint.setX( btMax(-boxHalfExtent.getX(), closestPoint.getX()) );
closestPoint.setY( btMin(boxHalfExtent.getY(), closestPoint.getY()) );
closestPoint.setY( btMax(-boxHalfExtent.getY(), closestPoint.getY()) );
closestPoint.setZ( btMin(boxHalfExtent.getZ(), closestPoint.getZ()) );
closestPoint.setZ( btMax(-boxHalfExtent.getZ(), closestPoint.getZ()) );
bounds[0] = -boxShape->getHalfExtentsWithoutMargin();
bounds[1] = boxShape->getHalfExtentsWithoutMargin();
btScalar intersectionDist = fRadius + boxMargin;
btScalar contactDist = intersectionDist + maxContactDistance;
normal = sphereRelPos - closestPoint;
margins = boxShape->getMargin();//also add sphereShape margin?
const btTransform& m44T = boxObj->getWorldTransform();
btVector3 boundsVec[2];
btScalar fPenetration;
boundsVec[0] = bounds[0];
boundsVec[1] = bounds[1];
btVector3 marginsVec( margins, margins, margins );
// add margins
bounds[0] += marginsVec;
bounds[1] -= marginsVec;
/////////////////////////////////////////////////
btVector3 tmp, prel, n[6], normal, v3P;
btScalar fSep = btScalar(10000000.0), fSepThis;
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);
bool bFound = false;
v3P = prel;
for (int i=0;i<6;i++)
//if there is no penetration, we are done
btScalar dist2 = normal.length2();
if (dist2 > contactDist * contactDist)
{
int j = i<3? 0:1;
if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > btScalar(0.0) )
{
v3P = v3P - n[i]*fSepThis;
bFound = true;
}
}
//
if ( bFound )
{
bounds[0] = boundsVec[0];
bounds[1] = boundsVec[1];
normal = (prel - v3P).normalize();
pointOnBox = v3P + normal*margins;
v3PointOnSphere = prel - normal*fRadius;
if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > btScalar(0.0) )
{
return btScalar(1.0);
}
// transform back in world space
tmp = m44T( pointOnBox);
pointOnBox = tmp;
tmp = m44T( v3PointOnSphere);
v3PointOnSphere = tmp;
btScalar fSeps2 = (pointOnBox-v3PointOnSphere).length2();
//if this fails, fallback into deeper penetration case, below
if (fSeps2 > SIMD_EPSILON)
{
fSep = - btSqrt(fSeps2);
normal = (pointOnBox-v3PointOnSphere);
normal *= btScalar(1.)/fSep;
}
return fSep;
return false;
}
//////////////////////////////////////////////////
// Deep penetration case
btScalar distance;
fPenetration = getSpherePenetration( boxObj,pointOnBox, v3PointOnSphere, sphereCenter, fRadius,bounds[0],bounds[1] );
bounds[0] = boundsVec[0];
bounds[1] = boundsVec[1];
if ( fPenetration <= btScalar(0.0) )
return (fPenetration-margins);
else
return btScalar(1.0);
}
btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* boxObj,btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax)
{
btVector3 bounds[2];
bounds[0] = aabbMin;
bounds[1] = aabbMax;
btVector3 p0, tmp, prel, n[6], normal;
btScalar fSep = btScalar(-10000000.0), fSepThis;
// set p0 and normal to a default value to shup up GCC
p0.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
normal.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
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();
// convert point in local space
prel = m44T.invXform( sphereCenter);
///////////
for (int i=0;i<6;i++)
//special case if the sphere center is inside the box
if (dist2 <= SIMD_EPSILON)
{
int j = i<3 ? 0:1;
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];
fSep = fSepThis;
}
distance = -getSpherePenetration(boxHalfExtent, sphereRelPos, closestPoint, normal);
}
else //compute the penetration details
{
distance = normal.length();
normal /= distance;
}
pointOnBox = prel - normal*(normal.dot((prel-p0)));
v3PointOnSphere = pointOnBox + normal*fSep;
pointOnBox = closestPoint + normal * boxMargin;
// v3PointOnSphere = sphereRelPos - (normal * fRadius);
penetrationDepth = distance - intersectionDist;
// transform back in world space
tmp = m44T( pointOnBox);
pointOnBox = tmp;
tmp = m44T( v3PointOnSphere); v3PointOnSphere = tmp;
normal = (pointOnBox-v3PointOnSphere).normalize();
return fSep;
btVector3 tmp = m44T(pointOnBox);
pointOnBox = tmp;
// tmp = m44T(v3PointOnSphere);
// v3PointOnSphere = tmp;
tmp = m44T.getBasis() * normal;
normal = tmp;
return true;
}
btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3 const &boxHalfExtent, btVector3 const &sphereRelPos, btVector3 &closestPoint, btVector3& normal )
{
//project the center of the sphere on the closest face of the box
btScalar faceDist = boxHalfExtent.getX() - sphereRelPos.getX();
btScalar minDist = faceDist;
closestPoint.setX( boxHalfExtent.getX() );
normal.setValue(btScalar(1.0f), btScalar(0.0f), btScalar(0.0f));
faceDist = boxHalfExtent.getX() + sphereRelPos.getX();
if (faceDist < minDist)
{
minDist = faceDist;
closestPoint = sphereRelPos;
closestPoint.setX( -boxHalfExtent.getX() );
normal.setValue(btScalar(-1.0f), btScalar(0.0f), btScalar(0.0f));
}
faceDist = boxHalfExtent.getY() - sphereRelPos.getY();
if (faceDist < minDist)
{
minDist = faceDist;
closestPoint = sphereRelPos;
closestPoint.setY( boxHalfExtent.getY() );
normal.setValue(btScalar(0.0f), btScalar(1.0f), btScalar(0.0f));
}
faceDist = boxHalfExtent.getY() + sphereRelPos.getY();
if (faceDist < minDist)
{
minDist = faceDist;
closestPoint = sphereRelPos;
closestPoint.setY( -boxHalfExtent.getY() );
normal.setValue(btScalar(0.0f), btScalar(-1.0f), btScalar(0.0f));
}
faceDist = boxHalfExtent.getZ() - sphereRelPos.getZ();
if (faceDist < minDist)
{
minDist = faceDist;
closestPoint = sphereRelPos;
closestPoint.setZ( boxHalfExtent.getZ() );
normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(1.0f));
}
faceDist = boxHalfExtent.getZ() + sphereRelPos.getZ();
if (faceDist < minDist)
{
minDist = faceDist;
closestPoint = sphereRelPos;
closestPoint.setZ( -boxHalfExtent.getZ() );
normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(-1.0f));
}
return minDist;
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_BOX_COLLISION_ALGORITHM_H
#define SPHERE_BOX_COLLISION_ALGORITHM_H
#ifndef BT_SPHERE_BOX_COLLISION_ALGORITHM_H
#define BT_SPHERE_BOX_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@ -34,11 +34,11 @@ class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
public:
btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, bool isSwapped);
virtual ~btSphereBoxCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -50,26 +50,26 @@ public:
}
}
btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius );
bool getSphereDistance( const btCollisionObjectWrapper* boxObjWrap, btVector3& v3PointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& v3SphereCenter, btScalar fRadius, btScalar maxContactDistance );
btScalar getSpherePenetration( btCollisionObject* boxObj, btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax);
btScalar getSpherePenetration( btVector3 const &boxHalfExtent, btVector3 const &sphereRelPos, btVector3 &closestPoint, btVector3& normal );
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm));
if (!m_swapped)
{
return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false);
} else
{
return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true);
return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true);
}
}
};
};
#endif //SPHERE_BOX_COLLISION_ALGORITHM_H
#endif //BT_SPHERE_BOX_COLLISION_ALGORITHM_H

View file

@ -17,15 +17,16 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1)
: btActivatingCollisionAlgorithm(ci,col0,col1),
btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap)
: btActivatingCollisionAlgorithm(ci,col0Wrap,col1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf)
{
if (!m_manifoldPtr)
{
m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1);
m_manifoldPtr = m_dispatcher->getNewManifold(col0Wrap->getCollisionObject(),col1Wrap->getCollisionObject());
m_ownManifold = true;
}
}
@ -39,7 +40,7 @@ btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm()
}
}
void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btSphereSphereCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
@ -48,10 +49,10 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
resultOut->setPersistentManifold(m_manifoldPtr);
btSphereShape* sphere0 = (btSphereShape*)col0->getCollisionShape();
btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape();
btSphereShape* sphere0 = (btSphereShape*)col0Wrap->getCollisionShape();
btSphereShape* sphere1 = (btSphereShape*)col1Wrap->getCollisionShape();
btVector3 diff = col0->getWorldTransform().getOrigin()- col1->getWorldTransform().getOrigin();
btVector3 diff = col0Wrap->getWorldTransform().getOrigin()- col1Wrap->getWorldTransform().getOrigin();
btScalar len = diff.length();
btScalar radius0 = sphere0->getRadius();
btScalar radius1 = sphere1->getRadius();
@ -80,7 +81,7 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
///point on A (worldspace)
///btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;
///point on B (worldspace)
btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
btVector3 pos1 = col1Wrap->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
/// report a contact. internally this will be kept persistent, and contact reduction is done

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H
#define SPHERE_SPHERE_COLLISION_ALGORITHM_H
#ifndef BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H
#define BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@ -32,12 +32,12 @@ class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm
btPersistentManifold* m_manifoldPtr;
public:
btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap);
btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btActivatingCollisionAlgorithm(ci) {}
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -53,14 +53,14 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm));
return new(mem) btSphereSphereCollisionAlgorithm(0,ci,body0,body1);
return new(mem) btSphereSphereCollisionAlgorithm(0,ci,col0Wrap,col1Wrap);
}
};
};
#endif //SPHERE_SPHERE_COLLISION_ALGORITHM_H
#endif //BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H

View file

@ -19,17 +19,17 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "SphereTriangleDetector.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped)
: btActivatingCollisionAlgorithm(ci,col0,col1),
btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool swapped)
: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf),
m_swapped(swapped)
{
if (!m_manifoldPtr)
{
m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1);
m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
m_ownManifold = true;
}
}
@ -43,16 +43,16 @@ btSphereTriangleCollisionAlgorithm::~btSphereTriangleCollisionAlgorithm()
}
}
void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
void btSphereTriangleCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
return;
btCollisionObject* sphereObj = m_swapped? col1 : col0;
btCollisionObject* triObj = m_swapped? col0 : col1;
const btCollisionObjectWrapper* sphereObjWrap = m_swapped? col1Wrap : col0Wrap;
const btCollisionObjectWrapper* triObjWrap = m_swapped? col0Wrap : col1Wrap;
btSphereShape* sphere = (btSphereShape*)sphereObj->getCollisionShape();
btTriangleShape* triangle = (btTriangleShape*)triObj->getCollisionShape();
btSphereShape* sphere = (btSphereShape*)sphereObjWrap->getCollisionShape();
btTriangleShape* triangle = (btTriangleShape*)triObjWrap->getCollisionShape();
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->setPersistentManifold(m_manifoldPtr);
@ -60,8 +60,8 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);///@todo: tighter bounds
input.m_transformA = sphereObj->getWorldTransform();
input.m_transformB = triObj->getWorldTransform();
input.m_transformA = sphereObjWrap->getWorldTransform();
input.m_transformB = triObjWrap->getWorldTransform();
bool swapResults = m_swapped;

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#ifndef BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#define BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@ -32,12 +32,12 @@ class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm
bool m_swapped;
public:
btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped);
btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool swapped);
btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btActivatingCollisionAlgorithm(ci) {}
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@ -54,16 +54,16 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm));
return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_swapped);
}
};
};
#endif //SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#endif //BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H

View file

@ -53,7 +53,7 @@ class btUnionFindElementSortPredicate
{
public:
bool operator() ( const btElement& lhs, const btElement& rhs )
bool operator() ( const btElement& lhs, const btElement& rhs ) const
{
return lhs.m_id < rhs.m_id;
}
@ -70,7 +70,9 @@ void btUnionFind::sortIslands()
for (int i=0;i<numElements;i++)
{
m_elements[i].m_id = find(i);
#ifndef STATIC_SIMULATION_ISLAND_OPTIMIZATION
m_elements[i].m_sz = i;
#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION
}
// Sort the vector using predicate and std::sort
@ -78,4 +80,3 @@ void btUnionFind::sortIslands()
m_elements.quickSort(btUnionFindElementSortPredicate());
}

View file

@ -13,12 +13,15 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef UNION_FIND_H
#define UNION_FIND_H
#ifndef BT_UNION_FIND_H
#define BT_UNION_FIND_H
#include "LinearMath/btAlignedObjectArray.h"
#define USE_PATH_COMPRESSION 1
#define USE_PATH_COMPRESSION 1
///see for discussion of static island optimizations by Vroonsh here: http://code.google.com/p/bullet/issues/detail?id=406
#define STATIC_SIMULATION_ISLAND_OPTIMIZATION 1
struct btElement
{
@ -106,10 +109,12 @@ class btUnionFind
//not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically
#ifdef USE_PATH_COMPRESSION
//
m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id;
#endif //
const btElement* elementPtr = &m_elements[m_elements[x].m_id];
m_elements[x].m_id = elementPtr->m_id;
x = elementPtr->m_id;
#else//
x = m_elements[x].m_id;
#endif
//btAssert(x < m_N);
//btAssert(x >= 0);
@ -121,4 +126,4 @@ class btUnionFind
};
#endif //UNION_FIND_H
#endif //BT_UNION_FIND_H

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OBB_BOX_2D_SHAPE_H
#define OBB_BOX_2D_SHAPE_H
#ifndef BT_OBB_BOX_2D_SHAPE_H
#define BT_OBB_BOX_2D_SHAPE_H
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
@ -23,7 +23,7 @@ subject to the following restrictions:
#include "LinearMath/btMinMax.h"
///The btBox2dShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
class btBox2dShape: public btPolyhedralConvexShape
ATTRIBUTE_ALIGNED16(class) btBox2dShape: public btPolyhedralConvexShape
{
//btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead
@ -34,6 +34,8 @@ class btBox2dShape: public btPolyhedralConvexShape
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btVector3 getHalfExtentsWithMargin() const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
@ -83,6 +85,7 @@ public:
}
///a btBox2dShape is a flat 2D box in the X-Y plane (Z extents are zero)
btBox2dShape( const btVector3& boxHalfExtents)
: btPolyhedralConvexShape(),
m_centroid(0,0,0)
@ -97,6 +100,11 @@ public:
m_normals[2].setValue(0,1,0);
m_normals[3].setValue(-1,0,0);
btScalar minDimension = boxHalfExtents.getX();
if (minDimension>boxHalfExtents.getY())
minDimension = boxHalfExtents.getY();
setSafeMargin(minDimension);
m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
@ -358,6 +366,6 @@ public:
};
#endif //OBB_BOX_2D_SHAPE_H
#endif //BT_OBB_BOX_2D_SHAPE_H

View file

@ -14,8 +14,18 @@ subject to the following restrictions:
*/
#include "btBoxShape.h"
btBoxShape::btBoxShape( const btVector3& boxHalfExtents)
: btPolyhedralConvexShape()
{
m_shapeType = BOX_SHAPE_PROXYTYPE;
setSafeMargin(boxHalfExtents);
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
};
//{
void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OBB_BOX_MINKOWSKI_H
#define OBB_BOX_MINKOWSKI_H
#ifndef BT_OBB_BOX_MINKOWSKI_H
#define BT_OBB_BOX_MINKOWSKI_H
#include "btPolyhedralConvexShape.h"
#include "btCollisionMargin.h"
@ -23,7 +23,7 @@ subject to the following restrictions:
#include "LinearMath/btMinMax.h"
///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
class btBoxShape: public btPolyhedralConvexShape
ATTRIBUTE_ALIGNED16(class) btBoxShape: public btPolyhedralConvexShape
{
//btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead
@ -31,6 +31,8 @@ class btBoxShape: public btPolyhedralConvexShape
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btVector3 getHalfExtentsWithMargin() const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
@ -41,7 +43,7 @@ public:
const btVector3& getHalfExtentsWithoutMargin() const
{
return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
return m_implicitShapeDimensions;//scaling is included, margin is not
}
@ -80,13 +82,7 @@ public:
}
btBoxShape( const btVector3& boxHalfExtents)
: btPolyhedralConvexShape()
{
m_shapeType = BOX_SHAPE_PROXYTYPE;
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
};
btBoxShape( const btVector3& boxHalfExtents);
virtual void setMargin(btScalar collisionMargin)
{
@ -145,7 +141,7 @@ public:
virtual void getVertex(int i,btVector3& vtx) const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
btVector3 halfExtents = getHalfExtentsWithMargin();
vtx = btVector3(
halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
@ -312,6 +308,7 @@ public:
};
#endif //OBB_BOX_MINKOWSKI_H
#endif //BT_OBB_BOX_MINKOWSKI_H

View file

@ -17,12 +17,14 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
#include "LinearMath/btSerializer.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, bool useQuantizedAabbCompression, bool buildBvh)
:btTriangleMeshShape(meshInterface),
m_bvh(0),
m_triangleInfoMap(0),
m_useQuantizedAabbCompression(useQuantizedAabbCompression),
m_ownsBvh(false)
{
@ -30,22 +32,9 @@ m_ownsBvh(false)
//construct bvh from meshInterface
#ifndef DISABLE_BVH
btVector3 bvhAabbMin,bvhAabbMax;
if(meshInterface->hasPremadeAabb())
{
meshInterface->getPremadeAabb(&bvhAabbMin, &bvhAabbMax);
}
else
{
meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
}
if (buildBvh)
{
void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
m_bvh = new (mem) btOptimizedBvh();
m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
m_ownsBvh = true;
buildOptimizedBvh();
}
#endif //DISABLE_BVH
@ -55,6 +44,7 @@ m_ownsBvh(false)
btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh)
:btTriangleMeshShape(meshInterface),
m_bvh(0),
m_triangleInfoMap(0),
m_useQuantizedAabbCompression(useQuantizedAabbCompression),
m_ownsBvh(false)
{
@ -287,13 +277,13 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
nodeSubPart);
unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT||indicestype==PHY_UCHAR);
const btVector3& meshScaling = m_meshInterface->getScaling();
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:indicestype==PHY_INTEGER?gfxbase[j]:((unsigned char*)gfxbase)[j];
#ifdef DEBUG_TRIANGLE_MESH
@ -343,20 +333,25 @@ void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
{
btTriangleMeshShape::setLocalScaling(scaling);
if (m_ownsBvh)
{
m_bvh->~btOptimizedBvh();
btAlignedFree(m_bvh);
}
///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
m_bvh = new(mem) btOptimizedBvh();
//rebuild the bvh...
m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
m_ownsBvh = true;
buildOptimizedBvh();
}
}
void btBvhTriangleMeshShape::buildOptimizedBvh()
{
if (m_ownsBvh)
{
m_bvh->~btOptimizedBvh();
btAlignedFree(m_bvh);
}
///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
m_bvh = new(mem) btOptimizedBvh();
//rebuild the bvh...
m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
m_ownsBvh = true;
}
void btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling)
{
btAssert(!m_bvh);
@ -372,3 +367,100 @@ void btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVect
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
btTriangleMeshShapeData* trimeshData = (btTriangleMeshShapeData*) dataBuffer;
btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer);
m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
trimeshData->m_collisionMargin = float(m_collisionMargin);
if (m_bvh && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_BVH))
{
void* chunk = serializer->findPointer(m_bvh);
if (chunk)
{
#ifdef BT_USE_DOUBLE_PRECISION
trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)chunk;
trimeshData->m_quantizedFloatBvh = 0;
#else
trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)chunk;
trimeshData->m_quantizedDoubleBvh= 0;
#endif //BT_USE_DOUBLE_PRECISION
} else
{
#ifdef BT_USE_DOUBLE_PRECISION
trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh);
trimeshData->m_quantizedFloatBvh = 0;
#else
trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh);
trimeshData->m_quantizedDoubleBvh= 0;
#endif //BT_USE_DOUBLE_PRECISION
int sz = m_bvh->calculateSerializeBufferSizeNew();
btChunk* chunk = serializer->allocate(sz,1);
const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,m_bvh);
}
} else
{
trimeshData->m_quantizedFloatBvh = 0;
trimeshData->m_quantizedDoubleBvh = 0;
}
if (m_triangleInfoMap && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_TRIANGLEINFOMAP))
{
void* chunk = serializer->findPointer(m_triangleInfoMap);
if (chunk)
{
trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)chunk;
} else
{
trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)serializer->getUniquePointer(m_triangleInfoMap);
int sz = m_triangleInfoMap->calculateSerializeBufferSize();
btChunk* chunk = serializer->allocate(sz,1);
const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,m_triangleInfoMap);
}
} else
{
trimeshData->m_triangleInfoMap = 0;
}
return "btTriangleMeshShapeData";
}
void btBvhTriangleMeshShape::serializeSingleBvh(btSerializer* serializer) const
{
if (m_bvh)
{
int len = m_bvh->calculateSerializeBufferSizeNew(); //make sure not to use calculateSerializeBufferSize because it is used for in-place
btChunk* chunk = serializer->allocate(len,1);
const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,(void*)m_bvh);
}
}
void btBvhTriangleMeshShape::serializeSingleTriangleInfoMap(btSerializer* serializer) const
{
if (m_triangleInfoMap)
{
int len = m_triangleInfoMap->calculateSerializeBufferSize();
btChunk* chunk = serializer->allocate(len,1);
const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,(void*)m_triangleInfoMap);
}
}

View file

@ -13,13 +13,13 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BVH_TRIANGLE_MESH_SHAPE_H
#define BVH_TRIANGLE_MESH_SHAPE_H
#ifndef BT_BVH_TRIANGLE_MESH_SHAPE_H
#define BT_BVH_TRIANGLE_MESH_SHAPE_H
#include "btTriangleMeshShape.h"
#include "btOptimizedBvh.h"
#include "LinearMath/btAlignedAllocator.h"
#include "btTriangleInfoMap.h"
///The btBvhTriangleMeshShape is a static-triangle mesh shape with several optimizations, such as bounding volume hierarchy and cache friendly traversal for PlayStation 3 Cell SPU. It is recommended to enable useQuantizedAabbCompression for better memory usage.
///It takes a triangle mesh as input, for example a btTriangleMesh or btTriangleIndexVertexArray. The btBvhTriangleMeshShape class allows for triangle mesh deformations by a refit or partialRefit method.
@ -29,6 +29,8 @@ ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape
{
btOptimizedBvh* m_bvh;
btTriangleInfoMap* m_triangleInfoMap;
bool m_useQuantizedAabbCompression;
bool m_ownsBvh;
bool m_pad[11];////need padding due to alignment
@ -37,7 +39,7 @@ public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btBvhTriangleMeshShape() : btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;};
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true);
///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
@ -73,14 +75,65 @@ public:
return m_bvh;
}
void setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& localScaling=btVector3(1,1,1));
void buildOptimizedBvh();
bool usesQuantizedAabbCompression() const
{
return m_useQuantizedAabbCompression;
}
}
;
#endif //BVH_TRIANGLE_MESH_SHAPE_H
void setTriangleInfoMap(btTriangleInfoMap* triangleInfoMap)
{
m_triangleInfoMap = triangleInfoMap;
}
const btTriangleInfoMap* getTriangleInfoMap() const
{
return m_triangleInfoMap;
}
btTriangleInfoMap* getTriangleInfoMap()
{
return m_triangleInfoMap;
}
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
virtual void serializeSingleBvh(btSerializer* serializer) const;
virtual void serializeSingleTriangleInfoMap(btSerializer* serializer) const;
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btTriangleMeshShapeData
{
btCollisionShapeData m_collisionShapeData;
btStridingMeshInterfaceData m_meshInterface;
btQuantizedBvhFloatData *m_quantizedFloatBvh;
btQuantizedBvhDoubleData *m_quantizedDoubleBvh;
btTriangleInfoMapData *m_triangleInfoMap;
float m_collisionMargin;
char m_pad3[4];
};
SIMD_FORCE_INLINE int btBvhTriangleMeshShape::calculateSerializeBufferSize() const
{
return sizeof(btTriangleMeshShapeData);
}
#endif //BT_BVH_TRIANGLE_MESH_SHAPE_H

View file

@ -55,7 +55,7 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter
btVector3 pos(0,0,0);
pos[getUpAxis()] = getHalfHeight();
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
vtx = pos +vec*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
@ -67,7 +67,7 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter
btVector3 pos(0,0,0);
pos[getUpAxis()] = -getHalfHeight();
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
vtx = pos +vec*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
@ -96,7 +96,7 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter
{
btVector3 pos(0,0,0);
pos[getUpAxis()] = getHalfHeight();
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
vtx = pos +vec*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
@ -107,7 +107,7 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter
{
btVector3 pos(0,0,0);
pos[getUpAxis()] = -getHalfHeight();
vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
vtx = pos +vec*(radius) - vec * getMargin();
newDot = vec.dot(vtx);
if (newDot > maxDot)
{

View file

@ -23,7 +23,7 @@ subject to the following restrictions:
///The btCapsuleShape represents a capsule around the Y axis, there is also the btCapsuleShapeX aligned around the X axis and btCapsuleShapeZ around the Z axis.
///The total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
///The btCapsuleShape is a convex hull of two spheres. The btMultiSphereShape is a more general collision shape that takes the convex hull of multiple sphere, so it can also represent a capsule when just using two spheres.
class btCapsuleShape : public btConvexInternalShape
ATTRIBUTE_ALIGNED16(class) btCapsuleShape : public btConvexInternalShape
{
protected:
int m_upAxis;
@ -33,6 +33,9 @@ protected:
btCapsuleShape() : btConvexInternalShape() {m_shapeType = CAPSULE_SHAPE_PROXYTYPE;};
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btCapsuleShape(btScalar radius,btScalar height);
///CollisionShape Interface
@ -43,6 +46,18 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
virtual void setMargin(btScalar collisionMargin)
{
//correct the m_implicitShapeDimensions for the margin
btVector3 oldMargin(getMargin(),getMargin(),getMargin());
btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
btConvexInternalShape::setMargin(collisionMargin);
btVector3 newMargin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
}
virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
{
btVector3 halfExtents(getRadius(),getRadius(),getRadius());
@ -50,8 +65,8 @@ public:
halfExtents += btVector3(getMargin(),getMargin(),getMargin());
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
aabbMin = center - extent;
aabbMax = center + extent;
}
@ -88,6 +103,21 @@ public:
m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
}
virtual btVector3 getAnisotropicRollingFrictionDirection() const
{
btVector3 aniDir(0,0,0);
aniDir[getUpAxis()]=1;
return aniDir;
}
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
};
///btCapsuleShapeX represents a capsule around the Z axis
@ -124,6 +154,31 @@ public:
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btCapsuleShapeData
{
btConvexInternalShapeData m_convexInternalShapeData;
int m_upAxis;
char m_padding[4];
};
SIMD_FORCE_INLINE int btCapsuleShape::calculateSerializeBufferSize() const
{
return sizeof(btCapsuleShapeData);
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE const char* btCapsuleShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
btCapsuleShapeData* shapeData = (btCapsuleShapeData*) dataBuffer;
btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer);
shapeData->m_upAxis = m_upAxis;
return "btCapsuleShapeData";
}
#endif //BT_CAPSULE_SHAPE_H

View file

@ -13,14 +13,15 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_MARGIN_H
#define COLLISION_MARGIN_H
//used by Gjk and some other algorithms
#ifndef BT_COLLISION_MARGIN_H
#define BT_COLLISION_MARGIN_H
///The CONVEX_DISTANCE_MARGIN is a default collision margin for convex collision shapes derived from btConvexInternalShape.
///This collision margin is used by Gjk and some other algorithms
///Note that when creating small objects, you need to make sure to set a smaller collision margin, using the 'setMargin' API
#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01)
#endif //COLLISION_MARGIN_H
#endif //BT_COLLISION_MARGIN_H

View file

@ -13,10 +13,7 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
btScalar gContactThresholdFactor=btScalar(0.02);
#include "LinearMath/btSerializer.h"
/*
Make sure this dummy function never changes so that it
@ -45,10 +42,11 @@ void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) con
}
btScalar btCollisionShape::getContactBreakingThreshold() const
btScalar btCollisionShape::getContactBreakingThreshold(btScalar defaultContactThreshold) const
{
return getAngularMotionDisc() * gContactThresholdFactor;
return getAngularMotionDisc() * defaultContactThreshold;
}
btScalar btCollisionShape::getAngularMotionDisc() const
{
///@todo cache this value, to improve performance
@ -96,3 +94,26 @@ void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const b
temporalAabbMin -= angularMotion3d;
temporalAabbMax += angularMotion3d;
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btCollisionShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
btCollisionShapeData* shapeData = (btCollisionShapeData*) dataBuffer;
char* name = (char*) serializer->findNameForPointer(this);
shapeData->m_name = (char*)serializer->getUniquePointer(name);
if (shapeData->m_name)
{
serializer->serializeName(name);
}
shapeData->m_shapeType = m_shapeType;
//shapeData->m_padding//??
return "btCollisionShapeData";
}
void btCollisionShape::serializeSingleShape(btSerializer* serializer) const
{
int len = calculateSerializeBufferSize();
btChunk* chunk = serializer->allocate(len,1);
const char* structType = serialize(chunk->m_oldPtr, serializer);
serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,(void*)this);
}

View file

@ -13,16 +13,18 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COLLISION_SHAPE_H
#define COLLISION_SHAPE_H
#ifndef BT_COLLISION_SHAPE_H
#define BT_COLLISION_SHAPE_H
#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btMatrix3x3.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
class btSerializer;
///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects.
class btCollisionShape
ATTRIBUTE_ALIGNED16(class) btCollisionShape
{
protected:
int m_shapeType;
@ -30,6 +32,8 @@ protected:
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0)
{
}
@ -46,14 +50,14 @@ public:
///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations.
virtual btScalar getAngularMotionDisc() const;
virtual btScalar getContactBreakingThreshold() const;
virtual btScalar getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const;
///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) const;
#ifndef __SPU__
SIMD_FORCE_INLINE bool isPolyhedral() const
{
@ -69,6 +73,10 @@ public:
{
return btBroadphaseProxy::isConvex(getShapeType());
}
SIMD_FORCE_INLINE bool isNonMoving() const
{
return btBroadphaseProxy::isNonMoving(getShapeType());
}
SIMD_FORCE_INLINE bool isConcave() const
{
return btBroadphaseProxy::isConcave(getShapeType());
@ -78,13 +86,18 @@ public:
return btBroadphaseProxy::isCompound(getShapeType());
}
SIMD_FORCE_INLINE bool isSoftBody() const
{
return btBroadphaseProxy::isSoftBody(getShapeType());
}
///isInfinite is used to catch simulation error (aabb check)
SIMD_FORCE_INLINE bool isInfinite() const
{
return btBroadphaseProxy::isInfinite(getShapeType());
}
#ifndef __SPU__
virtual void setLocalScaling(const btVector3& scaling) =0;
virtual const btVector3& getLocalScaling() const =0;
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0;
@ -96,6 +109,13 @@ public:
int getShapeType() const { return m_shapeType; }
///the getAnisotropicRollingFrictionDirection can be used in combination with setAnisotropicFriction
///See Bullet/Demos/RollingFrictionDemo for an example
virtual btVector3 getAnisotropicRollingFrictionDirection() const
{
return btVector3(1,1,1);
}
virtual void setMargin(btScalar margin) = 0;
virtual btScalar getMargin() const = 0;
@ -111,7 +131,29 @@ public:
return m_userPointer;
}
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
virtual void serializeSingleShape(btSerializer* serializer) const;
};
#endif //COLLISION_SHAPE_H
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btCollisionShapeData
{
char *m_name;
int m_shapeType;
char m_padding[4];
};
SIMD_FORCE_INLINE int btCollisionShape::calculateSerializeBufferSize() const
{
return sizeof(btCollisionShapeData);
}
#endif //BT_COLLISION_SHAPE_H

View file

@ -16,6 +16,7 @@ subject to the following restrictions:
#include "btCompoundShape.h"
#include "btCollisionShape.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
#include "LinearMath/btSerializer.h"
btCompoundShape::btCompoundShape(bool enableDynamicAabbTree)
: m_localAabbMin(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)),
@ -51,6 +52,7 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
//m_childTransforms.push_back(localTransform);
//m_childShapes.push_back(shape);
btCompoundShapeChild child;
child.m_node = 0;
child.m_transform = localTransform;
child.m_childShape = shape;
child.m_childShapeType = shape->getShapeType();
@ -83,7 +85,7 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
}
void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform)
void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform,bool shouldRecalculateLocalAabb)
{
m_children[childIndex].m_transform = newChildTransform;
@ -97,7 +99,10 @@ void btCompoundShape::updateChildTransform(int childIndex, const btTransform& ne
m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds);
}
recalculateLocalAabb();
if (shouldRecalculateLocalAabb)
{
recalculateLocalAabb();
}
}
void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
@ -109,6 +114,8 @@ void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
m_dynamicAabbTree->remove(m_children[childShapeIndex].m_node);
}
m_children.swap(childShapeIndex,m_children.size()-1);
if (m_dynamicAabbTree)
m_children[childShapeIndex].m_node->dataAsInt = childShapeIndex;
m_children.pop_back();
}
@ -175,9 +182,7 @@ void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVect
btVector3 center = trans(localCenter);
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
abs_b[1].dot(localHalfExtents),
abs_b[2].dot(localHalfExtents));
btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
aabbMin = center-extent;
aabbMax = center+extent;
@ -216,9 +221,13 @@ void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransf
for (k = 0; k < n; k++)
{
btAssert(masses[k]>0);
center += m_children[k].m_transform.getOrigin() * masses[k];
totalMass += masses[k];
}
btAssert(totalMass>0);
center /= totalMass;
principal.setOrigin(center);
@ -264,3 +273,82 @@ void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransf
void btCompoundShape::setLocalScaling(const btVector3& scaling)
{
for(int i = 0; i < m_children.size(); i++)
{
btTransform childTrans = getChildTransform(i);
btVector3 childScale = m_children[i].m_childShape->getLocalScaling();
// childScale = childScale * (childTrans.getBasis() * scaling);
childScale = childScale * scaling / m_localScaling;
m_children[i].m_childShape->setLocalScaling(childScale);
childTrans.setOrigin((childTrans.getOrigin())*scaling);
updateChildTransform(i, childTrans,false);
}
m_localScaling = scaling;
recalculateLocalAabb();
}
void btCompoundShape::createAabbTreeFromChildren()
{
if ( !m_dynamicAabbTree )
{
void* mem = btAlignedAlloc(sizeof(btDbvt),16);
m_dynamicAabbTree = new(mem) btDbvt();
btAssert(mem==m_dynamicAabbTree);
for ( int index = 0; index < m_children.size(); index++ )
{
btCompoundShapeChild &child = m_children[index];
//extend the local aabbMin/aabbMax
btVector3 localAabbMin,localAabbMax;
child.m_childShape->getAabb(child.m_transform,localAabbMin,localAabbMax);
const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
}
}
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btCompoundShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
btCompoundShapeData* shapeData = (btCompoundShapeData*) dataBuffer;
btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer);
shapeData->m_collisionMargin = float(m_collisionMargin);
shapeData->m_numChildShapes = m_children.size();
shapeData->m_childShapePtr = 0;
if (shapeData->m_numChildShapes)
{
btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData),shapeData->m_numChildShapes);
btCompoundShapeChildData* memPtr = (btCompoundShapeChildData*)chunk->m_oldPtr;
shapeData->m_childShapePtr = (btCompoundShapeChildData*)serializer->getUniquePointer(memPtr);
for (int i=0;i<shapeData->m_numChildShapes;i++,memPtr++)
{
memPtr->m_childMargin = float(m_children[i].m_childMargin);
memPtr->m_childShape = (btCollisionShapeData*)serializer->getUniquePointer(m_children[i].m_childShape);
//don't serialize shapes that already have been serialized
if (!serializer->findPointer(m_children[i].m_childShape))
{
btChunk* chunk = serializer->allocate(m_children[i].m_childShape->calculateSerializeBufferSize(),1);
const char* structType = m_children[i].m_childShape->serialize(chunk->m_oldPtr,serializer);
serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,m_children[i].m_childShape);
}
memPtr->m_childShapeType = m_children[i].m_childShapeType;
m_children[i].m_transform.serializeFloat(memPtr->m_transform);
}
serializer->finalizeChunk(chunk,"btCompoundShapeChildData",BT_ARRAY_CODE,chunk->m_oldPtr);
}
return "btCompoundShapeData";
}

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef COMPOUND_SHAPE_H
#define COMPOUND_SHAPE_H
#ifndef BT_COMPOUND_SHAPE_H
#define BT_COMPOUND_SHAPE_H
#include "btCollisionShape.h"
@ -62,6 +62,11 @@ ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape
///increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be updated
int m_updateRevision;
btScalar m_collisionMargin;
protected:
btVector3 m_localScaling;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
@ -101,7 +106,7 @@ public:
}
///set a new transform for a child, and update internal data structures (local aabb and dynamic tree)
void updateChildTransform(int childIndex, const btTransform& newChildTransform);
void updateChildTransform(int childIndex, const btTransform& newChildTransform, bool shouldRecalculateLocalAabb = true);
btCompoundShapeChild* getChildList()
@ -116,10 +121,8 @@ public:
Use this yourself if you modify the children or their transforms. */
virtual void recalculateLocalAabb();
virtual void setLocalScaling(const btVector3& scaling)
{
m_localScaling = scaling;
}
virtual void setLocalScaling(const btVector3& scaling);
virtual const btVector3& getLocalScaling() const
{
return m_localScaling;
@ -140,13 +143,17 @@ public:
return "Compound";
}
//this is optional, but should make collision queries faster, by culling non-overlapping nodes
void createAabbTreeFromChildren();
btDbvt* getDynamicAabbTree()
const btDbvt* getDynamicAabbTree() const
{
return m_dynamicAabbTree;
}
btDbvt* getDynamicAabbTree()
{
return m_dynamicAabbTree;
}
void createAabbTreeFromChildren();
///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia
///and the center of mass to the current coordinate system. "masses" points to an array of masses of the children. The resulting transform
@ -160,13 +167,46 @@ public:
return m_updateRevision;
}
private:
btScalar m_collisionMargin;
protected:
btVector3 m_localScaling;
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btCompoundShapeChildData
{
btTransformFloatData m_transform;
btCollisionShapeData *m_childShape;
int m_childShapeType;
float m_childMargin;
};
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct btCompoundShapeData
{
btCollisionShapeData m_collisionShapeData;
btCompoundShapeChildData *m_childShapePtr;
int m_numChildShapes;
float m_collisionMargin;
};
SIMD_FORCE_INLINE int btCompoundShape::calculateSerializeBufferSize() const
{
return sizeof(btCompoundShapeData);
}
#endif //COMPOUND_SHAPE_H
#endif //BT_COMPOUND_SHAPE_H

View file

@ -13,8 +13,8 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONCAVE_SHAPE_H
#define CONCAVE_SHAPE_H
#ifndef BT_CONCAVE_SHAPE_H
#define BT_CONCAVE_SHAPE_H
#include "btCollisionShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
@ -33,12 +33,14 @@ typedef enum PHY_ScalarType {
///The btConcaveShape class provides an interface for non-moving (static) concave shapes.
///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape.
class btConcaveShape : public btCollisionShape
ATTRIBUTE_ALIGNED16(class) btConcaveShape : public btCollisionShape
{
protected:
btScalar m_collisionMargin;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btConcaveShape();
virtual ~btConcaveShape();
@ -57,4 +59,4 @@ public:
};
#endif //CONCAVE_SHAPE_H
#endif //BT_CONCAVE_SHAPE_H

View file

@ -131,3 +131,13 @@ btVector3 btConeShape::localGetSupportingVertex(const btVector3& vec) const
}
void btConeShape::setLocalScaling(const btVector3& scaling)
{
int axis = m_coneIndices[1];
int r1 = m_coneIndices[0];
int r2 = m_coneIndices[2];
m_height *= scaling[axis] / m_localScaling[axis];
m_radius *= (scaling[r1] / m_localScaling[r1] + scaling[r2] / m_localScaling[r2]) / 2;
m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height));
btConvexInternalShape::setLocalScaling(scaling);
}

View file

@ -13,14 +13,14 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CONE_MINKOWSKI_H
#define CONE_MINKOWSKI_H
#ifndef BT_CONE_MINKOWSKI_H
#define BT_CONE_MINKOWSKI_H
#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
///The btConeShape implements a cone shape primitive, centered around the origin and aligned with the Y axis. The btConeShapeX is aligned around the X axis and btConeShapeZ around the Z axis.
class btConeShape : public btConvexInternalShape
ATTRIBUTE_ALIGNED16(class) btConeShape : public btConvexInternalShape
{
@ -32,6 +32,8 @@ class btConeShape : public btConvexInternalShape
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btConeShape (btScalar radius,btScalar height);
virtual btVector3 localGetSupportingVertex(const btVector3& vec) const;
@ -81,6 +83,14 @@ public:
{
return m_coneIndices[1];
}
virtual btVector3 getAnisotropicRollingFrictionDirection() const
{
return btVector3 (0,1,0);
}
virtual void setLocalScaling(const btVector3& scaling);
};
///btConeShape implements a Cone shape, around the X axis
@ -88,6 +98,12 @@ class btConeShapeX : public btConeShape
{
public:
btConeShapeX(btScalar radius,btScalar height);
virtual btVector3 getAnisotropicRollingFrictionDirection() const
{
return btVector3 (1,0,0);
}
};
///btConeShapeZ implements a Cone shape, around the Z axis
@ -95,6 +111,12 @@ class btConeShapeZ : public btConeShape
{
public:
btConeShapeZ(btScalar radius,btScalar height);
};
#endif //CONE_MINKOWSKI_H
virtual btVector3 getAnisotropicRollingFrictionDirection() const
{
return btVector3 (0,0,1);
}
};
#endif //BT_CONE_MINKOWSKI_H

View file

@ -19,14 +19,16 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
///The btConvex2dShape allows to use arbitrary convex shapes are 2d convex shapes, with the Z component assumed to be 0.
///The btConvex2dShape allows to use arbitrary convex shapes as 2d convex shapes, with the Z component assumed to be 0.
///For 2d boxes, the btBox2dShape is recommended.
class btConvex2dShape : public btConvexShape
ATTRIBUTE_ALIGNED16(class) btConvex2dShape : public btConvexShape
{
btConvexShape* m_childConvexShape;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btConvex2dShape( btConvexShape* convexChildShape);
virtual ~btConvex2dShape();

View file

@ -17,7 +17,7 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
#include "LinearMath/btQuaternion.h"
#include "LinearMath/btSerializer.h"
btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexAabbCachingShape ()
{
@ -52,35 +52,20 @@ void btConvexHullShape::addPoint(const btVector3& point)
}
btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
btScalar maxDot = btScalar(-BT_LARGE_FLOAT);
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;
}
// Here we take advantage of dot(a, b*c) = dot(a*b, c). Note: This is true mathematically, but not numerically.
if( 0 < m_unscaledPoints.size() )
{
btVector3 scaled = vec * m_localScaling;
int index = (int) scaled.maxDot( &m_unscaledPoints[0], m_unscaledPoints.size(), maxDot); // FIXME: may violate encapsulation of m_unscaledPoints
return m_unscaledPoints[index] * m_localScaling;
}
for (int i=0;i<m_unscaledPoints.size();i++)
{
btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
newDot = vec.dot(vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supVec = vtx;
}
}
return supVec;
return supVec;
}
void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
@ -93,23 +78,19 @@ void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const
supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
}
}
for (int i=0;i<m_unscaledPoints.size();i++)
{
btVector3 vtx = getScaledPoint(i);
for (int j=0;j<numVectors;j++)
{
const btVector3& vec = vectors[j];
newDot = vec.dot(vtx);
if (newDot > supportVerticesOut[j][3])
{
//WARNING: don't swap next lines, the w component would get overwritten!
supportVerticesOut[j] = vtx;
supportVerticesOut[j][3] = newDot;
}
}
}
for (int j=0;j<numVectors;j++)
{
btVector3 vec = vectors[j] * m_localScaling; // dot(a*b,c) = dot(a,b*c)
if( 0 < m_unscaledPoints.size() )
{
int i = (int) vec.maxDot( &m_unscaledPoints[0], m_unscaledPoints.size(), newDot);
supportVerticesOut[j] = getScaledPoint(i);
supportVerticesOut[j][3] = newDot;
}
else
supportVerticesOut[j][3] = -BT_LARGE_FLOAT;
}
@ -186,3 +167,79 @@ bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const
return false;
}
///fills the dataBuffer and returns the struct name (and 0 on failure)
const char* btConvexHullShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
//int szc = sizeof(btConvexHullShapeData);
btConvexHullShapeData* shapeData = (btConvexHullShapeData*) dataBuffer;
btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer);
int numElem = m_unscaledPoints.size();
shapeData->m_numUnscaledPoints = numElem;
#ifdef BT_USE_DOUBLE_PRECISION
shapeData->m_unscaledPointsFloatPtr = 0;
shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]): 0;
#else
shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]): 0;
shapeData->m_unscaledPointsDoublePtr = 0;
#endif
if (numElem)
{
int sz = sizeof(btVector3Data);
// int sz2 = sizeof(btVector3DoubleData);
// int sz3 = sizeof(btVector3FloatData);
btChunk* chunk = serializer->allocate(sz,numElem);
btVector3Data* memPtr = (btVector3Data*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
m_unscaledPoints[i].serialize(*memPtr);
}
serializer->finalizeChunk(chunk,btVector3DataName,BT_ARRAY_CODE,(void*)&m_unscaledPoints[0]);
}
return "btConvexHullShapeData";
}
void btConvexHullShape::project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const
{
#if 1
minProj = FLT_MAX;
maxProj = -FLT_MAX;
int numVerts = m_unscaledPoints.size();
for(int i=0;i<numVerts;i++)
{
btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
btVector3 pt = trans * vtx;
btScalar dp = pt.dot(dir);
if(dp < minProj)
{
minProj = dp;
witnesPtMin = pt;
}
if(dp > maxProj)
{
maxProj = dp;
witnesPtMax=pt;
}
}
#else
btVector3 localAxis = dir*trans.getBasis();
witnesPtMin = trans(localGetSupportingVertex(localAxis));
witnesPtMax = trans(localGetSupportingVertex(-localAxis));
minProj = witnesPtMin.dot(dir);
maxProj = witnesPtMax.dot(dir);
#endif
if(minProj>maxProj)
{
btSwap(minProj,maxProj);
btSwap(witnesPtMin,witnesPtMax);
}
}

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