Merge branch 'GarageGames/master' into ueberengine-dev

Conflicts:
	Engine/source/windowManager/sdl/sdlWindowMgr.cpp
	Tools/CMake/torque3d.cmake

3.10 final update
This commit is contained in:
Duion 2017-03-23 20:36:21 +01:00
commit aff033dd0d
1003 changed files with 53039 additions and 82707 deletions

View file

@ -0,0 +1,27 @@
language: cpp
os:
- linux
- osx
compiler:
- gcc
- clang
addons:
apt:
packages:
- python3
script:
- echo "CXX="$CXX
- echo "CC="$CC
- cmake . -DBUILD_PYBULLET=ON -G"Unix Makefiles" #-DCMAKE_CXX_FLAGS=-Werror
- make -j8
- ctest -j8 --output-on-failure
# Build again with double precision
- cmake . -G "Unix Makefiles" -DUSE_DOUBLE_PRECISION=ON #-DCMAKE_CXX_FLAGS=-Werror
- make -j8
- ctest -j8 --output-on-failure
# Build again with shared libraries
- cmake . -G "Unix Makefiles" -DBUILD_SHARED_LIBS=ON
- make -j8
- ctest -j8 --output-on-failure
- sudo make install

View file

@ -1,22 +0,0 @@
Bullet Physics Library is an open source project with help from the community at the Physics Forum
See the forum at http://bulletphysics.com
The project was started by Erwin Coumans
Following people contributed to Bullet
(random order, please let us know on the forum if your name should be in this list)
Gino van den Bergen: LinearMath classes
Christer Ericson: parts of the voronoi simplex solver
Simon Hobbs: 3d axis sweep and prune, Extras/SATCollision, separating axis theorem + SIMD code
Dirk Gregorius: generic D6 constraint
Erin Catto: accumulated impulse in sequential impulse
Nathanael Presson: EPA penetration depth calculation
Francisco Leon: GIMPACT Concave Concave collision
Joerg Henrichs: make buildsystem (work in progress)
Eric Sunshine: jam + msvcgen buildsystem
Steve Baker: GPU physics and general implementation improvements
Jay Lee: Double precision support
KleMiX, aka Vsevolod Klementjev, managed version, rewritten in C# for XNA
Erwin Coumans: most other source code

View file

@ -0,0 +1,40 @@
Bullet Physics is created by Erwin Coumans with contributions from the following authors / copyright holders:
AMD
Apple
Steve Baker
Gino van den Bergen
Nicola Candussi
Erin Catto
Lawrence Chai
Erwin Coumans
Christer Ericson
Disney Animation
Google
Dirk Gregorius
Marcus Hennix
MBSim Development Team
Takahiro Harada
Simon Hobbs
John Hsu
Ole Kniemeyer
Jay Lee
Francisco Leon
Vsevolod Klementjev
Phil Knight
John McCutchan
Steven Peters
Roman Ponomarev
Nathanael Presson
Gabor PUHR
Arthur Shek
Russel Smith
Sony
Jakub Stephien
Marten Svanfeldt
Pierre Terdiman
Steven Thompson
Tamas Umenhoffer
Yunfei Bai
If your name is missing, please send an email to erwin.coumans@gmail.com or file an issue at http://github.com/bulletphysics/bullet3

View file

@ -0,0 +1,25 @@
# -*- cmake -*-
#
# BulletConfig.cmake(.in)
#
# Use the following variables to compile and link against Bullet:
# BULLET_FOUND - True if Bullet was found on your system
# BULLET_USE_FILE - The file making Bullet usable
# BULLET_DEFINITIONS - Definitions needed to build with Bullet
# BULLET_INCLUDE_DIR - Directory where Bullet-C-Api.h can be found
# BULLET_INCLUDE_DIRS - List of directories of Bullet and it's dependencies
# BULLET_LIBRARIES - List of libraries to link against Bullet library
# BULLET_LIBRARY_DIRS - List of directories containing Bullet' libraries
# BULLET_ROOT_DIR - The base directory of Bullet
# BULLET_VERSION_STRING - A human-readable string containing the version
set ( BULLET_FOUND 1 )
set ( BULLET_USE_FILE "@BULLET_USE_FILE@" )
set ( BULLET_DEFINITIONS "@BULLET_DEFINITIONS@" )
set ( BULLET_INCLUDE_DIR "@INCLUDE_INSTALL_DIR@" )
set ( BULLET_INCLUDE_DIRS "@INCLUDE_INSTALL_DIR@" )
set ( BULLET_LIBRARIES "@BULLET_LIBRARIES@" )
set ( BULLET_LIBRARY_DIRS "@LIB_DESTINATION@" )
set ( BULLET_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" )
set ( BULLET_VERSION_STRING "@BULLET_VERSION@" )

View file

@ -1,18 +0,0 @@
/*
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.
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.
*/
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

View file

@ -5,10 +5,14 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
SET(MSVC_INCREMENTAL_DEFAULT ON)
PROJECT(BULLET_PHYSICS)
SET(BULLET_VERSION 2.82)
SET(BULLET_VERSION 2.85)
IF(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
if(POLICY CMP0042)
# Enable MACOSX_RPATH by default.
cmake_policy(SET CMP0042 NEW)
endif(POLICY CMP0042)
ENDIF(COMMAND cmake_policy)
@ -22,158 +26,19 @@ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
OPTION(USE_DOUBLE_PRECISION "Use double precision" OFF)
OPTION(USE_GRAPHICAL_BENCHMARK "Use Graphical Benchmark" ON)
OPTION(BUILD_SHARED_LIBS "Use shared libraries" OFF)
OPTION(USE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD "Use btSoftMultiBodyDynamicsWorld" OFF)
OPTION(BULLET2_USE_THREAD_LOCKS "Build Bullet 2 libraries with mutex locking around certain operations" OFF)
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)
#statically linking VC++ isn't supported for WindowsPhone/WindowsStore
IF (CMAKE_SYSTEM_NAME STREQUAL WindowsPhone OR CMAKE_SYSTEM_NAME STREQUAL WindowsStore)
OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" ON)
ELSE ()
OPTION(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC Runtime Library DLL (/MD or /MDd)" OFF)
ENDIF (CMAKE_SYSTEM_NAME STREQUAL WindowsPhone OR CMAKE_SYSTEM_NAME STREQUAL WindowsStore)
#SET(CMAKE_EXE_LINKER_FLAGS_INIT "/STACK:10000000 /INCREMENTAL:NO")
#SET(CMAKE_EXE_LINKER_FLAGS "/STACK:10000000 /INCREMENTAL:NO")
@ -190,13 +55,15 @@ IF(MSVC)
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" 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})
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}" )
@ -204,7 +71,7 @@ IF(MSVC)
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)
FOREACH(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO )
IF(${flag_var} MATCHES "/MD")
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
ENDIF(${flag_var} MATCHES "/MD")
@ -219,13 +86,15 @@ IF(MSVC)
ELSE()
OPTION(USE_MSVC_SSE "Use MSVC /arch:sse option" ON)
IF (USE_MSVC_SSE)
ADD_DEFINITIONS(/arch:SSE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE")
ENDIF()
ENDIF()
OPTION(USE_MSVC_FAST_FLOATINGPOINT "Use MSVC /fp:fast option" ON)
IF (USE_MSVC_FAST_FLOATINGPOINT)
ADD_DEFINITIONS(/fp:fast)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast")
ENDIF()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4244 /wd4267")
ENDIF(MSVC)
@ -265,7 +134,7 @@ ENDIF(INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES)
ENDIF (WIN32)
OPTION(BUILD_CPU_DEMOS "Build original Bullet CPU demos" ON)
OPTION(BUILD_CPU_DEMOS "Build original Bullet CPU examples" ON)
@ -279,20 +148,30 @@ ADD_DEFINITIONS( -DBT_USE_DOUBLE_PRECISION)
SET( BULLET_DOUBLE_DEF "-DBT_USE_DOUBLE_PRECISION")
ENDIF (USE_DOUBLE_PRECISION)
IF (USE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD)
ADD_DEFINITIONS(-DUSE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD)
ENDIF (USE_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD)
IF(USE_GRAPHICAL_BENCHMARK)
ADD_DEFINITIONS( -DUSE_GRAPHICAL_BENCHMARK)
ENDIF (USE_GRAPHICAL_BENCHMARK)
IF(BULLET2_USE_THREAD_LOCKS)
ADD_DEFINITIONS( -DBT_THREADSAFE=1 )
IF (NOT MSVC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
ENDIF (NOT MSVC)
ENDIF (BULLET2_USE_THREAD_LOCKS)
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 )
string (REPLACE "/D_WINDOWS" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
remove_definitions(-D_WINDOWS )
ENDIF()
@ -320,60 +199,89 @@ ELSE (OPENGL_FOUND)
SET(OPENGL_glu_LIBRARY glu32)
ENDIF (OPENGL_FOUND)
# ADD_DEFINITIONS(-DBT_USE_FREEGLUT)
FIND_PACKAGE(GLU)
#FIND_PACKAGE(GLU)
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)
IF (APPLE)
FIND_LIBRARY(COCOA_LIBRARY Cocoa)
ENDIF()
OPTION(BUILD_BULLET3 "Set when you want to build Bullet 3" ON)
OPTION(BUILD_PYBULLET "Set when you want to build pybullet (experimental Python bindings for Bullet)" OFF)
IF(BUILD_PYBULLET)
FIND_PACKAGE(PythonLibs)
OPTION(BUILD_PYBULLET_NUMPY "Set when you want to build pybullet with NumPy support" OFF)
OPTION(BUILD_PYBULLET_ENET "Set when you want to build pybullet with enet UDP networking support" ON)
IF(BUILD_PYBULLET_NUMPY)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_LIST_DIR}/build3/cmake)
#include(FindNumPy)
FIND_PACKAGE(NumPy)
if (PYTHON_NUMPY_FOUND)
message("NumPy found")
add_definitions(-DPYBULLET_USE_NUMPY)
else()
message("NumPy not found")
endif()
ENDIF()
OPTION(BUILD_PYBULLET "Set when you want to build pybullet (experimental Python bindings for Bullet)" OFF)
IF(WIN32)
SET(BUILD_SHARED_LIBS OFF CACHE BOOL "Shared Libs" FORCE)
ELSE(WIN32)
SET(BUILD_SHARED_LIBS ON CACHE BOOL "Shared Libs" FORCE)
ENDIF(WIN32)
ENDIF(BUILD_PYBULLET)
IF(BUILD_BULLET3)
IF(APPLE)
MESSAGE("Mac OSX Version is ${_CURRENT_OSX_VERSION}")
IF(_CURRENT_OSX_VERSION VERSION_LESS 10.9)
MESSAGE("Mac OSX below 10.9 has no OpenGL 3 support so please disable the BUILD_OPENGL3_DEMOS option")
#unset(BUILD_OPENGL3_DEMOS CACHE)
OPTION(BUILD_OPENGL3_DEMOS "Set when you want to build the OpenGL3+ demos" OFF)
ELSE()
MESSAGE("GLUT NOT FOUND")
ENDIF (MSVC)
ENDIF (GLUT_FOUND)
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)
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)
OPTION(BUILD_OPENGL3_DEMOS "Set when you want to build the OpenGL3+ demos" ON)
ENDIF()
ELSE()
OPTION(BUILD_OPENGL3_DEMOS "Set when you want to build Bullet 3 OpenGL3+ demos" ON)
ENDIF()
ENDIF(MSVC)
ELSE(BUILD_BULLET3)
unset(BUILD_OPENGL3_DEMOS CACHE)
OPTION(BUILD_OPENGL3_DEMOS "Set when you want to build Bullet 3 OpenGL3+ demos" OFF)
ENDIF(BUILD_BULLET3)
IF(BUILD_OPENGL3_DEMOS)
IF(EXISTS ${BULLET_PHYSICS_SOURCE_DIR}/Demos3 AND IS_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR}/Demos3)
SUBDIRS(Demos3)
ENDIF()
ELSE()
ADD_DEFINITIONS(-DNO_OPENGL3)
ENDIF(BUILD_OPENGL3_DEMOS)
OPTION(BUILD_BULLET2_DEMOS "Set when you want to build the Bullet 2 demos" ON)
IF(BUILD_BULLET2_DEMOS)
IF(EXISTS ${BULLET_PHYSICS_SOURCE_DIR}/examples AND IS_DIRECTORY ${BULLET_PHYSICS_SOURCE_DIR}/examples)
SUBDIRS(examples)
ENDIF()
IF (BULLET2_USE_THREAD_LOCKS)
OPTION(BULLET2_MULTITHREADED_OPEN_MP_DEMO "Build Bullet 2 MultithreadedDemo using OpenMP (requires a compiler with OpenMP support)" OFF)
OPTION(BULLET2_MULTITHREADED_TBB_DEMO "Build Bullet 2 MultithreadedDemo using Intel Threading Building Blocks (requires the TBB library to be already installed)" OFF)
IF (MSVC)
OPTION(BULLET2_MULTITHREADED_PPL_DEMO "Build Bullet 2 MultithreadedDemo using Microsoft Parallel Patterns Library (requires MSVC compiler)" OFF)
ENDIF (MSVC)
ENDIF (BULLET2_USE_THREAD_LOCKS)
ENDIF(BUILD_BULLET2_DEMOS)
OPTION(BUILD_EXTRAS "Set when you want to build the extras" ON)
@ -381,6 +289,7 @@ IF(BUILD_EXTRAS)
SUBDIRS(Extras)
ENDIF(BUILD_EXTRAS)
#Maya Dynamica plugin is moved to http://dynamica.googlecode.com
SUBDIRS(src)
@ -398,18 +307,18 @@ 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")
SET (LIB_DESTINATION "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)
SET(INCLUDE_INSTALL_DIR "include/bullet/" CACHE PATH "The subdirectory to the header prefix")
SET(PKGCONFIG_INSTALL_PREFIX "lib${LIB_SUFFIX}/pkgconfig/" CACHE STRING "Base directory for pkgconfig files")
IF(NOT MSVC)
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)
FILES
${CMAKE_CURRENT_BINARY_DIR}/bullet.pc
DESTINATION
${PKGCONFIG_INSTALL_PREFIX})
ENDIF(NOT MSVC)
ENDIF(INSTALL_LIBS)
#INSTALL of other files requires CMake 2.6
@ -417,23 +326,27 @@ 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)
OPTION(BUILD_UNIT_TESTS "Build Unit Tests" ON)
IF (BUILD_UNIT_TESTS)
SUBDIRS(UnitTests)
ENABLE_TESTING()
SUBDIRS(test)
ENDIF()
set (BULLET_CONFIG_CMAKE_PATH lib${LIB_SUFFIX}/cmake/bullet )
list (APPEND BULLET_LIBRARIES LinearMath)
list (APPEND BULLET_LIBRARIES BulletCollisions)
IF(BUILD_BULLET3)
list (APPEND BULLET_LIBRARIES BulletInverseDynamics)
ENDIF(BUILD_BULLET3)
list (APPEND BULLET_LIBRARIES BulletCollision)
list (APPEND BULLET_LIBRARIES BulletDynamics)
list (APPEND BULLET_LIBRARIES BulletSoftBody)
set (BULLET_USE_FILE ${CMAKE_INSTALL_PREFIX}/${BULLET_CONFIG_CMAKE_PATH}/UseBullet.cmake)
configure_file ( ${CMAKE_SOURCE_DIR}/BulletConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/BulletConfig.cmake
@ONLY ESCAPE_QUOTES
)
install ( FILES ${CMAKE_SOURCE_DIR}/UseBullet.cmake
${CMAKE_CURRENT_BINARY_DIR}/BulletConfig.cmake
DESTINATION ${BULLET_CONFIG_CMAKE_PATH}
)
set (BULLET_USE_FILE ${BULLET_CONFIG_CMAKE_PATH}/UseBullet.cmake)
configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/BulletConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/BulletConfig.cmake
@ONLY ESCAPE_QUOTES
)
install ( FILES ${CMAKE_CURRENT_SOURCE_DIR}/UseBullet.cmake
${CMAKE_CURRENT_BINARY_DIR}/BulletConfig.cmake
DESTINATION ${BULLET_CONFIG_CMAKE_PATH}
)

View file

@ -1,17 +0,0 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2011 Erwin Coumans http://bulletphysics.org
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.
Files in the Extras and Demos folder may have a different license, see the respective files.

View file

@ -1,795 +0,0 @@
Bullet Continuous Collision Detection and Physics Library
Primary author and maintainer: Erwin Coumans
This ChangeLog is incomplete, for an up-to-date list of all fixed issues see http://bullet.googlecode.com
using http://tinyurl.com/yabmjjj
2013 October 23
- Bullet 2.82 release
- See docs/BulletQuickstart.pdf or issue tracked for details.
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 1776
- Support for btConvex2dShape, check out Bullet/Demos/Box2dDemo
- Fixes in build systems
- Minor fix in btGjkPairDetector
- Initialize world transform for btCollisionShape in constructor
2009 September 6
- Bullet 2.75 release
- Added SPH fluid simulation in Extras, not integrated with rigid body / soft body yet
Thanks to Rama Hoetzlein to make this contribution available under the ZLib license
- add special capsule-capsule collider code in btConvexConvexCollisionAlgorithm, to speed up capsule-ragdolls
- soft body improvement: faster building of bending constraints
- soft body improvement: allow to disable/enable cluster self-collision
- soft body fix: 'exploding' soft bodies when using cluster collision
- fix some degenerate cases in continuous convex cast, could impact ray cast/convex cast
Thanks to Jacob Langford for the report and reproduction cases, see http://code.google.com/p/bullet/issues/detail?id=250&can=1&start=200
- re-enabled split impulse
- added btHinge2Constraint, btUniversalConstraint, btGeneric6DofSpringConstraint
- demonstrate 2D physics with 2D/3D object interaction
2008 December 2
- Fix contact refresh issues with btCompoundShape, introduced with btDbvt acceleration structure in btCompoundCollisionAlgorithm
- Made btSequentialImpulseConstraintSolver 100% compatible with ODE quickstep
constraints can use 'solveConstraint' method or 'getInfo/getInfo2'
2008 November 30
- Add highly optimized SIMD branchless PGS/SI solver innerloop
2008 November 12
- Add compound shape export to BulletColladaConverter
Thanks to JamesH for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=12&t=2840
- Fix compiler build for Visual Studio 6
Thanks to JoF for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2841
2008 November 11
- Add CProfileManager::dumpAll() to dump performance statistics to console using printf.
- Add support for interaction between btSoftBody and btCollisionObject/btGhostObject
2008 November 8
- Fix PosixThreadSupport
- Add improved btHeightfieldTerrainShape support and new Demos/TerrainDemo
Thanks to tomva, http://code.google.com/p/bullet/issues/detail?id=63&can=1
- Moved kinematic character controller from Demos/CharacterDemo into src/BulletDynamics/Character/btKinematicCharacterController.cpp
2008 November 6
- reduced default memory pool allocation from 40Mb to 3Mb. This should be more suitable for all platforms, including iPhone
- improved CUDA broadphase
- IBM Cell SDK 3.x support, fix ibmsdk Makefiles
- improved CMake support with 'install' and 'framework option
2008 November 4
- add btAxisSweep::resetPool to avoid non-determinism due to shuffled linked list
Thanks to Ole for the contribution,
2008 October 30
- disabled btTriangleMesh duplicate search by default, it is extremely slow
- added Extras/IFF binary chunk serialization library as preparation for in-game native platform serialization (planned COLLADA DOM -> IFF converter)
2008 October 20
- added SCE Physics Effects box-box collision detection for SPU/BulletMultiThreaded version
See Bullet/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp
Thanks to Sony Computer Entertainment Japan, SCEI for the contribution
2008 October 17
- Added btGhostObject support, this helps character controller, explosions, triggers and other local spatial queries
2008 October 10
- Moved aabb to btBroadphaseProxy, improves rayTest dramatically. Further raytest improvements using the broadphase acceleration structures are planned
- Moved BulletMultiThreaded from Extras to /src/BulletMultiThreaded for better integration
2008 October 3
- Add support for autoconf automake
./autogen.sh and ./configure will create both Makefile and Jamfile. CMake and autogenerated Visual Studio projectfiles remain supported too.
- Improved ColladaConverter: plane shape export, and callback for shape construction to allow deletion of memory
2008 Sept 30
- Improved Soft Body support, fixed issues related to soft body colliding against concave triangle meshes
- Shared more code between regular version and SPU/BulletMultiThreaded, in particular GJK/EPA
2008 Sept 28
- Fixed rotation issues in Dynamic Maya Plugin
2008 Sept 11
- Enable CCD motion clamping for btDiscreteDynamicsWorld, to avoid tunneling. A more advanced solution will be implemented in btContinuousDynamicsWorld.
2008 Sept 7
- Add btScaledBvhTriangleMeshShape, to allow re-use of btBvhTriangleMeshShape of different sizes, without copying of the BVH data.
2008 Sept 5
- Enabled Demos/ForkLiftDemo
Thanks Roman Ponomarev.
2008 Sept 4
- Added btCudaBroadphase in Extras/CUDA: some research into accelerating Bullet using CUDA.
Thanks to the particle demo from the NVidia CUDA SDK.
2008 Sept 3
- Several bug fixes and contributions related to inertia tensor, memory leaks etc.
Thanks to Ole K.
2008 Sept 1
- Updated CDTestFramework, with latest version of OPCODE Array SAP. See Extras/CDTestFramework
Thanks to Pierre Terdiman for the update
2008 August 25
- Walt Disney Studios contributes their in-house Maya Plugin for simulating Bullet physics, with options for other engines such as PhysBam or PhysX.
Thanks to Nicola Candussi and Arthur Shek
2008 August 14
- Improved performance for btDbvtBroadphase, based on dual dynamic AABB trees (one for static, one for dynamic objects, where objects can move from one to the other tree)
Thanks to Nathanael Presson again, for all his work.
2008 July 31
- Added Havok .hkx to COLLADA Physics .dae converter patch+information
- Fix btSubsimplexConvexCast
Thanks to Nacho, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2422)
- Fix in rendering, GL_STENCIL
- btTriangleIndexVertexArray indices should be unsigned int/unsigned short int,
- Made InternalProcessAllTriangles virtual, thanks to
Both thank to Fullmetalcoder, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2401
- clamp impulse for btPoint2PointConstraint
Thanks to Martijn Reuvers, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2418
- Free memory of bvh, pass in scaling factor (optional)
Thanks to Roy Eltham, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2375
2008 July 27
btDbvtBroadphase:
- Fixed a performance issues reported by 'reltham'
- Added btDbvtBroadphase::optimize() for people who want good performances right
away or don't do dynamics.
- fixed compilation issues when DBVT_BP_PROFILE was set.
btSoftBody:
- Fixed singular matrix issues related to polar decomposition (flat meshes).
DemoApplication:
- Shadows (enable/disable through 'g' or DemoApplication::setShadows(bool)).
- Texture can be enable/disable through 'u'
CDFramework:
- fixed compilation issues.
All thanks to Nathanael Presson
2008 July 10
- Added btMultimaterialTriangleMeshShape and MultiMaterialDemo
Thanks to Alex Silverman for the contribution
2008 June 30
- Added initial support for kinematic character controller
Thanks to John McCutchan
2008 April 14
- Added ray cast support for Soft Bodies
Thanks to Nathanael Presson for the contribution
2008 April 9
- Cleanup of Stan Melax ConvexHull, removed Extras/ConvexHull, moved sources into LinearMath/BulletCollision
2008 April 4
- Added btSliderConstraint and demo
Thanks Roman Ponomarev
2008 April 3
- Fixed btMinkowskiSumShape, and added hitpoint to btSubsimplexConvexCast
2008 April 2
- Added Extras/CdTestFrameWork
Thanks Pierre Terdiman
2008 April 1
- Added posix thread (pthread) support
Thanks Enrico
2008 March 30
- Added Soft Body, cloth, rope and deformable volumes, including demos and interaction
Thanks Nathanael Presson for this great contribution
2008 March 17
- Improved BulletColladaConverter
Thanks John McCutchan
2008 March 15
- btMultiSapBroadphase in a working state. Needs more optimizations to be fully useable.
- Allow btOptimizedBvh to be used for arbitrary objects, not just triangles
- added quicksort to btAlignedObjectArray
- removed btTypedUserInfo, added btHashMap
2008 March 30
- Moved quickstep solver and boxbox into Bullet/src folder
Thanks Russell L. Smith for permission to redistribute Open Dynamics Engine quickstep and box-box under the ZLib license
2008 Feb 27
- Added initial version for Character Control Demo
- Applied fixes to IBM Cell SDK 3.0 build makefiles
Thanks Jochen and mojo for reporting/providing patch: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1922
2008 Feb 8
- Bugfixes in ConvexCast support against the world.
Thanks to Isgmasa for reporting/providing fix: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1823
2008 Feb 6
- Added btCapsuleShapeX and btCapsuleShapeZ for capsules around X and Z axis (default capsule is around Y)
2008 Feb 3
- Added btTypedUserInfo, useful for serialization
2008 Jan 31
- Add support for 16 and 32-bit indices for SPU / BulletMultiThreaded version.
2008 Jan 29
- Added COLLADA Physics export/serialization/snapshot from any Bullet btDynamicsWorld. Saving the physics world into a text .xml file is useful for debugging etc.
2008 Jan 23
- Added Stan Melax Convex Hull utility library in Extras/ConvexHull. This is useful to render non-polyhedral convex objects, and to simplify convex polyhedra.
2008 Jan 14
- Add support for batch raycasting on SPU / BulletMultiThreaded
2007 Dec 16
- Added btRigidBodyConstructionInfo, to make it easier to set individual setting (and leave other untouched) during rigid body construction.
Thanks Vangelis Kokkevis for pointing this out.
- Fixed memoryleak in the ConstraintDemo and Raytracer demo.
- Fixed issue with clearing forces/gravity at the end of the stepSimulation, instead of during internalSingleStepSimulation.
Thanks chunky for pointing this out: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1780
- Disabled additional damping in rigid body by default, but enable it in most demos. Set btRigidBodyConstructionInfo m_additionalDamping to true to enable this.
- Removed obsolete QUICKPROF BEGIN/END_PROFILE, and enabled BT_PROFILE. Profiling is enabled by default (see Bullet/Demos/OpenGL/DemoApplication.cpp how to use this).
User can switch off profiling by enabling define BT_NO_PROFILE in Bullet/src/btQuickprof.h.
2007 Dec 14
- Added Hello World and BulletMultiThreaded demos
- Add portable version of BulletMultiThreaded, through SequentialThreadSupport (non-parallel but sharing the same code-path)
- Add Cmake support for AllBulletDemos
2007 Dec 11
- Moved the 'btRigidBody::clearForce' to the end of the stepSimulation, instead of in each substep.
See discussion http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1601
- Added btConvexPlaneCollisionAlgorithm, makes planes perform better, and prevents tunneling
Thanks Andy O'Neil for reporting the performance/functionality issue
- Fixes for IBM Cell SDK 3.0
Thanks to Jochen Roth for the patch.
2007 Dec 10
- Fixes in btHeightfieldTerrainShape
Thanks to Jay Lee for the patch.
2007 Dec 9
- Only update aabb of active objects
Thanks Peter Tchernev for reporting (http://bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1764 )
- Added workaround to compile libxml under Visual Studio 2008 Beta 2
- Make glui compile under MSVC 9.0 beta (vsnprintf is already defined)
2007 Dec 6
- Added DynamicControlDemo, showing dynamic control through constraint motors
Thanks to Eddy Boxerman
- Add support for generic concave shapes for convex cast.
- Added convex cast query to collision world.
- Added workaround for OpenGL bug in Mac OS X 10.5.0 (Leopard)
- Added concave raycast demo
All above thanks to John McCutchan (JMC)
- Fixed issues that prevent Linux version to compile.
Thanks to Enrico for reporting and patch, see
- Fixed misleading name 'numTriangleIndices' into 'numTriangles'
Thanks Sean Tasker for reporting:
2007 Nov 28:
- Added raycast against trianglemesh. Will be extended to object cast soon.
Thanks John McCutchan (JMC)
- make getNumPoints const correct, add const getPoints().
Thanks Dirk Gregorius
- Bugfix: allow btCollisionObjects (non-btRigidBody) to interact properly with btRigidBody for cache-friendly btSequentialImpulseConstraintSolver.
Thanks Andy O'Neil for pointing this out.
- Bugfix: don't fail if spheres have identical center, use arbitrary separating normal (1,0,0)
Thanks Sean Tasker for reporting! http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1681
2007, November 20
- Added hierarchical profiling
- Fixed memory leak in btMultiSapBroadphase,
- Fixed hash function (typo, should use 2 proxies)
Thanks to Stephen (shatcher) for reporting and fixes! http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1696
2007 Nov 11
- Fixed parallel solver (BulletMultiThreaded) friction issue
- Terminate Win32 Threads when closing the CcdPhysicsDemo (when USE_PARALLEL_SOLVER/USE_PARALLEL_DISPATCHER is defined)
2007 Nov 6
- Added support for 16-bit indices for triangle meshes
- Added support for multiple mesh parts using btBvhTriangleMeshShape.
Thanks to Tim Johansson
2007 Oct 22
- All memory allocations go through btAlignedAlloc/btAlignedFree. User can override this to verify memory leaks
- added a few more demos to AllBulletDemos
- fix for one of the constructors of btHingeConstraint
Thanks Marcus Hennix
2007 Oct 20
- included glui, a GLUT/OpenGL based toolkit for some graphical user elements
Removed dynamic_cast from glui, to allow linkage without rtti
- added Box2D framework using glui, allowing all demos to run within one executable
Thanks Erin Catto for the FrameWork skeleton (http://www.box2d.org)
2007 Ocy 17
- Allow user to pass in their own memory (stack and pool) allocators, through collisionConfiguration. See demos how to use this
2007 Oct 14
- Included working version of Cell SPU parallel optimized version for Libspe2 SPU task scheduler.
This version compiles and runs on Playstation 3 Linux and IBM CellBlade, see BulletSpuOptimized.pdf for build instructions
(Official Playstation 3 developers can request a SPURS version through Sony PS3 Devnet.)
Thanks to IBM 'Extreme Blue' project for the contribution
http://www-913.ibm.com/employment/us/extremeblue/
Thanks Minh Cuong Tran, Benjamin Hoeferlin, Frederick Roth and Martina Huellmann
for various contributions to get this initial Libspe2 parallel version up and running.
2007 Oct 13
- made 'btCollisionShape::calculateLocalInertia' const
Thanks to cgripeos, see http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1514
- applied a large patch to remove warnings
Thanks to Enrico, see http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1568
- removed SSE includes, added #incude <string.h> for memset in Extras/quickstep, thanks Eternl Knight
2007 Oct 11
- added Hashed Overlapping Pair Cache, recommended by Pierre Terdiman. It works like a charm, thanks Pierre and Erin Catto (code from Box2D)
- modified some margins inside btBoxShape, btCylinderShape and btSphereShape
- added cone debug rendering (for cones with x, y and z up-axis)
- added improvements for optional Extra/quickstep, thanks to Remotion
- some performance improvements for Bullet constraint solver
2007 Sept 28
- upgraded GIMPACT to version 0.3
Thanks to Francisco Leon
2007 Sept 27
- added contribution from IBM Extreme Blue project for Libspe2 support. This allow to execute BulletMultiThreaded on Cell SPU under PS3 Linux and Cell Blade. See http://www-913.ibm.com/employment/us/extremeblue
Thanks to Minh Cuong Tran, Frederick Roth, Martina Heullmann and Benjamin Hoeferlin.
2007 Sept 13
- Improved btGenericD6Constraint. It can be used to create ragdolls (similar to the new btConeTwistConstraint). See GenericJointDemo
- Added support for Bullet constraints in the optional Extras/quickstep ODE solver. See CcdPhysicsDemo, enable #COMPARE_WITH_QUICKSTEP and add libquickstep to the dependencies.
For both patches/improvements thanks Francisco Leon/projectileman
2007 Sept 10
- removed union from btQuadWordStorage, it caused issues under certain version of gcc/Linux
2007 Sept 10
- Reverted constraint solver, due to some issues. Need to review the recent memory allocation changes.
- Fixed issue with kinematic objects rotating at low speed: quaternion was de-normalized, passing value > 1 into acosf returns #IND00 invalid values
- 16 byte memory alignment for BVH serialization
- memory cleanup for btPoolAllocator
2007 Sept 9
- Added serialization for BVH/btBvhTriangleMeshShape, including endian swapping. See ConcaveDemo for an example.
Thanks to Phil Knight for the contribution.
- Fixed issues related to stack allocator/compound collision algorithm
Thanks Proctoid, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=18&t=1460
- Increase some default memory pool settings, and added a fallback for the constraints solver to use heap memory
- Removed accidential testing code in btScalar.h related to operator new.
- Enable btAxis3Sweep and bt32BitAxis3Sweep to be linked in at the same time, using template
2007 Sept 7
- Replaced several dynamic memory allocations by stack allocation and pool allocations
- Added branch-free quantized aabb bounding box overlap check, works better on Playstation 3 and XBox 360
Thanks to Phil Knight. Also see www.cellperformance.com for related articles
- Collision algorithms and settings for the memory/stack allocator can be done using btDefaultCollisionConfiguration
This is an API change. See demos how to modify existing implementations with a one-liner.
- Register several collision algorithms by default (sphere-sphere, sphere-box, sphere-triangle)
- Use other traveral method for BVH by default, this improves triangle mesh collision performance.
2007 Aug 31
- fixed MSVC 6 build
Thanks Proctoid, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1375
- fixed double precision build issues
Thanks Alex Silverman, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1434
2007 Aug 24
- fixed bug in btMatrix3x3::transposeTimes(const btMatrix3x3& m) const. Luckily it wasn't used in core parts of the library (yet).
Thanks to Jay Lee
2007 Aug 15
- fixed bug in Extras/GIMPACT 0.2 related to moving triangle meshes
Thanks Thomas, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1368
2007 Aug 14
- added parallel constraint solver. Works on Playstation 3 Cell SPU and multi core (Win Threads on PC and XBox 360).
See Extras/BulletMultiThreaded for SpuSolverTask subfolder and SpuParallelSolver.cpp
Thanks Marten Svanfeldt (Starbreeze Studios)
- fixed some bugs related to parallel collision detection (Extras/BulletMultiThreaded)
Thanks Marten Svanfeldt (Starbreeze Studios)
2007 Aug 2
- added compound and concave-convex (swapped) case for BulletMultiThreaded collision detection, thanks to Marten Svanfeldt
- refactored broadphase and overlapping pair cache. This allows performance improvement by combining multiple broadphases. This helps add/remove of large batches of objects and large worlds. See also Pierre Terdiman forum topic:
http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329
2007 July 27
- added Ragdoll Demo
Thanks to Marten Svanfeldt (Starbreeze Studios)
- added Vector Math library for SIMD 3D graphics linear algebra (vector, matrix, quaternion)
See Bullet/Extras/vectormathlibrary
Supports SIMD SSE, PowerPC PPU and Cell SPU (including PS3 Linux and CellBlade), as well as generic portable scalar version
Will be used to improve BulletMultiThreaded performance
Open Sourced by Sony Computer Entertainment Inc. under the new BSD license
- added SIMD math library
4-way SIMD for common math functions like atan2f4, cosf4, floorf4, fabsf4, rsqrtf4 etc. Used by Vector Math library under PPU and SPU.
Supports PowerPC (PPU) and Cell SPU, including PS3 Linux and CellBlade.
See Bullet/Extras/simdmathlibrary
Open sourced by Sony Computer Entertainment Inc. under the new BSD license
2007 July 25
- added several patches: per-rigidbody sleeping threshold. added Assert to prevent deletion of rigidbody while constraints are still pointing at it
Thanks to Marten Svanfeldt (Starbreeze Studios)
2007 July 13
- fixed relative #include paths again. We can't use "../" relative paths: some compilers choke on it (it causes extreme long paths)
Within the libraries, we always need to start with "BulletCollision/" or "BulletDynamics/ or "LinearMath/"
2007 July 10
- Updated Bullet User Manual
2007 July 5
- added btConeTwistConstraint, especially useful for ragdolls. See Demos/RagdollDemo
Thanks to Marten Svanfeldt (Starbreeze Studios)
2007 June 29
- btHeightfieldTerrainShape: Added heightfield support, with customizations
- Upgraded to GIMPACT 0.2, see Extras/GIMPACT and MovingConcaveDemo
- Several patches from Marten Svanfeldt (Starbreeze Studios)
Improved collision filtering (in broadphase and rigidbody)
Improved debug rendering
Allow to set collision filter group/mask in addRigidBody
2007 June 15
- Changed btAlignedObjectArray to call copy constructor/replacement new for duplication, rather then assignment operator (operator=).
2007 June 11
- Added multi-threading. Originally for Playstation 3 Cell SPU, but the same code can run using Win32 Threads using fake DMA transfers (memcpy)
Libspe2 support for Cell Blade / PS3 Linux is upcoming
See Extras/BulletMultiThreaded. Usage: replace btCollisionDispatcher by btSpuGatheringCollisionDispatcher
- Added managed Bullet library, entirely rewritten in C# for Windows and XBox 360 XNA
See Extras/BulletX
Thanks to KleMiX, aka Vsevolod Klementjev
2007 May 31
- sign-bit went wrong in case of 32-bit broadphase, causing quantization problems.
Thanks DevO for reporting.
2007 May 23
- Fixed quantization problem for planar triangle meshes in btOptimizedBvh
Thanks Phil Knight for reporting and helping to fix this bug.
2007 May 20
- btAxisSweep3: Fixed a bug in btAxisSweep3 (sweep and prune) related to object removal. Only showed up when at least one btStaticPlaneShape was inserted.
Thanks tbp for more details on reproducing case.
- btAxisSweep3: Fixed issue with full 32bit precision btAxisSweep3 (define BP_USE_FIXEDPOINT_INT_32), it used only 0xffff/65536 for quantization instead of full integer space (0xffffffff)
- btRaycastVehicle: Added 'getForwardVector' and getCurrentSpeedKmHour utility functions
- Fixed local scaling issues (btConvexTriangleMeshShape, btBvhTriangleMeshShape, removed scaling from btMatrix3x3).
Thanks Volker for reporting!
- Added second filename search, so that starting BspDemo and ConvexDecompositionDemo from within Visual Studio (without setting the starting path) still works
2007 April 22
- Added braking functionality to btRaycastVehicle
- Removed tons of warnings, under MSVC 2005 compilation in -W4
2007 March 21
- Fixed issues: comma at end of enum causes errors for some compilers
- Fixed initialization bug in LocalRayResult ( m_localShapeInfo(localShapeInfo) )
2007 March 20
- Added refit tree to quantized stackless tree, and updated ConcaveDemo as example.
2007 March 17
- Added constraint solver optimizations, avoiding cross products during iterations, and gather rigidbody/constraint info in contiguous memory (btSolverBody/btSolverConstraint)
- These optimizations don't give large benefit yet, but it has good potential. Turned on by default. Can be switched off using solver->setSolverMode(SOLVER_RANDMIZE_ORDER).
- Enabled anti-jitter for rigid bodies. This is experimental, and can be switched off by setting a global (it is experimental so no proper interface) gJitterVelocityDampingFactor = 1.0;
- Fixed bug in islandmanifold.heapSort(btPersistentManifoldSortPredicate()); , thanks Noehrgel for reporting this (affected Sun Solaris)
2007 March 12
- Added compile-time toggle between on 16-bit and 32-bit fixed-point SAP broadphase.
This allows the number of bodies to exceed 32767
- Enable useQuantizedAabbCompression on btTriangleMesh, see ColladaDemo
2007 March 8
- Fixed bug in constraint/island sorting (caused by replacing STL by dedicated btAlignedObjectArray with heapSort)
Thanks Clemens Unterkofler for pointing this out!
2007 March 6
- removed STL from the Bullet library: replace std::vector by btAlignedObjectArray. Also removed the std::set for overlapping pair set, and turned it into an overlapping pair array. The SAP only adds objects, never removed. Removal is postponed for during traversal of overlapping pairs (duplicates and non-overlapping pairs are removed during that traversal).
- added heap sort and binary search/linear search to btAlignedObjectArray
- fixed wrong cast, thanks Hamstray, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1015
2007 Feb 25
- Improved performance of convex collision shapes, cache local AABB instead of recomputation. This fixes issue with very slow performance in larger .bsp levels
2007 Feb 24
- Added compressed/quantized AABB tree, 16 bytes per node, while supporting 32-bit (triangle) indices.
Should be faster and smaller then original version (quantized aabb check is done in integer space)
Original aabb tree nodes are still supported. They are 44 bytes, with full floating point precision and additional subPart index.
- added meter-unit scaling support in ColladaConverter.cpp
2007 Feb 21
- Build system: updated bullet.pc.in library names
- Updated EPA comparison integration (missing parameter)
2007 Jan 04
- fixed optimized AABB tree building: in some cases the tree building fails due to unbalanced trees, which generated stack overflow
2006 Dec 15
- added contribution to allow double precision collision detection/dynamics. Define BT_USE_DOUBLE_PRECISION in your project and libraries that include Bullet
2006 Dec 14
- merged contact and non-contact constraint solving into one loop, will improve stability of jointed bodies during collisions
- added first draft for hingeConstraint motor
2006 Dec 8, Erwin Coumans
- preparation for SIMD: added btAlignedAllocator and btAlignedObjectArray, to replace stl std::vector, same interface, but compatible with 16 byte alignment
- cleaned up dependencies in autogenerated msvc projectfiles
- aligned btVector3 on 16 bytes boundary, under win32. see if developers will come up with problems
2006 Dec 04, Erwin Coumans
Added btNearCallback. This is similar to Open Dynamics Engine (ODE) dNearCallback, but important differences:
- contact points are persistent (lifetime more then one frame, for warmstarting/incremental contact point management)
- continuous collision detection, time of impact
Added btRigidBody::isInWorld(), returns true if btRigidBody is inside a btCollisionWorld/btDynamicsWorld derived class
Added angularFactor to btRigidbody, this helps some character control (no angular impulse applied)
2006 Nov 28
Moved StackAlloc from EPA into LinearMath/btStackAlloc
renamed internal class ConcaveShape into btConcaveShape
added btHeightfieldTerrainShape (not completed yet)
2006 Nov 15 Nathanael Presson
Added EPA penetration depth algorithm, Expanding Polytope Algorithm
Added Pierre Terdiman penetration depth comparison/test DEMO
Fixed Bullet's Minkowski sampling penetration depth solver
Contributed by Nathanael Presson
2006 Nov 11 Francisco León Nájera
Added GIMPACT trimesh collision detection: concave versus concave,
Contributed by Francisco León Nájera
2006 Nov 2
Minor refactoring: btCollisionObject changes from struct into class, added accessor methods
Force use of btMotionState to synchronize graphics transform, disabled old btRigidBody constructor that accepts btTransform
Renamed treshold into threshold throughout the code
2006 Oct 30
Enable decoupling of physics and graphics framerate using interpolation and internal fixed timestep, based on btMotionState
Enabled raycast vehicle demo (still needs tuning)
Refresh contact points, even when they are already persistent.
Fixed debugDraw colors (thanks pc0de for reporting)
Use Dispatcher in ConcaveConvexCollisionAlgorithm (so it uses the registered collision algorithm, not hardcoded convexconcave)
Improved performance of constraint solver by precalculating the cross product/impulse arm
Added collision comparison code: ODE box-box, also sphere-triangle
Added safety check into GJK, and an assert for AABB's that are very large
Fixed kinematic support (deriving velocities for animated objects)
Updated comparison/optional quickstep solver in Extras
UserCollisionAlgorithm demonstrates btTriangleMesh usage (easier trimesh compared to index array version)
Removed scaling from btTransform (we only want to deal with rigid transforms)
2006 Oct 4
Fixed minor leak in btOptimizeBVH
Cleanup of btRigidBody construction
added getW() in btQuaternion
assert when setLinearVelocity is called on btRigidBody
renamed projectfile library from collada-dom to colladadom (to make VC6 happy)
2006 Sept 27
Big Refactoring: renamed and moved files, create a replacement for CcdPhysicsEnvironment/CcdPhysicsController.
All Bullet classes in LinearMath, BulletCollision and BulletDynamics start with bt, and methods start with lowercase.
Moved classes into src folder, which is the only include folder needed.
Added 2 headerfiles in src: btBulletCollisionCommon.h and btBulletDynamicsCommon.h
2006 Sept 23
Fixed 2 bugs, causing crashes when removing objects. Should do better unit-testing. UnionFind and 3D SAP were involved.
2006 Sept 19
Allow programmable friction and contact solver model. User can register their own functions for several interaction types.
Improved performance, and removed hardcoded maximum overlaps (switched from C-array to stl::set)
2006 Sept 16
Added Bullet 2.0 User Manual
Allow registration of custom user collision algorithms
2006 Sept 10
Started cleaning up demos
2006 Sept 4
Fixed concave collision bug (caused instability/missing collisions in meshes/compounds)
Fixed memoryleak in OptimizedBvh, added RayTestSingle to CollisionWorld
Prepared for VehicleDemo
Increased Performance (island generation for sleeping objects took too much time)
Better COLLADA 1.4.1 physics conformance in ColladaDemo
2006 August 11
Added Quake BspDemo
Improved CCD for compound and non-convex objects
2006 August 10
Added per-triangle material (friction/restitution) support for non-convex meshes. See ConcaveDemo for usage.
2006 August 9
Added CMake support (see http://cmake.org)
This can autogenerate makefiles, projectfiles cross platform (including MacOS X Xcode )
Just run cmake . in the root folder and it will autogenerate build files
2006 July 26 Erwin Coumans
Upgraded to COLLADA-DOM 1.4.1, latest SVN version
ColladaDemo can export snapshots to .dae
2006 July 24 Erwin Coumans
Added Compound CollisionShape support
(this is still low performance -> requires stackless tree-versus-tree traversal for better performance)
2006 July 15 Erwin Coumans
Added initial support for Parallel execution (collision detection, constraint solving)
See ParallelPhysicsEnvironment in Extras\PhysicsInterface\CcdPhysics
2006 July 10 Erwin Coumans
Added MacOS X support (some build issues mainly)
2006 July 5 Erwin Coumans
Improved COLLADA 1.4 physics import, both COLLADA-DOM and FCollada
2006 June 29 Erwin Coumans
Refactoring of the broadphase
Moved some optional files to Extras: Algebraic ccd and EPA, quickstep
Moved the limits on bodies/overlap to 32k and 65k
2006 June 25 Erwin Coumans
Added basic Collision Filtering, during broadphase
Allow adding meshes to the TriangleIndexVertexArray,
(input for TriangleMeshShape)
Preparation for CompoundShape
2006 June 19 Erwin Coumans
Added support for COLLADA Physics Import.
Both jam and Visual Studio can compile ColladaDemo
2006 June 18 Dirk Gregorius <dirk@dirkgregorius.de>
Started implementing Generic6DOF joint and setup basic interface
2006 June 17 Frank Richter <resqu@gmx.ch>
Bumped version in configure.ac to 1.5.6 (assuming that "1.5f" is
the next version released).
Updated files in mk/autoconf and mk/jam with copies from CS; fixes a
GLU detection issue on MinGW.
Set msvc/bullet_ico.ico as the default application icon.
Disabled exceptions for gcc builds.
Applied a patch from Michael D. Adams to fix a warning with gcc.
2006 jUNE 16 Erwin Coumans
Constraints now merge simulation islands.
2006 May 24
Improved GJK accuracy, fixed GjkConvexCast issue, thanks to ~MyXa~ for reporting
2006 May 19
Added restitution support
Moved out Friction and Dynamics info from ManifoldPoint (removed logical dependency)
Added a void* m_userPersistentData in ManifoldPoint.
Added a ContactDestroyedCallback, to allow user to handle destruction of m_userPersistentData
2006 May 13
Fixed some bugs in friction / jacobian calculations. Reported by Dirk Gregorius. Thanks!
2006 May 9
Fixed raycasting filtering
Moved repository to SVN at https://svn.sourceforge.net/svnroot/bullet
2006 April 27
Moved raycasting to CollisionWorld, to make it more generic
Added basic CCD option in the CcdCollisionDemo
Fixed 'noResponse' mode, for triggering rigidbodies (useful for Artificial Intelligence queries)
Improved Bullet/ODE sample (in Extras)
2006 April 10
Separating Axis Test (SAT) convex hull collision detector, contribution by Simon Hobbs
Added SIMD SSE Math classes (for above SAT)
Added Mouse picking in CcdPhysicsDemo
Improved penetration depth estimation in MinkowskiPenetrationDepthSolver, both accuracy and performance
Added Hinge constraint
Added quickprof profiling (see http://sourceforge.net/projects/quickprof )
2006 March 21 Frank Richter <resqu@gmx.ch>
Removed VC manifest files.
Removed superfluous "grpplugins" projects.
2006 March 20 Erwin Coumans
Clamped the acculumated impulse rather then intermediate impulse (within the iteration)
Use the persistent contacts for reusing the impulse
Separated friction and normal solving for better stability
Decreased the default number of iterations of the constraint solver from 10 to 4
2006 March 19 Frank Richter <resqu@gmx.ch>
Removed a couple of CSisms from the VC projects.
Fixed VC include & lib paths to go to the Addtional* options
instead the command line arguments.
Added pkgconfig support.
2006 March 14 Frank Richter <resqu@gmx.ch>
Added support for shipped GLUT on MinGW.
Fixed GLUT support on MinGW.
2006 March 13 Frank Richter <resqu@gmx.ch>
Bolted on Jam-based build system.
Generated VC project files.
Fixed GCC warnings.
Fixed Linux build issues.
2006 March 13
Added 3D Sweep and Prune Broadphase Collision Detection, Contribution from Simon Hobbs.
2006 March 2
Minor change in license to ZLib/LibPNG
This makes it legally a bit easier to deploy on Playstation 3
Prepared for more generic constraints, added ConstraintsDemo
2006 Feb 23
Rearranged files and dependencies to allow for easier standalone Collision Detection without Bullet Dynamics.
See Demos/CollisionInterfaceDemo and Extras/ode/ode/test/test_BulletGjk.cpp for examples how to use.
2005 August 6
Bullet 0.2 release with demos, sources, doxygen, draft manual
2005 June 1
First public release of Bullet
... todo: add history
2003 Initial version (continuous collision detection)

View file

@ -270,7 +270,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = src
INPUT = src/LinearMath src/BulletCollision src/BulletDynamics src/BulletSoftBody src/btBulletCollisionCommon.h src/btBulletDynamicsCommon.h Extras/Serialize/BulletWorldImporter Extras/Serialize/BulletFileLoader
# If the value of the INPUT tag contains directories, you can use the
@ -605,7 +605,7 @@ SEARCH_INCLUDES = YES
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH = src
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the

View file

@ -1,111 +0,0 @@
Bullet Collision Detection and Physics Library
See also http://bulletphysics.org/mediawiki-1.5.8/index.php/Creating_a_project_from_scratch
** Windows Compilation **
Open the Microsoft Visual Studio solution in msvc/20xx/BULLET_PHYSICS.sln
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 **
- Download/install CMake from www.cmake.org or package manager
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'
BUILD_DEMOS: default 'ON', compiles applications found in 'Demos'
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'
- Run 'cmake' with desired options of the form -DOPTION=VALUE
By default this will create the usual Makefile build system, but CMake can
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 -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.
** Mac OS X Compilation **
- Download/install CMake from www.cmake.org or package manager
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'
BUILD_DEMOS: default 'ON', compiles applications found in 'Demos'
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
If both FRAMEWORK and BUILD_SHARED_LIBS are set, will create
OS X style Framework Bundles which can be placed in
linked via the -framework gcc argument or drag into Xcode projects.
(If not framework, then UNIX style 'include' and 'lib' will be produced)
Other options may be discovered by 'cmake --help-variable-list' and
'cmake --help-variable OPTION'
- Run 'cmake' with desired options of the form -DOPTION=VALUE
By default this will create the usual Makefile build system, but CMake can
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 -DFRAMEWORK=ON \
-DCMAKE_INSTALL_PREFIX=/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 autoconf/make **
- at the command line:
./autogen.sh
./configure
make
** For more help, visit http://www.bulletphysics.org **

View file

@ -1,6 +1,8 @@
/*
The files in this repository are licensed under the zlib license, except for the files under 'Extras' and examples/ThirdPartyLibs.
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
http://bulletphysics.org
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.
@ -11,9 +13,3 @@ 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.
*/

View file

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

View file

@ -1,5 +0,0 @@
For news, visit the Bullet Physics forums at
http://www.bulletphysics.org and http://bullet.googlecode.com

View file

@ -1,6 +0,0 @@
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.
See the Bullet_User_Manual.pdf for more info and visit the Bullet Physics Forum at
http://bulletphysics.org

107
Engine/lib/bullet/README.md Normal file
View file

@ -0,0 +1,107 @@
[![Travis Build Status](https://api.travis-ci.org/bulletphysics/bullet3.png?branch=master)](https://travis-ci.org/bulletphysics/bullet3)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/6sly9uxajr6xsstq)](https://ci.appveyor.com/project/erwincoumans/bullet3)
# Bullet Physics SDK
This is the official C++ source code repository of the Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.
New in Bullet 2.85: pybullet Python bindings, improved support for robotics and VR
The Bullet 2 API will stay default and up-to-date while slowly moving to a new API.
The steps towards a new API is in a nutshell:
1. The old Bullet2 demos are being merged into the examples/ExampleBrowser
2. A new physics-engine agnostic C-API is created, see examples/SharedMemory/PhysicsClientC_API.h
3. Python bindings in pybullet are on top of this C-API, see examples/pybullet
4. A Virtual Reality sandbox using openvr for HTC Vive and Oculus Rift is available
5. The OpenCL examples in the ExampleBrowser can be enabled using --enable_experimental_opencl
You can still use svn or svn externals using the github git repository: use svn co https://github.com/bulletphysics/bullet3/trunk
## Requirements for Bullet 2
A C++ compiler for C++ 2003. The library is tested on Windows, Linux, Mac OSX, iOS, Android,
but should likely work on any platform with C++ compiler.
Some optional demos require OpenGL 2 or OpenGL 3, there are some non-graphical demos and unit tests too.
## Contributors and Coding Style information
https://docs.google.com/document/d/1u9vyzPtrVoVhYqQOGNWUgjRbfwfCdIts_NzmvgiJ144/edit
## Requirements for experimental OpenCL GPGPU support
The entire collision detection and rigid body dynamics can be executed on the GPU.
A high-end desktop GPU, such as an AMD Radeon 7970 or NVIDIA GTX 680 or better.
We succesfully tested the software under Windows, Linux and Mac OSX.
The software currently doesn't work on OpenCL CPU devices. It might run
on a laptop GPU but performance will not likely be very good. Note that
often an OpenCL drivers fails to compile a kernel. Some unit tests exist to
track down the issue, but more work is required to cover all OpenCL kernels.
## License
All source code files are licensed under the permissive zlib license
(http://opensource.org/licenses/Zlib) unless marked differently in a particular folder/file.
## Build instructions for Bullet using premake. You can also use cmake instead.
**Windows**
Click on build_visual_studio.bat and open build3/vs2010/0MySolution.sln
**Windows Virtual Reality sandbox for HTC Vive and Oculus Rift**
Click on build_visual_studio_vr_pybullet_double.bat and open build3/vs2010/0MySolution.sln
Edit this batch file to choose where Python include/lib directories are located.
Build and run the App_SharedMemoryPhysics_VR project, preferably in Release/optimized build.
You can connect from Python pybullet to the sandbox using:
```
import pybullet as p
p.connect(p.SHARED_MEMORY)
```
**Linux and Mac OSX gnu make**
In a terminal type:
cd build3
Depending on your system (Linux 32bit, 64bit or Mac OSX) use one of the following lines
./premake4_linux gmake
./premake4_linux64 gmake
./premake4_osx gmake
Then
cd gmake
make
**Mac OSX Xcode**
Click on build3/xcode4.command or in a terminal window execute
./premake_osx xcode4
## Usage
The App_ExampleBrowser executables will be located in the bin folder.
You can just run it though a terminal/command prompt, or by clicking it.
```
[--start_demo_name="Demo Name"] Start with a selected demo
[--mp4=moviename.mp4] Create a mp4 movie of the window, requires ffmpeg installed
[--mouse_move_multiplier=0.400000] Set the mouse move sensitivity
[--mouse_wheel_multiplier=0.01] Set the mouse wheel sensitivity
[--background_color_red= 0.9] Set the red component for background color. Same for green and blue
[--fixed_timestep= 0.0] Use either a real-time delta time (0.0) or a fixed step size (0.016666)
```
You can use mouse picking to grab objects. When holding the ALT or CONTROL key, you have Maya style camera mouse controls.
Press F1 to create a series of screenshots. Hit ESCAPE to exit the demo app.
Check out the docs folder and the Bullet physics forums for further information.

View file

@ -1,36 +0,0 @@
This document details the steps necessary to package a release of Bullet.
1) Preparing for release:
update VERSION in several places (/VERSION file, /CMakeLists.txt, /configure.ac, /src/LinearMath/btScalar.h, /src/LinearMath/btSerializer.h around line 441)
re-generate serialization structures, if they changed (/src/LinearMath/btSerializer.cpp using makesdna)
update ChangeLog with larger/important changes
regenerate MSVC project files using build/vs_all.bat
create a Subversion tag revision in bullet.googlecode.com/svn/tags/bullet-<VERSION>
2) Generating the release .zip:
Do an SVN export on a Windows machine into the directory: bullet-X.YY
prepare a zip file containing the directory
3) Generating the release .tar.gz:
Do an SVN export on a Unix machine into the directory: bullet-X.YY
prepare a .tar.gz file containing the directory
4) Uploading release to google code:
Google Code Bullet downloads URL: http://code.google.com/p/bullet/downloads/list
Title of release should follow this guide line: Bullet <VERSION> Physics SDK <Release Type> (revision)
It is better to upload the .tar.gz before the .zip so that the .zip appears first in the list
If the release is an Alpha/Beta or RC the tags should be: Type-Source, OpSys-ALL
If the release is a final release the tags should be: Type-Source, OpSys-ALL, Featured
5) Obsoleting old releases
Edit the tags on old releases and add the 'Deprecated' tag
6) Announcing final releases:
Final release announcements are done here: http://bulletphysics.com/Bullet/phpBB3/viewforum.php?f=18

View file

@ -0,0 +1,10 @@
# -*- cmake -*-
#
# UseBullet.cmake
#
add_definitions ( ${BULLET_DEFINITIONS} )
include_directories ( ${BULLET_INCLUDE_DIRS} )
link_directories ( ${BULLET_LIBRARY_DIRS} )

View file

@ -1 +1 @@
2.82
2.85

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,19 @@
build:
project: build3/vs2010/0_Bullet3Solution.sln
build_script:
- mkdir cm
- cd cm
- cmake .. -G"Visual Studio 14 2015 Win64"
- cmake --build . --target ALL_BUILD --config Release -- /maxcpucount:4 /verbosity:quiet
test_script:
- ctest --parallel 4 --build-config Release --output-on-failure
before_build:
- echo %CD%
- ps: cd build3
- echo %CD%
- premake4 vs2010
- ps: cd ..

View file

@ -1,61 +0,0 @@
#! /bin/sh
if [ "$USER" = "root" ]; then
echo "*** You cannot do this as "$USER" please use a normal user account."
exit 1
fi
if test ! -f configure.ac ; then
echo "*** Please invoke this script from directory containing configure.ac."
exit 1
fi
echo "running aclocal"
aclocal
rc=$?
if test $rc -eq 0; then
echo "running libtool"
libtoolize --force --automake --copy
rc=$?
else
echo "An error occured, autogen.sh stopping."
exit $rc
fi
if test $rc -eq 0; then
echo "libtool worked."
else
echo "libtool not found. trying glibtool."
glibtoolize --force --automake --copy
rc=$?
fi
if test $rc -eq 0; then
echo "running automake"
automake --add-missing --copy
rc=$?
else
echo "An error occured, autogen.sh stopping."
exit $rc
fi
if test $rc -eq 0; then
echo "running autoheader"
autoheader
rc=$?
else
echo "An error occured, autogen.sh stopping."
exit $rc
fi
if test $rc -eq 0; then
echo "running autoconf"
autoconf
rc=$?
else
echo "An error occured, autogen.sh stopping."
exit $rc
fi
echo "autogen.sh complete"
exit $rc

View file

@ -0,0 +1,6 @@
Name: bullet
Description: Bullet Continuous Collision Detection and Physics Library
Requires:
Version: @BULLET_VERSION@
Libs: -L@CMAKE_INSTALL_PREFIX@/@LIB_DESTINATION@ -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath
Cflags: @BULLET_DOUBLE_DEF@ -I@CMAKE_INSTALL_PREFIX@/@INCLUDE_INSTALL_DIR@ -I@CMAKE_INSTALL_PREFIX@/include

View file

@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: bullet
Description: Bullet Continuous Collision Detection and Physics Library
Requires:
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath
Cflags: -I${includedir}/bullet

View file

@ -1,113 +0,0 @@
/* 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
/* Architecture is x86 */
#undef ARCH_X86
/* Architecture is x86-64 */
#undef ARCH_X86_64
/* 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 <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_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
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* 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
/* Platform is Apple */
#undef PLATFORM_APPLE
/* Platform is Linux */
#undef PLATFORM_LINUX
/* Platform is Win32 */
#undef PLATFORM_WIN32
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* 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

@ -1,172 +0,0 @@
#----------------------------------------------------------------------------
# Autoconf input script. Invoke the ./autogen.sh script to generate a
# configure script from this file.
#----------------------------------------------------------------------------
AC_PREREQ([2.54])
#----------------------------------------------------------------------------
# Initialize Autoconf.
#----------------------------------------------------------------------------
AC_INIT(
[bullet],
[2.82],
[erwin.coumans@gmail.com])
AC_CANONICAL_HOST
AC_CONFIG_SRCDIR([configure.ac])
AM_INIT_AUTOMAKE
AM_PROG_CC_C_O
AC_PROG_CXX
AC_PROG_LIBTOOL
case "$host" in
*-*-mingw*|*-*-cygwin*)
AC_DEFINE(PLATFORM_WIN32, 1, [Platform is Win32])
opengl_LIBS="-lunsupported_platform"
PLATFORM_STRING="Win32"
;;
*-*-linux*)
AC_DEFINE(PLATFORM_LINUX, 1, [Platform is Linux])
opengl_LIBS="-lGL -lGLU -lglut"
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"
;;
*)
AC_MSG_WARN([*** Please add $host to configure.ac checks!])
;;
esac
AC_SUBST(opengl_LIBS)
case "$host" in
i?86-* | k?-* | athlon-* | pentium*-)
AC_DEFINE(ARCH_X86, 1, [Architecture is x86])
ARCH_SPECIFIC_CFLAGS=""
ARCH_STRING="X86"
;;
x86_64-*)
AC_DEFINE(ARCH_X86_64, 1, [Architecture is x86-64])
ARCH_SPECIFIC_CFLAGS="-DUSE_ADDR64"
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"
;;
*)
AC_MSG_ERROR([Unknown Architecture])
;;
esac
AC_C_BIGENDIAN
#----------------------------------------------------------------------------
# Setup for the configuration header.
#----------------------------------------------------------------------------
AC_CONFIG_HEADERS([config.h])
#----------------------------------------------------------------------------
# Package configuration switches.
#----------------------------------------------------------------------------
AC_ARG_ENABLE([multithreaded],
[AC_HELP_STRING([--enable-multithreaded],
[build BulletMultiThreaded (default NO)])],
[disable_multithreaded=no], [disable_multithreaded=yes])
AC_MSG_CHECKING([BulletMultiThreaded])
AS_IF([test "$disable_multithreaded" = yes], [build_multithreaded=no], [build_multithreaded=yes])
AC_MSG_RESULT([$build_multithreaded])
AM_CONDITIONAL([CONDITIONAL_BUILD_MULTITHREADED], [test "$build_multithreaded" = yes])
AC_ARG_ENABLE([demos],
[AS_HELP_STRING([--disable-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])
fi
AC_ARG_ENABLE([debug],
[AC_HELP_STRING([--enable-debug],
[build with debugging information (default NO)])],
[], [enable_debug=no])
AC_MSG_CHECKING([build mode])
AS_IF([test $enable_debug = yes], [build_mode=debug], [build_mode=optimize])
AC_MSG_RESULT([$build_mode])
CFLAGS="$ARCH_SPECIFIC_CFLAGS $CFLAGS"
CXXFLAGS="$ARCH_SPECIFIC_CFLAGS $CXXFLAGS $CFLAGS"
#----------------------------------------------------------------------------
# Emit generated files.
#----------------------------------------------------------------------------
AC_CONFIG_FILES([bullet.pc Makefile Demos/Makefile Demos/SoftDemo/Makefile Demos/AllBulletDemos/Makefile Demos/MultiThreadedDemo/Makefile Demos/OpenGL/Makefile Demos/ForkLiftDemo/Makefile Demos/FeatherstoneMultiBodyDemo/Makefile Demos/BasicDemo/Makefile Demos/CcdPhysicsDemo/Makefile Demos/VehicleDemo/Makefile Demos/TerrainDemo/Makefile src/Makefile Extras/Makefile])
AC_OUTPUT
AC_MSG_NOTICE([
Please type 'make' to build Bullet
])

View file

@ -1,322 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2004-07-05.00
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
-c (ignored)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit 0;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit 0;;
*) # When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
exit 1
fi
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp"
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test -d "$pathcomp" || exit
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View file

@ -1,176 +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.
*/
/*
Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
Work in progress, functionality will be added on demand.
If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h"
*/
#ifndef BULLET_C_API_H
#define BULLET_C_API_H
#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
#ifdef BT_USE_DOUBLE_PRECISION
typedef double plReal;
#else
typedef float plReal;
#endif
typedef plReal plVector3[3];
typedef plReal plQuaternion[4];
#ifdef __cplusplus
extern "C" {
#endif
/** Particular physics SDK (C-API) */
PL_DECLARE_HANDLE(plPhysicsSdkHandle);
/** Dynamics world, belonging to some physics SDK (C-API)*/
PL_DECLARE_HANDLE(plDynamicsWorldHandle);
/** Rigid Body that can be part of a Dynamics World (C-API)*/
PL_DECLARE_HANDLE(plRigidBodyHandle);
/** Collision Shape/Geometry, property of a Rigid Body (C-API)*/
PL_DECLARE_HANDLE(plCollisionShapeHandle);
/** Constraint for Rigid Bodies (C-API)*/
PL_DECLARE_HANDLE(plConstraintHandle);
/** Triangle Mesh interface (C-API)*/
PL_DECLARE_HANDLE(plMeshInterfaceHandle);
/** Broadphase Scene/Proxy Handles (C-API)*/
PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
PL_DECLARE_HANDLE(plCollisionWorldHandle);
/**
Create and Delete a Physics SDK
*/
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 */
typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
extern plCollisionBroadphaseHandle plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback);
extern void plDestroyBroadphase(plCollisionBroadphaseHandle bp);
extern plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle);
extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
/* todo: add pair cache support with queries like add/remove/find pair */
extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk);
/* todo: add/remove objects */
/* Dynamics World */
extern plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk);
extern void plDeleteDynamicsWorld(plDynamicsWorldHandle world);
extern void plStepSimulation(plDynamicsWorldHandle, plReal timeStep);
extern void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
extern void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
/* Rigid Body */
extern plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionShapeHandle cshape );
extern void plDeleteRigidBody(plRigidBodyHandle body);
/* Collision Shape definition */
extern plCollisionShapeHandle plNewSphereShape(plReal radius);
extern plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z);
extern plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);
extern plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);
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(void);
extern void plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
/* Concave static triangle meshes */
extern plMeshInterfaceHandle plNewMeshInterface(void);
extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
extern void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling);
/* SOLID has Response Callback/Table/Management */
/* PhysX has Triggers, User Callbacks and filtering */
/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */
/* typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle rbHandle, plVector3 pos); */
/* typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle rbHandle, plQuaternion orientation); */
/* get world transform */
extern void plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
extern void plGetPosition(plRigidBodyHandle object,plVector3 position);
extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation);
/* set world transform (position/orientation) */
extern void plSetPosition(plRigidBodyHandle object, const plVector3 position);
extern void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);
extern void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);
extern void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
typedef struct plRayCastResult {
plRigidBodyHandle m_body;
plCollisionShapeHandle m_shape;
plVector3 m_positionWorld;
plVector3 m_normalWorld;
} plRayCastResult;
extern int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res);
/* Sweep API */
/* extern plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */
/* Continuous Collision Detection API */
// needed for source/blender/blenkernel/intern/collision.c
double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
#ifdef __cplusplus
}
#endif
#endif //BULLET_C_API_H

View file

@ -38,8 +38,9 @@ static DBVT_INLINE btDbvtVolume merge( const btDbvtVolume& a,
const btDbvtVolume& b)
{
#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)
ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
btDbvtVolume& res=*(btDbvtVolume*)locals;
ATTRIBUTE_ALIGNED16( char locals[sizeof(btDbvtAabbMm)]);
btDbvtVolume* ptr = (btDbvtVolume*) locals;
btDbvtVolume& res=*ptr;
#else
btDbvtVolume res;
#endif
@ -250,7 +251,8 @@ static btDbvtVolume bounds( const tNodeArray& leaves)
{
#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]);
btDbvtVolume& volume=*(btDbvtVolume*)locals;
btDbvtVolume* ptr = (btDbvtVolume*) locals;
btDbvtVolume& volume=*ptr;
volume=leaves[0]->volume;
#else
btDbvtVolume volume=leaves[0]->volume;

View file

@ -122,6 +122,7 @@ subject to the following restrictions:
#error "DBVT_INT0_IMPL undefined"
#endif
//
// Defaults volumes
//
@ -188,6 +189,9 @@ struct btDbvtNode
};
};
typedef btAlignedObjectArray<const btDbvtNode*> btNodeStack;
///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes.
///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
@ -263,7 +267,6 @@ struct btDbvt
btAlignedObjectArray<sStkNN> m_stkStack;
mutable btAlignedObjectArray<const btDbvtNode*> m_rayTestStack;
// Methods
@ -325,6 +328,16 @@ struct btDbvt
void collideTV( const btDbvtNode* root,
const btDbvtVolume& volume,
DBVT_IPOLICY) const;
DBVT_PREFIX
void collideTVNoStackAlloc( const btDbvtNode* root,
const btDbvtVolume& volume,
btNodeStack& stack,
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
@ -343,6 +356,7 @@ struct btDbvt
btScalar lambda_max,
const btVector3& aabbMin,
const btVector3& aabbMax,
btAlignedObjectArray<const btDbvtNode*>& stack,
DBVT_IPOLICY) const;
DBVT_PREFIX
@ -917,39 +931,72 @@ inline void btDbvt::collideTT( const btDbvtNode* root0,
}
#endif
//
DBVT_PREFIX
inline void btDbvt::collideTV( const btDbvtNode* root,
const btDbvtVolume& vol,
DBVT_IPOLICY) const
{
DBVT_CHECKTYPE
if(root)
{
ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol);
btAlignedObjectArray<const btDbvtNode*> stack;
stack.resize(0);
stack.reserve(SIMPLE_STACKSIZE);
stack.push_back(root);
do {
const btDbvtNode* n=stack[stack.size()-1];
stack.pop_back();
if(Intersect(n->volume,volume))
if(root)
{
ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol);
btAlignedObjectArray<const btDbvtNode*> stack;
stack.resize(0);
stack.reserve(SIMPLE_STACKSIZE);
stack.push_back(root);
do {
const btDbvtNode* n=stack[stack.size()-1];
stack.pop_back();
if(Intersect(n->volume,volume))
{
if(n->isinternal())
{
if(n->isinternal())
{
stack.push_back(n->childs[0]);
stack.push_back(n->childs[1]);
}
else
{
policy.Process(n);
}
stack.push_back(n->childs[0]);
stack.push_back(n->childs[1]);
}
} while(stack.size()>0);
}
else
{
policy.Process(n);
}
}
} while(stack.size()>0);
}
}
//
DBVT_PREFIX
inline void btDbvt::collideTVNoStackAlloc( const btDbvtNode* root,
const btDbvtVolume& vol,
btNodeStack& stack,
DBVT_IPOLICY) const
{
DBVT_CHECKTYPE
if(root)
{
ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol);
stack.resize(0);
stack.reserve(SIMPLE_STACKSIZE);
stack.push_back(root);
do {
const btDbvtNode* n=stack[stack.size()-1];
stack.pop_back();
if(Intersect(n->volume,volume))
{
if(n->isinternal())
{
stack.push_back(n->childs[0]);
stack.push_back(n->childs[1]);
}
else
{
policy.Process(n);
}
}
} while(stack.size()>0);
}
}
DBVT_PREFIX
inline void btDbvt::rayTestInternal( const btDbvtNode* root,
const btVector3& rayFrom,
@ -959,7 +1006,8 @@ inline void btDbvt::rayTestInternal( const btDbvtNode* root,
btScalar lambda_max,
const btVector3& aabbMin,
const btVector3& aabbMax,
DBVT_IPOLICY) const
btAlignedObjectArray<const btDbvtNode*>& stack,
DBVT_IPOLICY ) const
{
(void) rayTo;
DBVT_CHECKTYPE
@ -969,7 +1017,6 @@ inline void btDbvt::rayTestInternal( const btDbvtNode* root,
int depth=1;
int treshold=DOUBLE_STACKSIZE-2;
btAlignedObjectArray<const btDbvtNode*>& stack = m_rayTestStack;
stack.resize(DOUBLE_STACKSIZE);
stack[0]=root;
btVector3 bounds[2];
@ -1193,19 +1240,34 @@ inline void btDbvt::collideOCL( const btDbvtNode* root,
/* Insert 0 */
j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
stack.push_back(0);
//void * memmove ( void * destination, const void * source, size_t num );
#if DBVT_USE_MEMMOVE
memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
{
int num_items_to_move = stack.size()-1-j;
if(num_items_to_move > 0)
memmove(&stack[j+1],&stack[j],sizeof(int)*num_items_to_move);
}
#else
for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
for(int k=stack.size()-1;k>j;--k) {
stack[k]=stack[k-1];
}
#endif
stack[j]=allocate(ifree,stock,nes[q]);
/* Insert 1 */
j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
stack.push_back(0);
#if DBVT_USE_MEMMOVE
memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
{
int num_items_to_move = stack.size()-1-j;
if(num_items_to_move > 0)
memmove(&stack[j+1],&stack[j],sizeof(int)*num_items_to_move);
}
#else
for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
for(int k=stack.size()-1;k>j;--k) {
stack[k]=stack[k-1];
}
#endif
stack[j]=allocate(ifree,stock,nes[1-q]);
}

View file

@ -16,6 +16,7 @@ subject to the following restrictions:
///btDbvtBroadphase implementation by Nathanael Presson
#include "btDbvtBroadphase.h"
#include "LinearMath/btThreads.h"
//
// Profiling
@ -142,6 +143,11 @@ btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
{
m_stageRoots[i]=0;
}
#if BT_THREADSAFE
m_rayTestStacks.resize(BT_MAX_THREAD_COUNT);
#else
m_rayTestStacks.resize(1);
#endif
#if DBVT_BP_PROFILE
clear(m_profiling);
#endif
@ -227,6 +233,23 @@ struct BroadphaseRayTester : btDbvt::ICollide
void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
{
BroadphaseRayTester callback(rayCallback);
btAlignedObjectArray<const btDbvtNode*>* stack = &m_rayTestStacks[0];
#if BT_THREADSAFE
// for this function to be threadsafe, each thread must have a separate copy
// of this stack. This could be thread-local static to avoid dynamic allocations,
// instead of just a local.
int threadIndex = btGetCurrentThreadIndex();
btAlignedObjectArray<const btDbvtNode*> localStack;
if (threadIndex < m_rayTestStacks.size())
{
// use per-thread preallocated stack if possible to avoid dynamic allocations
stack = &m_rayTestStacks[threadIndex];
}
else
{
stack = &localStack;
}
#endif
m_sets[0].rayTestInternal( m_sets[0].m_root,
rayFrom,
@ -236,6 +259,7 @@ void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo,
rayCallback.m_lambda_max,
aabbMin,
aabbMax,
*stack,
callback);
m_sets[1].rayTestInternal( m_sets[1].m_root,
@ -246,6 +270,7 @@ void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo,
rayCallback.m_lambda_max,
aabbMin,
aabbMax,
*stack,
callback);
}

View file

@ -87,6 +87,7 @@ struct btDbvtBroadphase : btBroadphaseInterface
bool m_releasepaircache; // Release pair cache on delete
bool m_deferedcollide; // Defere dynamic/static collision to collide call
bool m_needcleanup; // Need to run cleanup?
btAlignedObjectArray< btAlignedObjectArray<const btDbvtNode*> > m_rayTestStacks;
#if DBVT_BP_PROFILE
btClock m_clock;
struct {

View file

@ -64,6 +64,12 @@ struct btDispatcherInfo
btScalar m_convexConservativeDistanceThreshold;
};
enum ebtDispatcherQueryType
{
BT_CONTACT_POINT_ALGORITHMS = 1,
BT_CLOSEST_POINT_ALGORITHMS = 2
};
///The btDispatcher interface class can be used in combination with broadphase to dispatch calculations for overlapping pairs.
///For example for pairwise collision detection, calculating contact points stored in btPersistentManifold or user callbacks (game logic).
class btDispatcher
@ -73,7 +79,7 @@ class btDispatcher
public:
virtual ~btDispatcher() ;
virtual btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold=0) = 0;
virtual btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold, ebtDispatcherQueryType queryType) = 0;
virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1)=0;

View file

@ -34,7 +34,6 @@ int gFindPairs =0;
btHashedOverlappingPairCache::btHashedOverlappingPairCache():
m_overlapFilterCallback(0),
m_blockedForChanges(false),
m_ghostPairCallback(0)
{
int initialAllocatedSize= 2;
@ -373,10 +372,10 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
return userData;
}
//#include <stdio.h>
#include "LinearMath/btQuickprof.h"
void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher)
{
BT_PROFILE("btHashedOverlappingPairCache::processAllOverlappingPairs");
int i;
// printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size());

View file

@ -94,7 +94,6 @@ class btHashedOverlappingPairCache : public btOverlappingPairCache
{
btBroadphasePairArray m_overlappingPairArray;
btOverlapFilterCallback* m_overlapFilterCallback;
bool m_blockedForChanges;
protected:

View file

@ -107,6 +107,8 @@ void btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btV
v = unQuantize(vecIn);
m_bvhAabbMin.setMin(v-clampValue);
}
aabbSize = m_bvhAabbMax - m_bvhAabbMin;
m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
{
quantize(vecIn,m_bvhAabbMax,true);
v = unQuantize(vecIn);

View file

@ -18,6 +18,7 @@ SET(BulletCollision_SRCS
CollisionDispatch/btCollisionDispatcher.cpp
CollisionDispatch/btCollisionObject.cpp
CollisionDispatch/btCollisionWorld.cpp
CollisionDispatch/btCollisionWorldImporter.cpp
CollisionDispatch/btCompoundCollisionAlgorithm.cpp
CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp
CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
@ -126,6 +127,7 @@ SET(CollisionDispatch_HDRS
CollisionDispatch/btCollisionObject.h
CollisionDispatch/btCollisionObjectWrapper.h
CollisionDispatch/btCollisionWorld.h
CollisionDispatch/btCollisionWorldImporter.h
CollisionDispatch/btCompoundCollisionAlgorithm.h
CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h
CollisionDispatch/btConvexConcaveCollisionAlgorithm.h

View file

@ -100,7 +100,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
btScalar radiusWithThreshold = radius + contactBreakingThreshold;
btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
normal.normalize();
normal.safeNormalize();
btVector3 p1ToCentre = sphereCenter - vertices[0];
btScalar distanceFromPlane = p1ToCentre.dot(normal);

View file

@ -40,6 +40,9 @@ public:
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0;
virtual btCollisionAlgorithmCreateFunc* getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) = 0;
};
#endif //BT_COLLISION_CONFIGURATION

View file

@ -16,7 +16,7 @@ subject to the following restrictions:
#include "btCollisionDispatcher.h"
#include "LinearMath/btQuickprof.h"
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
@ -50,8 +50,10 @@ m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESH
{
for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
{
m_doubleDispatch[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j);
btAssert(m_doubleDispatch[i][j]);
m_doubleDispatchContactPoints[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j);
btAssert(m_doubleDispatchContactPoints[i][j]);
m_doubleDispatchClosestPoints[i][j] = m_collisionConfiguration->getClosestPointsAlgorithmCreateFunc(i, j);
}
}
@ -61,7 +63,12 @@ m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESH
void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
{
m_doubleDispatch[proxyType0][proxyType1] = createFunc;
m_doubleDispatchContactPoints[proxyType0][proxyType1] = createFunc;
}
void btCollisionDispatcher::registerClosestPointsCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
{
m_doubleDispatchClosestPoints[proxyType0][proxyType1] = createFunc;
}
btCollisionDispatcher::~btCollisionDispatcher()
@ -84,14 +91,10 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(const btCollisionObj
btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
void* mem = 0;
if (m_persistentManifoldPoolAllocator->getFreeCount())
void* mem = m_persistentManifoldPoolAllocator->allocate( sizeof( btPersistentManifold ) );
if (NULL == mem)
{
mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold));
} else
{
//we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert.
//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);
@ -142,14 +145,23 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold)
btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold, ebtDispatcherQueryType algoType)
{
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher1 = this;
ci.m_manifold = sharedManifold;
btCollisionAlgorithm* algo = m_doubleDispatch[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0Wrap,body1Wrap);
btCollisionAlgorithm* algo = 0;
if (algoType == BT_CONTACT_POINT_ALGORITHMS)
{
algo = m_doubleDispatchContactPoints[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci, body0Wrap, body1Wrap);
}
else
{
algo = m_doubleDispatchClosestPoints[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci, body0Wrap, body1Wrap);
}
return algo;
}
@ -189,7 +201,7 @@ bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0,const
if ((!body0->isActive()) && (!body1->isActive()))
needsCollision = false;
else if (!body0->checkCollideWith(body1))
else if ((!body0->checkCollideWith(body1)) || (!body1->checkCollideWith(body0)))
needsCollision = false;
return needsCollision ;
@ -227,6 +239,8 @@ public:
virtual bool processOverlap(btBroadphasePair& pair)
{
BT_PROFILE("btCollisionDispatcher::processOverlap");
(*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo);
return false;
@ -249,7 +263,6 @@ void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pa
//by default, Bullet will use this near callback
void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
{
@ -265,7 +278,7 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair,
//dispatcher will keep algorithms persistent in the collision pair
if (!collisionPair.m_algorithm)
{
collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap);
collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap,0, BT_CONTACT_POINT_ALGORITHMS);
}
if (collisionPair.m_algorithm)
@ -293,13 +306,13 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair,
void* btCollisionDispatcher::allocateCollisionAlgorithm(int size)
{
if (m_collisionAlgorithmPoolAllocator->getFreeCount())
{
return m_collisionAlgorithmPoolAllocator->allocate(size);
}
//warn user for overflow?
return btAlignedAlloc(static_cast<size_t>(size), 16);
void* mem = m_collisionAlgorithmPoolAllocator->allocate( size );
if (NULL == mem)
{
//warn user for overflow?
return btAlignedAlloc(static_cast<size_t>(size), 16);
}
return mem;
}
void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr)

View file

@ -57,7 +57,9 @@ protected:
btPoolAllocator* m_persistentManifoldPoolAllocator;
btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
btCollisionAlgorithmCreateFunc* m_doubleDispatchContactPoints[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
btCollisionAlgorithmCreateFunc* m_doubleDispatchClosestPoints[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
btCollisionConfiguration* m_collisionConfiguration;
@ -84,6 +86,8 @@ public:
///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc);
void registerClosestPointsCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc);
int getNumManifolds() const
{
return int( m_manifoldsPtr.size());
@ -115,7 +119,7 @@ public:
virtual void clearManifold(btPersistentManifold* manifold);
btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold = 0);
btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold, ebtDispatcherQueryType queryType);
virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1);

View file

@ -28,13 +28,19 @@ btCollisionObject::btCollisionObject()
m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT),
m_islandTag1(-1),
m_companionId(-1),
m_worldArrayIndex(-1),
m_activationState1(1),
m_deactivationTime(btScalar(0.)),
m_friction(btScalar(0.5)),
m_rollingFriction(0.0f),
m_restitution(btScalar(0.)),
m_rollingFriction(0.0f),
m_spinningFriction(0.f),
m_contactDamping(.1),
m_contactStiffness(1e4),
m_internalType(CO_COLLISION_OBJECT),
m_userObjectPointer(0),
m_userIndex2(-1),
m_userIndex(-1),
m_hitFraction(btScalar(1.)),
m_ccdSweptSphereRadius(btScalar(0.)),
m_ccdMotionThreshold(btScalar(0.)),
@ -90,6 +96,8 @@ const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* seriali
dataOut->m_deactivationTime = m_deactivationTime;
dataOut->m_friction = m_friction;
dataOut->m_rollingFriction = m_rollingFriction;
dataOut->m_contactDamping = m_contactDamping;
dataOut->m_contactStiffness = m_contactStiffness;
dataOut->m_restitution = m_restitution;
dataOut->m_internalType = m_internalType;

View file

@ -79,24 +79,31 @@ protected:
int m_islandTag1;
int m_companionId;
int m_worldArrayIndex; // index of object in world's collisionObjects array
mutable int m_activationState1;
mutable btScalar m_deactivationTime;
btScalar m_friction;
btScalar m_restitution;
btScalar m_rollingFriction;
btScalar m_rollingFriction;//torsional friction orthogonal to contact normal (useful to stop spheres rolling forever)
btScalar m_spinningFriction; // torsional friction around the contact normal (useful for grasping)
btScalar m_contactDamping;
btScalar m_contactStiffness;
///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
union
{
void* m_userObjectPointer;
int m_userIndex;
};
void* m_userObjectPointer;
int m_userIndex2;
int m_userIndex;
///time of impact calculation
btScalar m_hitFraction;
@ -110,13 +117,12 @@ protected:
/// If some object should have elaborate collision filtering by sub-classes
int m_checkCollideWith;
btAlignedObjectArray<const btCollisionObject*> m_objectsWithoutCollisionCheck;
///internal update revision number. It will be increased when the object changes. This allows some subsystems to perform lazy evaluation.
int m_updateRevision;
virtual bool checkCollideWithOverride(const btCollisionObject* /* co */) const
{
return true;
}
btVector3 m_customDebugColorRGB;
public:
@ -130,7 +136,9 @@ public:
CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
CF_CHARACTER_OBJECT = 16,
CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing
CF_DISABLE_SPU_COLLISION_PROCESSING = 64//disable parallel/SPU processing
CF_DISABLE_SPU_COLLISION_PROCESSING = 64,//disable parallel/SPU processing
CF_HAS_CONTACT_STIFFNESS_DAMPING = 128,
CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR = 256,
};
enum CollisionObjectTypes
@ -225,6 +233,33 @@ public:
return m_collisionShape;
}
void setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck)
{
if (ignoreCollisionCheck)
{
//We don't check for duplicates. Is it ok to leave that up to the user of this API?
//int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
//if (index == m_objectsWithoutCollisionCheck.size())
//{
m_objectsWithoutCollisionCheck.push_back(co);
//}
}
else
{
m_objectsWithoutCollisionCheck.remove(co);
}
m_checkCollideWith = m_objectsWithoutCollisionCheck.size() > 0;
}
virtual bool checkCollideWithOverride(const btCollisionObject* co) const
{
int index = m_objectsWithoutCollisionCheck.findLinearSearch(co);
if (index < m_objectsWithoutCollisionCheck.size())
{
return false;
}
return true;
}
@ -292,7 +327,39 @@ public:
{
return m_rollingFriction;
}
void setSpinningFriction(btScalar frict)
{
m_updateRevision++;
m_spinningFriction = frict;
}
btScalar getSpinningFriction() const
{
return m_spinningFriction;
}
void setContactStiffnessAndDamping(btScalar stiffness, btScalar damping)
{
m_updateRevision++;
m_contactStiffness = stiffness;
m_contactDamping = damping;
m_collisionFlags |=CF_HAS_CONTACT_STIFFNESS_DAMPING;
//avoid divisions by zero...
if (m_contactStiffness< SIMD_EPSILON)
{
m_contactStiffness = SIMD_EPSILON;
}
}
btScalar getContactStiffness() const
{
return m_contactStiffness;
}
btScalar getContactDamping() const
{
return m_contactDamping;
}
///reserved for Bullet internal usage
int getInternalType() const
@ -391,7 +458,18 @@ public:
m_companionId = id;
}
SIMD_FORCE_INLINE btScalar getHitFraction() const
SIMD_FORCE_INLINE int getWorldArrayIndex() const
{
return m_worldArrayIndex;
}
// only should be called by CollisionWorld
void setWorldArrayIndex(int ix)
{
m_worldArrayIndex = ix;
}
SIMD_FORCE_INLINE btScalar getHitFraction() const
{
return m_hitFraction;
}
@ -452,6 +530,12 @@ public:
{
return m_userIndex;
}
int getUserIndex2() const
{
return m_userIndex2;
}
///users can point to their objects, userPointer is not used by Bullet
void setUserPointer(void* userPointer)
{
@ -464,11 +548,36 @@ public:
m_userIndex = index;
}
void setUserIndex2(int index)
{
m_userIndex2 = index;
}
int getUpdateRevisionInternal() const
{
return m_updateRevision;
}
void setCustomDebugColor(const btVector3& colorRGB)
{
m_customDebugColorRGB = colorRGB;
m_collisionFlags |= CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR;
}
void removeCustomDebugColor()
{
m_collisionFlags &= ~CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR;
}
bool getCustomDebugColor(btVector3& colorRGB) const
{
bool hasCustomColor = (0!=(m_collisionFlags&CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR));
if (hasCustomColor)
{
colorRGB = m_customDebugColorRGB;
}
return hasCustomColor;
}
inline bool checkCollideWith(const btCollisionObject* co) const
{
@ -504,6 +613,8 @@ struct btCollisionObjectDoubleData
double m_deactivationTime;
double m_friction;
double m_rollingFriction;
double m_contactDamping;
double m_contactStiffness;
double m_restitution;
double m_hitFraction;
double m_ccdSweptSphereRadius;
@ -537,7 +648,8 @@ struct btCollisionObjectFloatData
float m_deactivationTime;
float m_friction;
float m_rollingFriction;
float m_contactDamping;
float m_contactStiffness;
float m_restitution;
float m_hitFraction;
float m_ccdSweptSphereRadius;

View file

@ -34,7 +34,7 @@ subject to the following restrictions:
#include "LinearMath/btSerializer.h"
#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
#include "BulletCollision/Gimpact/btGImpactShape.h"
//#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
@ -115,7 +115,9 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
//check that the object isn't already added
btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size());
btAssert(collisionObject->getWorldArrayIndex() == -1); // do not add the same object to more than one collision world
collisionObject->setWorldArrayIndex(m_collisionObjects.size());
m_collisionObjects.push_back(collisionObject);
//calculate new AABB
@ -195,6 +197,7 @@ void btCollisionWorld::updateAabbs()
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
btAssert(colObj->getWorldArrayIndex() == i);
//only update aabb of active objects
if (m_forceUpdateAllAabbs || colObj->isActive())
@ -253,9 +256,25 @@ void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
}
//swapremove
m_collisionObjects.remove(collisionObject);
int iObj = collisionObject->getWorldArrayIndex();
btAssert(iObj >= 0 && iObj < m_collisionObjects.size()); // trying to remove an object that was never added or already removed previously?
if (iObj >= 0 && iObj < m_collisionObjects.size())
{
btAssert(collisionObject == m_collisionObjects[iObj]);
m_collisionObjects.swap(iObj, m_collisionObjects.size()-1);
m_collisionObjects.pop_back();
if (iObj < m_collisionObjects.size())
{
m_collisionObjects[iObj]->setWorldArrayIndex(iObj);
}
}
else
{
// slow linear search
//swapremove
m_collisionObjects.remove(collisionObject);
}
collisionObject->setWorldArrayIndex(-1);
}
@ -292,12 +311,13 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
btGjkConvexCast gjkConvexCaster(castShape,convexShape,&simplexSolver);
//btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
bool condition = true;
btConvexCast* convexCasterPtr = 0;
if (resultCallback.m_flags & btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest)
convexCasterPtr = &subSimplexConvexCaster;
else
//use kF_UseSubSimplexConvexCastRaytest by default
if (resultCallback.m_flags & btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest)
convexCasterPtr = &gjkConvexCaster;
else
convexCasterPtr = &subSimplexConvexCaster;
btConvexCast& convexCaster = *convexCasterPtr;
@ -308,6 +328,7 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
{
if (castResult.m_fraction < resultCallback.m_closestHitFraction)
{
//todo: figure out what this is about. When is rayFromTest.getBasis() not identity?
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
//rotate normal into worldspace
castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
@ -387,14 +408,7 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
}
else if(collisionShape->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
{
btGImpactMeshShape* concaveShape = (btGImpactMeshShape*)collisionShape;
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
concaveShape->processAllTrianglesRay(&rcb,rayFromLocal,rayToLocal);
}else
else
{
//generic (slower) case
btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
@ -770,7 +784,7 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,
hitPointLocal,
hitFraction);
bool normalInWorldSpace = false;
bool normalInWorldSpace = true;
return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
}
@ -795,23 +809,50 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,
}
}
} else {
///@todo : use AABB tree or other BVH acceleration structure!
if (collisionShape->isCompound())
{
BT_PROFILE("convexSweepCompound");
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
int i=0;
for (i=0;i<compoundShape->getNumChildShapes();i++)
struct btCompoundLeafCallback : btDbvt::ICollide
{
btTransform childTrans = compoundShape->getChildTransform(i);
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childWorldTrans = colObjWorldTransform * childTrans;
btCompoundLeafCallback(
const btCollisionObjectWrapper* colObjWrap,
const btConvexShape* castShape,
const btTransform& convexFromTrans,
const btTransform& convexToTrans,
btScalar allowedPenetration,
const btCompoundShape* compoundShape,
const btTransform& colObjWorldTransform,
ConvexResultCallback& resultCallback)
:
m_colObjWrap(colObjWrap),
m_castShape(castShape),
m_convexFromTrans(convexFromTrans),
m_convexToTrans(convexToTrans),
m_allowedPenetration(allowedPenetration),
m_compoundShape(compoundShape),
m_colObjWorldTransform(colObjWorldTransform),
m_resultCallback(resultCallback) {
}
struct LocalInfoAdder : public ConvexResultCallback {
ConvexResultCallback* m_userCallback;
const btCollisionObjectWrapper* m_colObjWrap;
const btConvexShape* m_castShape;
const btTransform& m_convexFromTrans;
const btTransform& m_convexToTrans;
btScalar m_allowedPenetration;
const btCompoundShape* m_compoundShape;
const btTransform& m_colObjWorldTransform;
ConvexResultCallback& m_resultCallback;
public:
void ProcessChild(int index, const btTransform& childTrans, const btCollisionShape* childCollisionShape)
{
btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
struct LocalInfoAdder : public ConvexResultCallback {
ConvexResultCallback* m_userCallback;
int m_i;
LocalInfoAdder (int i, ConvexResultCallback *user)
LocalInfoAdder(int i, ConvexResultCallback *user)
: m_userCallback(user), m_i(i)
{
m_closestHitFraction = m_userCallback->m_closestHitFraction;
@ -820,27 +861,66 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,
{
return m_userCallback->needsCollision(p);
}
virtual btScalar addSingleResult (btCollisionWorld::LocalConvexResult& r, bool b)
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = -1;
shapeInfo.m_triangleIndex = m_i;
if (r.m_localShapeInfo == NULL)
r.m_localShapeInfo = &shapeInfo;
const btScalar result = m_userCallback->addSingleResult(r, b);
m_closestHitFraction = m_userCallback->m_closestHitFraction;
return result;
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& r, bool b)
{
btCollisionWorld::LocalShapeInfo shapeInfo;
shapeInfo.m_shapePart = -1;
shapeInfo.m_triangleIndex = m_i;
if (r.m_localShapeInfo == NULL)
r.m_localShapeInfo = &shapeInfo;
const btScalar result = m_userCallback->addSingleResult(r, b);
m_closestHitFraction = m_userCallback->m_closestHitFraction;
return result;
}
};
}
};
LocalInfoAdder my_cb(i, &resultCallback);
LocalInfoAdder my_cb(index, &m_resultCallback);
btCollisionObjectWrapper tmpObj(colObjWrap,childCollisionShape,colObjWrap->getCollisionObject(),childWorldTrans,-1,i);
btCollisionObjectWrapper tmpObj(m_colObjWrap, childCollisionShape, m_colObjWrap->getCollisionObject(), childWorldTrans, -1, index);
objectQuerySingleInternal(castShape, convexFromTrans,convexToTrans,
&tmpObj,my_cb, allowedPenetration);
objectQuerySingleInternal(m_castShape, m_convexFromTrans, m_convexToTrans, &tmpObj, my_cb, m_allowedPenetration);
}
void Process(const btDbvtNode* leaf)
{
// Processing leaf node
int index = leaf->dataAsInt;
btTransform childTrans = m_compoundShape->getChildTransform(index);
const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(index);
ProcessChild(index, childTrans, childCollisionShape);
}
};
BT_PROFILE("convexSweepCompound");
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
btVector3 fromLocalAabbMin, fromLocalAabbMax;
btVector3 toLocalAabbMin, toLocalAabbMax;
castShape->getAabb(colObjWorldTransform.inverse() * convexFromTrans, fromLocalAabbMin, fromLocalAabbMax);
castShape->getAabb(colObjWorldTransform.inverse() * convexToTrans, toLocalAabbMin, toLocalAabbMax);
fromLocalAabbMin.setMin(toLocalAabbMin);
fromLocalAabbMax.setMax(toLocalAabbMax);
btCompoundLeafCallback callback(colObjWrap, castShape, convexFromTrans, convexToTrans,
allowedPenetration, compoundShape, colObjWorldTransform, resultCallback);
const btDbvt* tree = compoundShape->getDynamicAabbTree();
if (tree) {
const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(fromLocalAabbMin, fromLocalAabbMax);
tree->collideTV(tree->m_root, bounds, callback);
} else {
int i;
for (i=0;i<compoundShape->getNumChildShapes();i++)
{
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childTrans = compoundShape->getChildTransform(i);
callback.ProcessChild(i, childTrans, childCollisionShape);
}
}
}
}
@ -1151,7 +1231,7 @@ struct btSingleContactCallback : public btBroadphaseAabbCallback
btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform(),-1,-1);
btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1);
btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1);
btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1,0, BT_CLOSEST_POINT_ALGORITHMS);
if (algorithm)
{
btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
@ -1187,10 +1267,11 @@ void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionOb
btCollisionObjectWrapper obA(0,colObjA->getCollisionShape(),colObjA,colObjA->getWorldTransform(),-1,-1);
btCollisionObjectWrapper obB(0,colObjB->getCollisionShape(),colObjB,colObjB->getWorldTransform(),-1,-1);
btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA,&obB);
btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA,&obB, 0, BT_CLOSEST_POINT_ALGORITHMS);
if (algorithm)
{
btBridgedManifoldResult contactPointResult(&obA,&obB, resultCallback);
contactPointResult.m_closestPointDistanceThreshold = resultCallback.m_closestDistanceThreshold;
//discrete collision detection query
algorithm->processCollision(&obA,&obB, getDispatchInfo(),&contactPointResult);
@ -1251,7 +1332,10 @@ public:
void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
{
// Draw a small simplex at the center of the object
getDebugDrawer()->drawTransform(worldTransform,1);
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawFrames)
{
getDebugDrawer()->drawTransform(worldTransform,1);
}
if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
{
@ -1429,81 +1513,93 @@ void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const
void btCollisionWorld::debugDrawWorld()
{
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
if (getDebugDrawer())
{
int numManifolds = getDispatcher()->getNumManifolds();
btVector3 color(1,1,0);
for (int i=0;i<numManifolds;i++)
{
btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
//btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
//btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
btIDebugDraw::DefaultColors defaultColors = getDebugDrawer()->getDefaultColors();
int numContacts = contactManifold->getNumContacts();
for (int j=0;j<numContacts;j++)
if ( getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
{
if (getDispatcher())
{
btManifoldPoint& cp = contactManifold->getContactPoint(j);
getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
int numManifolds = getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++)
{
btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
//btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
//btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
int numContacts = contactManifold->getNumContacts();
for (int j=0;j<numContacts;j++)
{
btManifoldPoint& cp = contactManifold->getContactPoint(j);
getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),defaultColors.m_contactPoint);
}
}
}
}
}
if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb)))
{
int i;
for ( i=0;i<m_collisionObjects.size();i++)
if ((getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb)))
{
btCollisionObject* colObj = m_collisionObjects[i];
if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
int i;
for ( i=0;i<m_collisionObjects.size();i++)
{
if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
btCollisionObject* colObj = m_collisionObjects[i];
if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
{
btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
switch(colObj->getActivationState())
if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
{
case ACTIVE_TAG:
color = btVector3(btScalar(1.),btScalar(1.),btScalar(1.)); break;
case ISLAND_SLEEPING:
color = btVector3(btScalar(0.),btScalar(1.),btScalar(0.));break;
case WANTS_DEACTIVATION:
color = btVector3(btScalar(0.),btScalar(1.),btScalar(1.));break;
case DISABLE_DEACTIVATION:
color = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));break;
case DISABLE_SIMULATION:
color = btVector3(btScalar(1.),btScalar(1.),btScalar(0.));break;
default:
btVector3 color(btScalar(0.4),btScalar(0.4),btScalar(0.4));
switch(colObj->getActivationState())
{
color = btVector3(btScalar(1),btScalar(0.),btScalar(0.));
}
};
case ACTIVE_TAG:
color = defaultColors.m_activeObject; break;
case ISLAND_SLEEPING:
color = defaultColors.m_deactivatedObject;break;
case WANTS_DEACTIVATION:
color = defaultColors.m_wantsDeactivationObject;break;
case DISABLE_DEACTIVATION:
color = defaultColors.m_disabledDeactivationObject;break;
case DISABLE_SIMULATION:
color = defaultColors.m_disabledSimulationObject;break;
default:
{
color = btVector3(btScalar(.3),btScalar(0.3),btScalar(0.3));
}
};
debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
}
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 minAabb,maxAabb;
btVector3 colorvec(1,0,0);
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
minAabb -= contactThreshold;
maxAabb += contactThreshold;
colObj->getCustomDebugColor(color);
btVector3 minAabb2,maxAabb2;
if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
{
colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
minAabb2 -= contactThreshold;
maxAabb2 += contactThreshold;
minAabb.setMin(minAabb2);
maxAabb.setMax(maxAabb2);
debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
}
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 minAabb,maxAabb;
btVector3 colorvec = defaultColors.m_aabb;
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
minAabb -= contactThreshold;
maxAabb += contactThreshold;
m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
btVector3 minAabb2,maxAabb2;
if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
{
colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2);
minAabb2 -= contactThreshold;
maxAabb2 += contactThreshold;
minAabb.setMin(minAabb2);
maxAabb.setMax(maxAabb2);
}
m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
}
}
}
}
}
}
@ -1512,15 +1608,6 @@ void btCollisionWorld::debugDrawWorld()
void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer)
{
int i;
//serialize all collision objects
for (i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
if (colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT)
{
colObj->serializeSingleObject(serializer);
}
}
///keep track of shapes already serialized
btHashMap<btHashPtr,btCollisionShape*> serializedShapes;
@ -1537,6 +1624,15 @@ void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer)
}
}
//serialize all collision objects
for (i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
if ((colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT) || (colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK))
{
colObj->serializeSingleObject(serializer);
}
}
}

View file

@ -27,7 +27,7 @@ subject to the following restrictions:
* @section install_sec Installation
*
* @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
* You can download the Bullet Physics Library from the github repository: https://github.com/bulletphysics/bullet3/releases
*
* @subsection step2 Step 2: Building
* Bullet has multiple build systems, including premake, cmake and autotools. Premake and cmake support all platforms.
@ -412,10 +412,12 @@ public:
{
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
btScalar m_closestDistanceThreshold;
ContactResultCallback()
:m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
m_collisionFilterMask(btBroadphaseProxy::AllFilter)
m_collisionFilterMask(btBroadphaseProxy::AllFilter),
m_closestDistanceThreshold(0)
{
}

View file

@ -0,0 +1,190 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2014 Erwin Coumans http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_COLLISION_WORLD_IMPORTER_H
#define BT_COLLISION_WORLD_IMPORTER_H
#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btHashMap.h"
class btCollisionShape;
class btCollisionObject;
struct btBulletSerializedArrays;
struct ConstraintInput;
class btCollisionWorld;
struct btCollisionShapeData;
class btTriangleIndexVertexArray;
class btStridingMeshInterface;
struct btStridingMeshInterfaceData;
class btGImpactMeshShape;
class btOptimizedBvh;
struct btTriangleInfoMap;
class btBvhTriangleMeshShape;
class btPoint2PointConstraint;
class btHingeConstraint;
class btConeTwistConstraint;
class btGeneric6DofConstraint;
class btGeneric6DofSpringConstraint;
class btSliderConstraint;
class btGearConstraint;
struct btContactSolverInfo;
class btCollisionWorldImporter
{
protected:
btCollisionWorld* m_collisionWorld;
int m_verboseMode;
btAlignedObjectArray<btCollisionShape*> m_allocatedCollisionShapes;
btAlignedObjectArray<btCollisionObject*> m_allocatedRigidBodies;
btAlignedObjectArray<btOptimizedBvh*> m_allocatedBvhs;
btAlignedObjectArray<btTriangleInfoMap*> m_allocatedTriangleInfoMaps;
btAlignedObjectArray<btTriangleIndexVertexArray*> m_allocatedTriangleIndexArrays;
btAlignedObjectArray<btStridingMeshInterfaceData*> m_allocatedbtStridingMeshInterfaceDatas;
btAlignedObjectArray<btCollisionObject*> m_allocatedCollisionObjects;
btAlignedObjectArray<char*> m_allocatedNames;
btAlignedObjectArray<int*> m_indexArrays;
btAlignedObjectArray<short int*> m_shortIndexArrays;
btAlignedObjectArray<unsigned char*> m_charIndexArrays;
btAlignedObjectArray<btVector3FloatData*> m_floatVertexArrays;
btAlignedObjectArray<btVector3DoubleData*> m_doubleVertexArrays;
btHashMap<btHashPtr,btOptimizedBvh*> m_bvhMap;
btHashMap<btHashPtr,btTriangleInfoMap*> m_timMap;
btHashMap<btHashString,btCollisionShape*> m_nameShapeMap;
btHashMap<btHashString,btCollisionObject*> m_nameColObjMap;
btHashMap<btHashPtr,const char*> m_objectNameMap;
btHashMap<btHashPtr,btCollisionShape*> m_shapeMap;
btHashMap<btHashPtr,btCollisionObject*> m_bodyMap;
//methods
char* duplicateName(const char* name);
btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData );
public:
btCollisionWorldImporter(btCollisionWorld* world);
virtual ~btCollisionWorldImporter();
bool convertAllObjects( btBulletSerializedArrays* arrays);
///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load.
///make sure you don't use the dynamics world containing objects after you call this method
virtual void deleteAllData();
void setVerboseMode(int verboseMode)
{
m_verboseMode = verboseMode;
}
int getVerboseMode() const
{
return m_verboseMode;
}
// query for data
int getNumCollisionShapes() const;
btCollisionShape* getCollisionShapeByIndex(int index);
int getNumRigidBodies() const;
btCollisionObject* getRigidBodyByIndex(int index) const;
int getNumConstraints() const;
int getNumBvhs() const;
btOptimizedBvh* getBvhByIndex(int index) const;
int getNumTriangleInfoMaps() const;
btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const;
// queris involving named objects
btCollisionShape* getCollisionShapeByName(const char* name);
btCollisionObject* getCollisionObjectByName(const char* name);
const char* getNameForPointer(const void* ptr) const;
///those virtuals are called by load and can be overridden by the user
//bodies
virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName);
///shapes
virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
virtual btCollisionShape* createBoxShape(const btVector3& halfExtents);
virtual btCollisionShape* createSphereShape(btScalar radius);
virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height);
virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height);
virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height);
virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height);
virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height);
virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height);
virtual btCollisionShape* createConeShapeX(btScalar radius,btScalar height);
virtual btCollisionShape* createConeShapeY(btScalar radius,btScalar height);
virtual btCollisionShape* createConeShapeZ(btScalar radius,btScalar height);
virtual class btTriangleIndexVertexArray* createTriangleMeshContainer();
virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh);
virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh);
#ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh);
#endif //SUPPORT_GIMPACT_SHAPE_IMPORT
virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData);
virtual class btConvexHullShape* createConvexHullShape();
virtual class btCompoundShape* createCompoundShape();
virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape);
virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres);
virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData);
///acceleration and connectivity structures
virtual btOptimizedBvh* createOptimizedBvh();
virtual btTriangleInfoMap* createTriangleInfoMap();
};
#endif //BT_WORLD_IMPORTER_H

View file

@ -65,7 +65,13 @@ void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(const btCollisionO
const btCollisionShape* childShape = compoundShape->getChildShape(i);
btCollisionObjectWrapper childWrap(colObjWrap,childShape,colObjWrap->getCollisionObject(),colObjWrap->getWorldTransform(),-1,i);//wrong child trans, but unused (hopefully)
m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(&childWrap,otherObjWrap,m_sharedManifold);
m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(&childWrap,otherObjWrap,m_sharedManifold, BT_CONTACT_POINT_ALGORITHMS);
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithmsContact;
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithmsClosestPoints;
}
}
}
@ -123,13 +129,19 @@ public:
//backup
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;
btVector3 aabbMin0,aabbMax0;
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
btVector3 extendAabb(m_resultOut->m_closestPointDistanceThreshold, m_resultOut->m_closestPointDistanceThreshold, m_resultOut->m_closestPointDistanceThreshold);
aabbMin0 -= extendAabb;
aabbMax0 += extendAabb;
btVector3 aabbMin1, aabbMax1;
m_otherObjWrap->getCollisionShape()->getAabb(m_otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1);
if (gCompoundChildShapePairCallback)
@ -143,11 +155,21 @@ public:
btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap,childShape,m_compoundColObjWrap->getCollisionObject(),newChildWorldTrans,-1,index);
btCollisionAlgorithm* algo = 0;
//the contactpoint is still projected back using the original inverted worldtrans
if (!m_childCollisionAlgorithms[index])
m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(&compoundWrap,m_otherObjWrap,m_sharedManifold);
if (m_resultOut->m_closestPointDistanceThreshold > 0)
{
algo = m_dispatcher->findAlgorithm(&compoundWrap, m_otherObjWrap, 0, BT_CLOSEST_POINT_ALGORITHMS);
}
else
{
//the contactpoint is still projected back using the original inverted worldtrans
if (!m_childCollisionAlgorithms[index])
{
m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(&compoundWrap, m_otherObjWrap, m_sharedManifold, BT_CONTACT_POINT_ALGORITHMS);
}
algo = m_childCollisionAlgorithms[index];
}
const btCollisionObjectWrapper* tmpWrap = 0;
@ -164,8 +186,7 @@ public:
m_resultOut->setShapeIdentifiersB(-1,index);
}
m_childCollisionAlgorithms[index]->processCollision(&compoundWrap,m_otherObjWrap,m_dispatchInfo,m_resultOut);
algo->processCollision(&compoundWrap,m_otherObjWrap,m_dispatchInfo,m_resultOut);
#if 0
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
@ -229,8 +250,11 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
removeChildAlgorithms();
preallocateChildAlgorithms(body0Wrap,body1Wrap);
m_compoundShapeRevision = compoundShape->getUpdateRevision();
}
if (m_childCollisionAlgorithms.size()==0)
return;
const btDbvt* tree = compoundShape->getDynamicAabbTree();
//use a dynamic aabb tree to cull potential child-overlaps
@ -241,7 +265,7 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
///so we should add a 'refreshManifolds' in the btCollisionAlgorithm
{
int i;
btManifoldArray manifoldArray;
manifoldArray.resize(0);
for (i=0;i<m_childCollisionAlgorithms.size();i++)
{
if (m_childCollisionAlgorithms[i])
@ -268,10 +292,13 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
btTransform otherInCompoundSpace;
otherInCompoundSpace = colObjWrap->getWorldTransform().inverse() * otherObjWrap->getWorldTransform();
otherObjWrap->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax);
btVector3 extraExtends(resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold);
localAabbMin -= extraExtends;
localAabbMax += extraExtends;
const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
//process all children, that overlap with the given AABB bounds
tree->collideTV(tree->m_root,bounds,callback);
tree->collideTVNoStackAlloc(tree->m_root,bounds,stack2,callback);
} else
{
@ -288,10 +315,10 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
//iterate over all children, perform an AABB check inside ProcessChildShape
int numChildren = m_childCollisionAlgorithms.size();
int i;
btManifoldArray manifoldArray;
manifoldArray.resize(0);
const btCollisionShape* childShape = 0;
btTransform orgTrans;
btTransform orgInterpolationTrans;
btTransform newChildWorldTrans;
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
@ -301,8 +328,8 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap
{
childShape = compoundShape->getChildShape(i);
//if not longer overlapping, remove the algorithm
orgTrans = colObjWrap->getWorldTransform();
orgInterpolationTrans = colObjWrap->getWorldTransform();
orgTrans = colObjWrap->getWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(i);
newChildWorldTrans = orgTrans*childTrans ;

View file

@ -26,6 +26,7 @@ class btDispatcher;
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "btCollisionCreateFunc.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
class btDispatcher;
class btCollisionObject;
@ -36,6 +37,10 @@ extern btShapePairCallback gCompoundChildShapePairCallback;
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
btNodeStack stack2;
btManifoldArray manifoldArray;
protected:
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
bool m_isSwapped;

View file

@ -15,6 +15,7 @@ subject to the following restrictions:
*/
#include "btCompoundCompoundCollisionAlgorithm.h"
#include "LinearMath/btQuickprof.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
@ -27,10 +28,8 @@ subject to the following restrictions:
btShapePairCallback gCompoundCompoundChildShapePairCallback = 0;
btCompoundCompoundCollisionAlgorithm::btCompoundCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped)
:btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_sharedManifold(ci.m_manifold)
:btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,isSwapped)
{
m_ownsManifold = false;
void* ptr = btAlignedAlloc(sizeof(btHashedSimplePairCache),16);
m_childCollisionAlgorithmCache= new(ptr) btHashedSimplePairCache();
@ -114,10 +113,9 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide
btManifoldResult* resultOut,
btHashedSimplePairCache* childAlgorithmsCache,
btPersistentManifold* sharedManifold)
:m_compound0ColObjWrap(compound1ObjWrap),m_compound1ColObjWrap(compound0ObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
:m_numOverlapPairs(0),m_compound0ColObjWrap(compound1ObjWrap),m_compound1ColObjWrap(compound0ObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
m_childCollisionAlgorithmCache(childAlgorithmsCache),
m_sharedManifold(sharedManifold),
m_numOverlapPairs(0)
m_sharedManifold(sharedManifold)
{
}
@ -127,6 +125,7 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide
void Process(const btDbvtNode* leaf0,const btDbvtNode* leaf1)
{
BT_PROFILE("btCompoundCompoundLeafCallback::Process");
m_numOverlapPairs++;
@ -162,6 +161,11 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide
childShape0->getAabb(newChildWorldTrans0,aabbMin0,aabbMax0);
childShape1->getAabb(newChildWorldTrans1,aabbMin1,aabbMax1);
btVector3 thresholdVec(m_resultOut->m_closestPointDistanceThreshold, m_resultOut->m_closestPointDistanceThreshold, m_resultOut->m_closestPointDistanceThreshold);
aabbMin0 -= thresholdVec;
aabbMax0 += thresholdVec;
if (gCompoundCompoundChildShapePairCallback)
{
if (!gCompoundCompoundChildShapePairCallback(childShape0,childShape1))
@ -177,17 +181,24 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide
btSimplePair* pair = m_childCollisionAlgorithmCache->findPair(childIndex0,childIndex1);
btCollisionAlgorithm* colAlgo = 0;
if (pair)
if (m_resultOut->m_closestPointDistanceThreshold > 0)
{
colAlgo = (btCollisionAlgorithm*)pair->m_userPointer;
} else
colAlgo = m_dispatcher->findAlgorithm(&compoundWrap0, &compoundWrap1, 0, BT_CLOSEST_POINT_ALGORITHMS);
}
else
{
colAlgo = m_dispatcher->findAlgorithm(&compoundWrap0,&compoundWrap1,m_sharedManifold);
pair = m_childCollisionAlgorithmCache->addOverlappingPair(childIndex0,childIndex1);
btAssert(pair);
pair->m_userPointer = colAlgo;
if (pair)
{
colAlgo = (btCollisionAlgorithm*)pair->m_userPointer;
}
else
{
colAlgo = m_dispatcher->findAlgorithm(&compoundWrap0, &compoundWrap1, m_sharedManifold, BT_CONTACT_POINT_ALGORITHMS);
pair = m_childCollisionAlgorithmCache->addOverlappingPair(childIndex0, childIndex1);
btAssert(pair);
pair->m_userPointer = colAlgo;
}
}
btAssert(colAlgo);
@ -218,10 +229,12 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide
static DBVT_INLINE bool MyIntersect( const btDbvtAabbMm& a,
const btDbvtAabbMm& b, const btTransform& xform)
const btDbvtAabbMm& b, const btTransform& xform, btScalar distanceThreshold)
{
btVector3 newmin,newmax;
btTransformAabb(b.Mins(),b.Maxs(),0.f,xform,newmin,newmax);
newmin -= btVector3(distanceThreshold, distanceThreshold, distanceThreshold);
newmax += btVector3(distanceThreshold, distanceThreshold, distanceThreshold);
btDbvtAabbMm newb = btDbvtAabbMm::FromMM(newmin,newmax);
return Intersect(a,newb);
}
@ -230,7 +243,7 @@ static DBVT_INLINE bool MyIntersect( const btDbvtAabbMm& a,
static inline void MycollideTT( const btDbvtNode* root0,
const btDbvtNode* root1,
const btTransform& xform,
btCompoundCompoundLeafCallback* callback)
btCompoundCompoundLeafCallback* callback, btScalar distanceThreshold)
{
if(root0&&root1)
@ -242,7 +255,7 @@ static inline void MycollideTT( const btDbvtNode* root0,
stkStack[0]=btDbvt::sStkNN(root0,root1);
do {
btDbvt::sStkNN p=stkStack[--depth];
if(MyIntersect(p.a->volume,p.b->volume,xform))
if(MyIntersect(p.a->volume,p.b->volume,xform, distanceThreshold))
{
if(depth>treshold)
{
@ -292,12 +305,21 @@ void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionOb
const btCompoundShape* compoundShape0 = static_cast<const btCompoundShape*>(col0ObjWrap->getCollisionShape());
const btCompoundShape* compoundShape1 = static_cast<const btCompoundShape*>(col1ObjWrap->getCollisionShape());
const btDbvt* tree0 = compoundShape0->getDynamicAabbTree();
const btDbvt* tree1 = compoundShape1->getDynamicAabbTree();
if (!tree0 || !tree1)
{
return btCompoundCollisionAlgorithm::processCollision(body0Wrap,body1Wrap,dispatchInfo,resultOut);
}
///btCompoundShape might have changed:
////make sure the internal child collision algorithm caches are still valid
if ((compoundShape0->getUpdateRevision() != m_compoundShapeRevision0) || (compoundShape1->getUpdateRevision() != m_compoundShapeRevision1))
{
///clear all
removeChildAlgorithms();
m_compoundShapeRevision0 = compoundShape0->getUpdateRevision();
m_compoundShapeRevision1 = compoundShape1->getUpdateRevision();
}
@ -329,14 +351,13 @@ void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionOb
}
const btDbvt* tree0 = compoundShape0->getDynamicAabbTree();
const btDbvt* tree1 = compoundShape1->getDynamicAabbTree();
btCompoundCompoundLeafCallback callback(col0ObjWrap,col1ObjWrap,this->m_dispatcher,dispatchInfo,resultOut,this->m_childCollisionAlgorithmCache,m_sharedManifold);
const btTransform xform=col0ObjWrap->getWorldTransform().inverse()*col1ObjWrap->getWorldTransform();
MycollideTT(tree0->m_root,tree1->m_root,xform,&callback);
MycollideTT(tree0->m_root,tree1->m_root,xform,&callback, resultOut->m_closestPointDistanceThreshold);
//printf("#compound-compound child/leaf overlap =%d \r",callback.m_numOverlapPairs);
@ -376,7 +397,9 @@ void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionOb
newChildWorldTrans0 = orgTrans0*childTrans0 ;
childShape0->getAabb(newChildWorldTrans0,aabbMin0,aabbMax0);
}
btVector3 thresholdVec(resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold);
aabbMin0 -= thresholdVec;
aabbMax0 += thresholdVec;
{
btTransform orgInterpolationTrans1;
const btCollisionShape* childShape1 = 0;
@ -391,7 +414,8 @@ void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionOb
childShape1->getAabb(newChildWorldTrans1,aabbMin1,aabbMax1);
}
aabbMin1 -= thresholdVec;
aabbMax1 += thresholdVec;
if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
{

View file

@ -17,6 +17,8 @@ subject to the following restrictions:
#ifndef BT_COMPOUND_COMPOUND_COLLISION_ALGORITHM_H
#define BT_COMPOUND_COMPOUND_COLLISION_ALGORITHM_H
#include "btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
@ -35,15 +37,12 @@ typedef bool (*btShapePairCallback)(const btCollisionShape* pShape0, const btCol
extern btShapePairCallback gCompoundCompoundChildShapePairCallback;
/// btCompoundCompoundCollisionAlgorithm supports collision between two btCompoundCollisionShape shapes
class btCompoundCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
class btCompoundCompoundCollisionAlgorithm : public btCompoundCollisionAlgorithm
{
class btHashedSimplePairCache* m_childCollisionAlgorithmCache;
btSimplePairArray m_removePairs;
class btPersistentManifold* m_sharedManifold;
bool m_ownsManifold;
int m_compoundShapeRevision0;//to keep track of changes, so that childAlgorithm array can be updated
int m_compoundShapeRevision1;

View file

@ -47,8 +47,6 @@ subject to the following restrictions:
btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
{
m_numPerturbationIterations = 0;
m_minimumPointsPerturbationThreshold = 3;
m_simplexSolver = simplexSolver;
m_pdSolver = pdSolver;
}
@ -57,15 +55,13 @@ btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc()
{
}
btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
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),
m_manifoldPtr(mf),
m_lowLevelOfDetail(false),
m_numPerturbationIterations(numPerturbationIterations),
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
m_lowLevelOfDetail(false)
{
(void)body0Wrap;
(void)body1Wrap;

View file

@ -40,9 +40,6 @@ class btConvex2dConvex2dAlgorithm : public btActivatingCollisionAlgorithm
btPersistentManifold* m_manifoldPtr;
bool m_lowLevelOfDetail;
int m_numPerturbationIterations;
int m_minimumPointsPerturbationThreshold;
public:
btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);

View file

@ -15,6 +15,7 @@ subject to the following restrictions:
#include "btConvexConcaveCollisionAlgorithm.h"
#include "LinearMath/btQuickprof.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@ -79,6 +80,7 @@ void btConvexTriangleCallback::clearCache()
void btConvexTriangleCallback::processTriangle(btVector3* triangle,int
partId, int triangleIndex)
{
BT_PROFILE("btConvexTriangleCallback::processTriangle");
if (!TestTriangleAgainstAabb2(triangle, m_aabbMin, m_aabbMax))
{
@ -88,20 +90,19 @@ partId, int triangleIndex)
//just for debugging purposes
//printf("triangle %d",m_triangleCount++);
const btCollisionObject* ob = const_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher1 = m_dispatcher;
//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 ))
{
const btCollisionObject* ob = const_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());
btVector3 color(1,1,0);
btTransform& tr = ob->getWorldTransform();
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
@ -117,8 +118,16 @@ partId, int triangleIndex)
btCollisionObjectWrapper triObWrap(m_triBodyWrap,&tm,m_triBodyWrap->getCollisionObject(),m_triBodyWrap->getWorldTransform(),partId,triangleIndex);//correct transform?
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap,&triObWrap,m_manifoldPtr);
btCollisionAlgorithm* colAlgo = 0;
if (m_resultOut->m_closestPointDistanceThreshold > 0)
{
colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap, &triObWrap, 0, BT_CLOSEST_POINT_ALGORITHMS);
}
else
{
colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap, &triObWrap, m_manifoldPtr, BT_CONTACT_POINT_ALGORITHMS);
}
const btCollisionObjectWrapper* tmpWrap = 0;
if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
@ -169,7 +178,8 @@ void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTr
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;
btScalar extraMargin = collisionMarginTriangle+ resultOut->m_closestPointDistanceThreshold;
btVector3 extra(extraMargin,extraMargin,extraMargin);
m_aabbMax += extra;
@ -185,7 +195,7 @@ void btConvexConcaveCollisionAlgorithm::clearCache()
void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
BT_PROFILE("btConvexConcaveCollisionAlgorithm::processCollision");
const btCollisionObjectWrapper* convexBodyWrap = m_isSwapped ? body1Wrap : body0Wrap;
const btCollisionObjectWrapper* triBodyWrap = m_isSwapped ? body0Wrap : body1Wrap;
@ -266,6 +276,7 @@ btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObj
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
{
BT_PROFILE("processTriangle");
(void)partId;
(void)triangleIndex;
//do a swept sphere for now

View file

@ -26,14 +26,16 @@ class btDispatcher;
#include "btCollisionCreateFunc.h"
///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
class btConvexTriangleCallback : public btTriangleCallback
ATTRIBUTE_ALIGNED16(class) btConvexTriangleCallback : public btTriangleCallback
{
const btCollisionObjectWrapper* m_convexBodyWrap;
const btCollisionObjectWrapper* m_triBodyWrap;
btVector3 m_aabbMin;
btVector3 m_aabbMax ;
const btCollisionObjectWrapper* m_convexBodyWrap;
const btCollisionObjectWrapper* m_triBodyWrap;
btManifoldResult* m_resultOut;
btDispatcher* m_dispatcher;
@ -41,6 +43,8 @@ class btConvexTriangleCallback : public btTriangleCallback
btScalar m_collisionMarginTriangle;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
int m_triangleCount;
btPersistentManifold* m_manifoldPtr;
@ -75,17 +79,19 @@ int m_triangleCount;
/// btConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes.
class btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm
ATTRIBUTE_ALIGNED16(class) btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
bool m_isSwapped;
btConvexTriangleCallback m_btConvexTriangleCallback;
bool m_isSwapped;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
virtual ~btConvexConcaveCollisionAlgorithm();

View file

@ -179,11 +179,10 @@ static SIMD_FORCE_INLINE btScalar capsuleCapsuleDistance(
btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
btConvexConvexAlgorithm::CreateFunc::CreateFunc(btConvexPenetrationDepthSolver* pdSolver)
{
m_numPerturbationIterations = 0;
m_minimumPointsPerturbationThreshold = 3;
m_simplexSolver = simplexSolver;
m_pdSolver = pdSolver;
}
@ -191,9 +190,8 @@ btConvexConvexAlgorithm::CreateFunc::~CreateFunc()
{
}
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_simplexSolver(simplexSolver),
m_pdSolver(pdSolver),
m_ownManifold (false),
m_manifoldPtr(mf),
@ -349,8 +347,8 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper*
btGjkPairDetector::ClosestPointInput input;
btGjkPairDetector gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
btVoronoiSimplexSolver simplexSolver;
btGjkPairDetector gjkPairDetector( min0, min1, &simplexSolver, m_pdSolver );
//TODO: if (dispatchInfo.m_useContinuous)
gjkPairDetector.setMinkowskiA(min0);
gjkPairDetector.setMinkowskiB(min1);
@ -367,7 +365,7 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper*
// input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
//} else
//{
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold()+resultOut->m_closestPointDistanceThreshold;
// }
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
@ -503,9 +501,11 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper*
// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
worldVertsB1.resize(0);
btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0Wrap->getWorldTransform(),
body1Wrap->getWorldTransform(), minDist-threshold, threshold, *resultOut);
body1Wrap->getWorldTransform(), minDist-threshold, threshold, worldVertsB1,worldVertsB2,
*resultOut);
}
if (m_ownManifold)
@ -568,8 +568,9 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper*
if (foundSepAxis)
{
worldVertsB2.resize(0);
btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(),
body0Wrap->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut);
body0Wrap->getWorldTransform(), vertices, worldVertsB2,minDist-threshold, maxDist, *resultOut);
}

View file

@ -24,6 +24,7 @@ subject to the following restrictions:
#include "btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h"
#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h"
class btConvexPenetrationDepthSolver;
@ -42,9 +43,10 @@ class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
#ifdef USE_SEPDISTANCE_UTIL2
btConvexSeparatingDistanceUtil m_sepDistance;
#endif
btSimplexSolverInterface* m_simplexSolver;
btConvexPenetrationDepthSolver* m_pdSolver;
btVertexArray worldVertsB1;
btVertexArray worldVertsB2;
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
@ -59,7 +61,7 @@ class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
public:
btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
virtual ~btConvexConvexAlgorithm();
@ -87,18 +89,17 @@ public:
{
btConvexPenetrationDepthSolver* m_pdSolver;
btSimplexSolverInterface* m_simplexSolver;
int m_numPerturbationIterations;
int m_minimumPointsPerturbationThreshold;
CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
CreateFunc(btConvexPenetrationDepthSolver* pdSolver);
virtual ~CreateFunc();
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,body0Wrap,body1Wrap,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
};

View file

@ -44,9 +44,7 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
//btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool)
{
void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16);
m_simplexSolver = new (mem)btVoronoiSimplexSolver();
void* mem = NULL;
if (constructionInfo.m_useEpaPenetrationAlgorithm)
{
mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
@ -59,7 +57,7 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
//default CreationFunctions, filling the m_doubleDispatch table
mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver);
m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_pdSolver);
mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc;
mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
@ -105,12 +103,12 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
int maxSize = sizeof(btConvexConvexAlgorithm);
int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
int sl = sizeof(btConvexSeparatingDistanceUtil);
sl = sizeof(btGjkPairDetector);
int maxSize4 = sizeof(btCompoundCompoundCollisionAlgorithm);
int collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize);
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
if (constructionInfo.m_persistentManifoldPool)
{
@ -123,6 +121,7 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize);
}
collisionAlgorithmMaxElementSize = (collisionAlgorithmMaxElementSize+16)&0xffffffffffff0;
if (constructionInfo.m_collisionAlgorithmPool)
{
m_ownsCollisionAlgorithmPool = false;
@ -192,9 +191,6 @@ btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
m_planeConvexCF->~btCollisionAlgorithmCreateFunc();
btAlignedFree( m_planeConvexCF);
m_simplexSolver->~btVoronoiSimplexSolver();
btAlignedFree(m_simplexSolver);
m_pdSolver->~btConvexPenetrationDepthSolver();
btAlignedFree(m_pdSolver);
@ -202,6 +198,86 @@ btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
}
btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1)
{
if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
{
return m_sphereSphereCF;
}
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
{
return m_sphereBoxCF;
}
if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
{
return m_boxSphereCF;
}
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == TRIANGLE_SHAPE_PROXYTYPE))
{
return m_sphereTriangleCF;
}
if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE))
{
return m_triangleSphereCF;
}
if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE))
{
return m_convexPlaneCF;
}
if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE))
{
return m_planeConvexCF;
}
if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
{
return m_convexConvexCreateFunc;
}
if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
{
return m_convexConcaveCreateFunc;
}
if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
{
return m_swappedConvexConcaveCreateFunc;
}
if (btBroadphaseProxy::isCompound(proxyType0) && btBroadphaseProxy::isCompound(proxyType1))
{
return m_compoundCompoundCreateFunc;
}
if (btBroadphaseProxy::isCompound(proxyType0))
{
return m_compoundCreateFunc;
}
else
{
if (btBroadphaseProxy::isCompound(proxyType1))
{
return m_swappedCompoundCreateFunc;
}
}
//failed to find an algorithm
return m_emptyCreateFunc;
}
btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
{

View file

@ -60,8 +60,7 @@ protected:
btPoolAllocator* m_collisionAlgorithmPool;
bool m_ownsCollisionAlgorithmPool;
//default simplex/penetration depth solvers
btVoronoiSimplexSolver* m_simplexSolver;
//default penetration depth solver
btConvexPenetrationDepthSolver* m_pdSolver;
//default CreationFunctions, filling the m_doubleDispatch table
@ -102,14 +101,10 @@ public:
}
virtual btVoronoiSimplexSolver* getSimplexSolver()
{
return m_simplexSolver;
}
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
virtual btCollisionAlgorithmCreateFunc* getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1);
///Use this method to allow to generate multiple contact points between at once, between two objects using the generic convex-convex algorithm.
///By default, this feature is disabled for best performance.
///@param numPerturbationIterations controls the number of collision queries. Set it to zero to disable the feature.

View file

@ -28,9 +28,7 @@ int gFindSimplePairs =0;
btHashedSimplePairCache::btHashedSimplePairCache():
m_blockedForChanges(false)
{
btHashedSimplePairCache::btHashedSimplePairCache() {
int initialAllocatedSize= 2;
m_overlappingPairArray.reserve(initialAllocatedSize);
growTables();

View file

@ -56,8 +56,6 @@ class btHashedSimplePairCache
{
btSimplePairArray m_overlappingPairArray;
bool m_blockedForChanges;
protected:

View file

@ -193,7 +193,7 @@ struct btConnectivityProcessor : public btTriangleCallback
btScalar len2 = calculatedEdge.length2();
btScalar correctedAngle(0);
btVector3 calculatedNormalB = normalA;
//btVector3 calculatedNormalB = normalA;
bool isConvex = false;
if (len2<m_triangleInfoMap->m_planarEpsilon)
@ -213,10 +213,6 @@ struct btConnectivityProcessor : public btTriangleCallback
isConvex = (dotA<0.);
correctedAngle = isConvex ? ang4 : -ang4;
btQuaternion orn2(calculatedEdge,-correctedAngle);
calculatedNormalB = btMatrix3x3(orn2)*normalA;
}

View file

@ -24,10 +24,9 @@ ContactAddedCallback gContactAddedCallback=0;
///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
inline btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1)
btScalar btManifoldResult::calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1)
{
btScalar friction = body0->getRollingFriction() * body1->getRollingFriction();
btScalar friction = body0->getRollingFriction() * body1->getFriction() + body1->getRollingFriction() * body0->getFriction();
const btScalar MAX_FRICTION = btScalar(10.);
if (friction < -MAX_FRICTION)
@ -38,6 +37,17 @@ inline btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,
}
btScalar btManifoldResult::calculateCombinedSpinningFriction(const btCollisionObject* body0,const btCollisionObject* body1)
{
btScalar friction = body0->getSpinningFriction() * body1->getFriction() + body1->getSpinningFriction() * body0->getFriction();
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)
@ -58,6 +68,22 @@ btScalar btManifoldResult::calculateCombinedRestitution(const btCollisionObject*
return body0->getRestitution() * body1->getRestitution();
}
btScalar btManifoldResult::calculateCombinedContactDamping(const btCollisionObject* body0,const btCollisionObject* body1)
{
return body0->getContactDamping() + body1->getContactDamping();
}
btScalar btManifoldResult::calculateCombinedContactStiffness(const btCollisionObject* body0,const btCollisionObject* body1)
{
btScalar s0 = body0->getContactStiffness();
btScalar s1 = body1->getContactStiffness();
btScalar tmp0 = btScalar(1)/s0;
btScalar tmp1 = btScalar(1)/s1;
btScalar combinedStiffness = btScalar(1) / (tmp0+tmp1);
return combinedStiffness;
}
btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
@ -70,6 +96,7 @@ btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap,con
m_index0(-1),
m_index1(-1)
#endif //DEBUG_PART_INDEX
, m_closestPointDistanceThreshold(0)
{
}
@ -109,6 +136,16 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
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());
newPt.m_combinedSpinningFriction = calculateCombinedSpinningFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
if ( (m_body0Wrap->getCollisionObject()->getCollisionFlags()& btCollisionObject::CF_HAS_CONTACT_STIFFNESS_DAMPING) ||
(m_body1Wrap->getCollisionObject()->getCollisionFlags()& btCollisionObject::CF_HAS_CONTACT_STIFFNESS_DAMPING))
{
newPt.m_combinedContactDamping1 = calculateCombinedContactDamping(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
newPt.m_combinedContactStiffness1 = calculateCombinedContactStiffness(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
newPt.m_contactPointFlags |= BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING;
}
btPlaneSpace1(newPt.m_normalWorldOnB,newPt.m_lateralFrictionDir1,newPt.m_lateralFrictionDir2);

View file

@ -53,13 +53,15 @@ protected:
public:
btManifoldResult()
#ifdef DEBUG_PART_INDEX
:
#ifdef DEBUG_PART_INDEX
m_partId0(-1),
m_partId1(-1),
m_index0(-1),
m_index1(-1)
#endif //DEBUG_PART_INDEX
m_closestPointDistanceThreshold(0)
{
}
@ -142,9 +144,15 @@ public:
return m_body1Wrap->getCollisionObject();
}
btScalar m_closestPointDistanceThreshold;
/// 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);
static btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1);
static btScalar calculateCombinedSpinningFriction(const btCollisionObject* body0,const btCollisionObject* body1);
static btScalar calculateCombinedContactDamping(const btCollisionObject* body0,const btCollisionObject* body1);
static btScalar calculateCombinedContactStiffness(const btCollisionObject* body0,const btCollisionObject* body1);
};
#endif //BT_MANIFOLD_RESULT_H

View file

@ -12,6 +12,7 @@ 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.
*/
#define CLEAR_MANIFOLD 1
#include "btSphereSphereCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
@ -62,7 +63,7 @@ void btSphereSphereCollisionAlgorithm::processCollision (const btCollisionObject
#endif
///iff distance positive, don't generate a new contact
if ( len > (radius0+radius1))
if ( len > (radius0+radius1+resultOut->m_closestPointDistanceThreshold))
{
#ifndef CLEAR_MANIFOLD
resultOut->refreshContactPoints();

View file

@ -56,7 +56,7 @@ void btSphereTriangleCollisionAlgorithm::processCollision (const btCollisionObje
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->setPersistentManifold(m_manifoldPtr);
SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold());
SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold()+ resultOut->m_closestPointDistanceThreshold);
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);///@todo: tighter bounds

View file

@ -245,16 +245,18 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
btStridingMeshInterface* m_meshInterface;
btTriangleCallback* m_callback;
btVector3 m_triangle[3];
int m_numOverlap;
MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
:m_meshInterface(meshInterface),
m_callback(callback)
m_callback(callback),
m_numOverlap(0)
{
}
virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
{
m_numOverlap++;
const unsigned char *vertexbase;
int numverts;
PHY_ScalarType type;
@ -322,7 +324,6 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
#endif//DISABLE_BVH

View file

@ -39,7 +39,11 @@ ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape
bool m_useQuantizedAabbCompression;
bool m_ownsBvh;
#ifdef __clang__
bool m_pad[11] __attribute__((unused));////need padding due to alignment
#else
bool m_pad[11];////need padding due to alignment
#endif
public:

View file

@ -117,6 +117,7 @@ public:
///fills the dataBuffer and returns the struct name (and 0 on failure)
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
SIMD_FORCE_INLINE void deSerializeFloat(struct btCapsuleShapeData* dataBuffer);
};
@ -181,4 +182,13 @@ SIMD_FORCE_INLINE const char* btCapsuleShape::serialize(void* dataBuffer, btSeri
return "btCapsuleShapeData";
}
SIMD_FORCE_INLINE void btCapsuleShape::deSerializeFloat(btCapsuleShapeData* dataBuffer)
{
m_implicitShapeDimensions.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_implicitShapeDimensions);
m_collisionMargin = dataBuffer->m_convexInternalShapeData.m_collisionMargin;
m_localScaling.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_localScaling);
//it is best to already pre-allocate the matching btCapsuleShape*(X/Z) version to match m_upAxis
m_upAxis = dataBuffer->m_upAxis;
}
#endif //BT_CAPSULE_SHAPE_H

View file

@ -29,12 +29,13 @@ ATTRIBUTE_ALIGNED16(class) btCollisionShape
protected:
int m_shapeType;
void* m_userPointer;
int m_userIndex;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0)
btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0), m_userIndex(-1)
{
}
@ -47,7 +48,7 @@ public:
virtual void getBoundingSphere(btVector3& center,btScalar& radius) const;
///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations.
///getAngularMotionDisc returns the maximum radius needed for Conservative Advancement to handle time-of-impact with rotations.
virtual btScalar getAngularMotionDisc() const;
virtual btScalar getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const;
@ -130,6 +131,16 @@ public:
{
return m_userPointer;
}
void setUserIndex(int index)
{
m_userIndex = index;
}
int getUserIndex() const
{
return m_userIndex;
}
virtual int calculateSerializeBufferSize() const;

View file

@ -18,7 +18,7 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
#include "LinearMath/btSerializer.h"
btCompoundShape::btCompoundShape(bool enableDynamicAabbTree)
btCompoundShape::btCompoundShape(bool enableDynamicAabbTree, const int initialChildCapacity)
: m_localAabbMin(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)),
m_localAabbMax(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)),
m_dynamicAabbTree(0),
@ -34,6 +34,8 @@ m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
m_dynamicAabbTree = new(mem) btDbvt();
btAssert(mem==m_dynamicAabbTree);
}
m_children.reserve(initialChildCapacity);
}
@ -77,8 +79,8 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
if (m_dynamicAabbTree)
{
const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
int index = m_children.size();
child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
size_t index = m_children.size();
child.m_node = m_dynamicAabbTree->insert(bounds,reinterpret_cast<void*>(index) );
}
m_children.push_back(child);
@ -312,7 +314,8 @@ void btCompoundShape::createAabbTreeFromChildren()
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);
size_t index2 = index;
child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast<void*>(index2) );
}
}
}

View file

@ -53,6 +53,7 @@ SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompou
/// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape)
ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape
{
protected:
btAlignedObjectArray<btCompoundShapeChild> m_children;
btVector3 m_localAabbMin;
btVector3 m_localAabbMax;
@ -64,13 +65,12 @@ ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape
btScalar m_collisionMargin;
protected:
btVector3 m_localScaling;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
btCompoundShape(bool enableDynamicAabbTree = true);
explicit btCompoundShape(bool enableDynamicAabbTree = true, const int initialChildCapacity = 0);
virtual ~btCompoundShape();

View file

@ -43,6 +43,15 @@ public:
btScalar getRadius() const { return m_radius;}
btScalar getHeight() const { return m_height;}
void setRadius(const btScalar radius)
{
m_radius = radius;
}
void setHeight(const btScalar height)
{
m_height = height;
}
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const
{

View file

@ -22,6 +22,8 @@ subject to the following restrictions:
#include "LinearMath/btQuaternion.h"
#include "LinearMath/btSerializer.h"
#include "btConvexPolyhedron.h"
#include "LinearMath/btConvexHullComputer.h"
btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexAabbCachingShape ()
{
@ -121,10 +123,17 @@ btVector3 btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const
}
void btConvexHullShape::optimizeConvexHull()
{
btConvexHullComputer conv;
conv.compute(&m_unscaledPoints[0].getX(), sizeof(btVector3),m_unscaledPoints.size(),0.f,0.f);
int numVerts = conv.vertices.size();
m_unscaledPoints.resize(0);
for (int i=0;i<numVerts;i++)
{
m_unscaledPoints.push_back(conv.vertices[i]);
}
}

View file

@ -55,8 +55,7 @@ public:
return getUnscaledPoints();
}
void optimizeConvexHull();
SIMD_FORCE_INLINE btVector3 getScaledPoint(int i) const
{

View file

@ -21,6 +21,7 @@ subject to the following restrictions:
#include "btConvexPolyhedron.h"
#include "LinearMath/btHashMap.h"
btConvexPolyhedron::btConvexPolyhedron()
{
@ -33,7 +34,7 @@ btConvexPolyhedron::~btConvexPolyhedron()
inline bool IsAlmostZero(const btVector3& v)
{
if(fabsf(v.x())>1e-6 || fabsf(v.y())>1e-6 || fabsf(v.z())>1e-6) return false;
if(btFabs(v.x())>1e-6 || btFabs(v.y())>1e-6 || btFabs(v.z())>1e-6) return false;
return true;
}

View file

@ -48,7 +48,7 @@ btConvexShape::~btConvexShape()
}
void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const
void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max, btVector3& witnesPtMin,btVector3& witnesPtMax) const
{
btVector3 localAxis = dir*trans.getBasis();
btVector3 vtx1 = trans(localGetSupportingVertex(localAxis));
@ -56,12 +56,16 @@ void btConvexShape::project(const btTransform& trans, const btVector3& dir, btSc
min = vtx1.dot(dir);
max = vtx2.dot(dir);
witnesPtMax = vtx2;
witnesPtMin = vtx1;
if(min>max)
{
btScalar tmp = min;
min = max;
max = tmp;
witnesPtMax = vtx1;
witnesPtMin = vtx2;
}
}

View file

@ -52,7 +52,8 @@ public:
btScalar getMarginNonVirtual () const;
void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
virtual void project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const;
virtual void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const;
//notice that the vectors should be unit length

View file

@ -59,15 +59,13 @@ PHY_ScalarType hdt, bool flipQuadEdges
)
{
// validation
btAssert(heightStickWidth > 1 && "bad width");
btAssert(heightStickLength > 1 && "bad length");
btAssert(heightfieldData && "null heightfield data");
btAssert(heightStickWidth > 1);// && "bad width");
btAssert(heightStickLength > 1);// && "bad length");
btAssert(heightfieldData);// && "null heightfield data");
// btAssert(heightScale) -- do we care? Trust caller here
btAssert(minHeight <= maxHeight && "bad min/max height");
btAssert(upAxis >= 0 && upAxis < 3 &&
"bad upAxis--should be in range [0,2]");
btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT &&
"Bad height data type enum");
btAssert(minHeight <= maxHeight);// && "bad min/max height");
btAssert(upAxis >= 0 && upAxis < 3);// && "bad upAxis--should be in range [0,2]");
btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT);// && "Bad height data type enum");
// initialize member variables
m_shapeType = TERRAIN_SHAPE_PROXYTYPE;
@ -110,7 +108,7 @@ PHY_ScalarType hdt, bool flipQuadEdges
default:
{
//need to get valid m_upAxis
btAssert(0 && "Bad m_upAxis");
btAssert(0);// && "Bad m_upAxis");
}
}
@ -365,14 +363,15 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
{
//first triangle
getVertex(x,j,vertices[0]);
getVertex(x+1,j,vertices[1]);
getVertex(x+1,j+1,vertices[2]);
getVertex(x, j + 1, vertices[1]);
getVertex(x + 1, j + 1, vertices[2]);
callback->processTriangle(vertices,x,j);
//second triangle
// getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
getVertex(x+1,j+1,vertices[1]);
getVertex(x,j+1,vertices[2]);
callback->processTriangle(vertices,x,j);
getVertex(x + 1, j, vertices[2]);
callback->processTriangle(vertices, x, j);
} else
{
//first triangle

View file

@ -75,7 +75,7 @@ btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScala
int inner_count = MIN( numSpheres - k, 128 );
for( long i = 0; i < inner_count; i++ )
{
temp[i] = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
temp[i] = (*pos)*m_localScaling +vec*m_localScaling*(*rad) - vec * getMargin();
pos++;
rad++;
}
@ -113,7 +113,7 @@ btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScala
int inner_count = MIN( numSpheres - k, 128 );
for( long i = 0; i < inner_count; i++ )
{
temp[i] = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
temp[i] = (*pos)*m_localScaling +vec*m_localScaling*(*rad) - vec * getMargin();
pos++;
rad++;
}

View file

@ -25,7 +25,6 @@ subject to the following restrictions:
ATTRIBUTE_ALIGNED16(class) btMultimaterialTriangleMeshShape : public btBvhTriangleMeshShape
{
btAlignedObjectArray <btMaterial*> m_materialList;
int ** m_triangleMaterials;
public:

View file

@ -21,7 +21,7 @@ subject to the following restrictions:
btStaticPlaneShape::btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
: btConcaveShape (), m_planeNormal(planeNormal.normalized()),
m_planeConstant(planeConstant),
m_localScaling(btScalar(0.),btScalar(0.),btScalar(0.))
m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
{
m_shapeType = STATIC_PLANE_PROXYTYPE;
// btAssert( btFuzzyZero(m_planeNormal.length() - btScalar(1.)) );

View file

@ -75,6 +75,13 @@ void btTriangleMesh::addIndex(int index)
}
}
void btTriangleMesh::addTriangleIndices(int index1, int index2, int index3 )
{
m_indexedMeshes[0].m_numTriangles++;
addIndex( index1 );
addIndex( index2 );
addIndex( index3 );
}
int btTriangleMesh::findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices)
{

View file

@ -53,6 +53,9 @@ class btTriangleMesh : public btTriangleIndexVertexArray
///In general it is better to directly use btTriangleIndexVertexArray instead.
void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2, bool removeDuplicateVertices=false);
///Add a triangle using its indices. Make sure the indices are pointing within the vertices array, so add the vertices first (and to be sure, avoid removal of duplicate vertices)
void addTriangleIndices(int index1, int index2, int index3 );
int getNumTriangles() const;
virtual void preallocateVertices(int numverts);

View file

@ -1,746 +0,0 @@
# Doxyfile 1.2.4
# This file describes the settings to be used by doxygen for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# 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 Continuous Collision Detection Library"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY =
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian,
# Polish, Portuguese and Slovene.
OUTPUT_LANGUAGE = English
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = YES
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these class will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = NO
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
STRIP_FROM_PATH =
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a class diagram (in Html and LaTeX) for classes with base or
# super classes. Setting the tag to NO turns the diagrams off.
CLASS_DIAGRAMS = YES
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower case letters. If set to YES upper case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# users are adviced to set this option to NO.
CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like the Qt-style comments (thus requiring an
# explict @brief command for a brief description.
JAVADOC_AUTOBRIEF = YES
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# reimplements.
INHERIT_DOCS = YES
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 8
# The ENABLE_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
ALIASES =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = .
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
FILE_PATTERNS = *.h *.cpp *.c
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
EXCLUDE_PATTERNS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
INPUT_FILTER =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse.
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = NO
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
# This tag can be used to set the number of enum values (range [1..20])
# that doxygen will group on one line in the generated HTML documentation.
ENUM_VALUES_PER_LINE = 4
# If the GENERATE_TREEVIEW tag is set to YES, a side pannel will be
# generated containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript and frames is required (for instance Netscape 4.0+
# or Internet explorer 4.0+).
GENERATE_TREEVIEW = NO
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimised for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using a WORD or other.
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assigments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation. Warning: This feature
# is still experimental and very incomplete.
GENERATE_XML = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
# 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.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH = ../../generic/extern
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
# 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.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED =
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tagfiles.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = YES
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
# YES then doxygen will generate a graph for each documented file showing
# the direct and indirect include dependencies of the file with other
# documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
# YES then doxygen will generate a graph for each documented header file showing
# the documented files that directly or indirectly include this file
INCLUDED_BY_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
DOT_PATH =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
# The CGI_NAME tag should be the name of the CGI script that
# starts the search engine (doxysearch) with the correct parameters.
# A script with this name will be generated by doxygen.
CGI_NAME = search.cgi
# The CGI_URL tag should be the absolute URL to the directory where the
# cgi binaries are located. See the documentation of your http daemon for
# details.
CGI_URL =
# The DOC_URL tag should be the absolute URL to the directory where the
# documentation is located. If left blank the absolute path to the
# documentation, with file:// prepended to it, will be used.
DOC_URL =
# The DOC_ABSPATH tag should be the absolute path to the directory where the
# documentation is located. If left blank the directory on the local machine
# will be used.
DOC_ABSPATH =
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
# is installed.
BIN_ABSPATH = c:\program files\doxygen\bin
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
# documentation generated for other projects. This allows doxysearch to search
# the documentation for these projects as well.
EXT_DOC_PATHS =

View file

@ -122,7 +122,7 @@ protected:
checkManifold(body0Wrap,body1Wrap);
btCollisionAlgorithm * convex_algorithm = m_dispatcher->findAlgorithm(
body0Wrap,body1Wrap,getLastManifold());
body0Wrap,body1Wrap,getLastManifold(), BT_CONTACT_POINT_ALGORITHMS);
return convex_algorithm ;
}

View file

@ -23,6 +23,59 @@ subject to the following restrictions:
#include "btGImpactMassUtil.h"
btGImpactMeshShapePart::btGImpactMeshShapePart( btStridingMeshInterface * meshInterface, int part )
{
// moved from .h to .cpp because of conditional compilation
// (The setting of BT_THREADSAFE may differ between various cpp files, so it is best to
// avoid using it in h files)
m_primitive_manager.m_meshInterface = meshInterface;
m_primitive_manager.m_part = part;
m_box_set.setPrimitiveManager( &m_primitive_manager );
#if BT_THREADSAFE
// If threadsafe is requested, this object uses a different lock/unlock
// model with the btStridingMeshInterface -- lock once when the object is constructed
// and unlock once in the destructor.
// The other way of locking and unlocking for each collision check in the narrowphase
// is not threadsafe. Note these are not thread-locks, they are calls to the meshInterface's
// getLockedReadOnlyVertexIndexBase virtual function, which by default just returns a couple of
// pointers. In theory a client could override the lock function to do all sorts of
// things like reading data from GPU memory, or decompressing data on the fly, but such things
// do not seem all that likely or useful, given the performance cost.
m_primitive_manager.lock();
#endif
}
btGImpactMeshShapePart::~btGImpactMeshShapePart()
{
// moved from .h to .cpp because of conditional compilation
#if BT_THREADSAFE
m_primitive_manager.unlock();
#endif
}
void btGImpactMeshShapePart::lockChildShapes() const
{
// moved from .h to .cpp because of conditional compilation
#if ! BT_THREADSAFE
// called in the narrowphase -- not threadsafe!
void * dummy = (void*) ( m_box_set.getPrimitiveManager() );
TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>( dummy );
dummymanager->lock();
#endif
}
void btGImpactMeshShapePart::unlockChildShapes() const
{
// moved from .h to .cpp because of conditional compilation
#if ! BT_THREADSAFE
// called in the narrowphase -- not threadsafe!
void * dummy = (void*) ( m_box_set.getPrimitiveManager() );
TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>( dummy );
dummymanager->unlock();
#endif
}
#define CALC_EXACT_INERTIA 1

View file

@ -722,17 +722,8 @@ public:
m_box_set.setPrimitiveManager(&m_primitive_manager);
}
btGImpactMeshShapePart(btStridingMeshInterface * meshInterface, int part)
{
m_primitive_manager.m_meshInterface = meshInterface;
m_primitive_manager.m_part = part;
m_box_set.setPrimitiveManager(&m_primitive_manager);
}
virtual ~btGImpactMeshShapePart()
{
}
btGImpactMeshShapePart( btStridingMeshInterface * meshInterface, int part );
virtual ~btGImpactMeshShapePart();
//! if true, then its children must get transforms.
virtual bool childrenHasTransform() const
@ -742,19 +733,8 @@ public:
//! call when reading child shapes
virtual void lockChildShapes() const
{
void * dummy = (void*)(m_box_set.getPrimitiveManager());
TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
dummymanager->lock();
}
virtual void unlockChildShapes() const
{
void * dummy = (void*)(m_box_set.getPrimitiveManager());
TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
dummymanager->unlock();
}
virtual void lockChildShapes() const;
virtual void unlockChildShapes() const;
//! Gets the number of children
virtual int getNumChildShapes() const

View file

@ -404,12 +404,12 @@ SIMD_FORCE_INLINE void SEGMENT_COLLISION(
CLASS_POINT & vPointA,
CLASS_POINT & vPointB)
{
CLASS_POINT _AD,_BD,_N;
CLASS_POINT _AD,_BD,n;
vec4f _M;//plane
VEC_DIFF(_AD,vA2,vA1);
VEC_DIFF(_BD,vB2,vB1);
VEC_CROSS(_N,_AD,_BD);
GREAL _tp = VEC_DOT(_N,_N);
VEC_CROSS(n,_AD,_BD);
GREAL _tp = VEC_DOT(n,n);
if(_tp<G_EPSILON)//ARE PARALELE
{
//project B over A
@ -424,10 +424,10 @@ SIMD_FORCE_INLINE void SEGMENT_COLLISION(
_M[2] = VEC_DOT(vA1,_AD);
_M[3] = VEC_DOT(vA2,_AD);
//mid points
_N[0] = (_M[0]+_M[1])*0.5f;
_N[1] = (_M[2]+_M[3])*0.5f;
n[0] = (_M[0]+_M[1])*0.5f;
n[1] = (_M[2]+_M[3])*0.5f;
if(_N[0]<_N[1])
if(n[0]<n[1])
{
if(_M[1]<_M[2])
{
@ -467,7 +467,7 @@ SIMD_FORCE_INLINE void SEGMENT_COLLISION(
}
VEC_CROSS(_M,_N,_BD);
VEC_CROSS(_M,n,_BD);
_M[3] = VEC_DOT(_M,vB1);
LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,btScalar(0), btScalar(1));

View file

@ -0,0 +1,369 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2014 Erwin Coumans http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H
#define BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H
#include "LinearMath/btTransform.h" // Note that btVector3 might be double precision...
#include "btGjkEpa3.h"
#include "btGjkCollisionDescription.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
template <typename btConvexTemplate>
bool btGjkEpaCalcPenDepth(const btConvexTemplate& a, const btConvexTemplate& b,
const btGjkCollisionDescription& colDesc,
btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB)
{
(void)v;
// const btScalar radialmargin(btScalar(0.));
btVector3 guessVector(b.getWorldTransform().getOrigin()-a.getWorldTransform().getOrigin());//?? why not use the GJK input?
btGjkEpaSolver3::sResults results;
if(btGjkEpaSolver3_Penetration(a,b,guessVector,results))
{
// debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
//resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
wWitnessOnA = results.witnesses[0];
wWitnessOnB = results.witnesses[1];
v = results.normal;
return true;
} else
{
if(btGjkEpaSolver3_Distance(a,b,guessVector,results))
{
wWitnessOnA = results.witnesses[0];
wWitnessOnB = results.witnesses[1];
v = results.normal;
return false;
}
}
return false;
}
template <typename btConvexTemplate, typename btGjkDistanceTemplate>
int btComputeGjkEpaPenetration(const btConvexTemplate& a, const btConvexTemplate& b, const btGjkCollisionDescription& colDesc, btVoronoiSimplexSolver& simplexSolver, btGjkDistanceTemplate* distInfo)
{
bool m_catchDegeneracies = true;
btScalar m_cachedSeparatingDistance = 0.f;
btScalar distance=btScalar(0.);
btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
btVector3 pointOnA,pointOnB;
btTransform localTransA = a.getWorldTransform();
btTransform localTransB = b.getWorldTransform();
btScalar marginA = a.getMargin();
btScalar marginB = b.getMargin();
int m_curIter = 0;
int gGjkMaxIter = colDesc.m_maxGjkIterations;//this is to catch invalid input, perhaps check for #NaN?
btVector3 m_cachedSeparatingAxis = colDesc.m_firstDir;
bool isValid = false;
bool checkSimplex = false;
bool checkPenetration = true;
int m_degenerateSimplex = 0;
int m_lastUsedMethod = -1;
{
btScalar squaredDistance = BT_LARGE_FLOAT;
btScalar delta = btScalar(0.);
btScalar margin = marginA + marginB;
simplexSolver.reset();
for ( ; ; )
//while (true)
{
btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* localTransA.getBasis();
btVector3 seperatingAxisInB = m_cachedSeparatingAxis* localTransB.getBasis();
btVector3 pInA = a.getLocalSupportWithoutMargin(seperatingAxisInA);
btVector3 qInB = b.getLocalSupportWithoutMargin(seperatingAxisInB);
btVector3 pWorld = localTransA(pInA);
btVector3 qWorld = localTransB(qInB);
btVector3 w = pWorld - qWorld;
delta = m_cachedSeparatingAxis.dot(w);
// potential exit, they don't overlap
if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * colDesc.m_maximumDistanceSquared))
{
m_degenerateSimplex = 10;
checkSimplex=true;
//checkPenetration = false;
break;
}
//exit 0: the new point is already in the simplex, or we didn't come any closer
if (simplexSolver.inSimplex(w))
{
m_degenerateSimplex = 1;
checkSimplex = true;
break;
}
// are we getting any closer ?
btScalar f0 = squaredDistance - delta;
btScalar f1 = squaredDistance * colDesc.m_gjkRelError2;
if (f0 <= f1)
{
if (f0 <= btScalar(0.))
{
m_degenerateSimplex = 2;
} else
{
m_degenerateSimplex = 11;
}
checkSimplex = true;
break;
}
//add current vertex to simplex
simplexSolver.addVertex(w, pWorld, qWorld);
btVector3 newCachedSeparatingAxis;
//calculate the closest point to the origin (update vector v)
if (!simplexSolver.closest(newCachedSeparatingAxis))
{
m_degenerateSimplex = 3;
checkSimplex = true;
break;
}
if(newCachedSeparatingAxis.length2()<colDesc.m_gjkRelError2)
{
m_cachedSeparatingAxis = newCachedSeparatingAxis;
m_degenerateSimplex = 6;
checkSimplex = true;
break;
}
btScalar previousSquaredDistance = squaredDistance;
squaredDistance = newCachedSeparatingAxis.length2();
#if 0
///warning: this termination condition leads to some problems in 2d test case see Bullet/Demos/Box2dDemo
if (squaredDistance>previousSquaredDistance)
{
m_degenerateSimplex = 7;
squaredDistance = previousSquaredDistance;
checkSimplex = false;
break;
}
#endif //
//redundant m_simplexSolver->compute_points(pointOnA, pointOnB);
//are we getting any closer ?
if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance)
{
// m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
checkSimplex = true;
m_degenerateSimplex = 12;
break;
}
m_cachedSeparatingAxis = newCachedSeparatingAxis;
//degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject
if (m_curIter++ > gGjkMaxIter)
{
#if defined(DEBUG) || defined (_DEBUG)
printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter);
printf("sepAxis=(%f,%f,%f), squaredDistance = %f\n",
m_cachedSeparatingAxis.getX(),
m_cachedSeparatingAxis.getY(),
m_cachedSeparatingAxis.getZ(),
squaredDistance);
#endif
break;
}
bool check = (!simplexSolver.fullSimplex());
//bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex());
if (!check)
{
//do we need this backup_closest here ?
// m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
m_degenerateSimplex = 13;
break;
}
}
if (checkSimplex)
{
simplexSolver.compute_points(pointOnA, pointOnB);
normalInB = m_cachedSeparatingAxis;
btScalar lenSqr =m_cachedSeparatingAxis.length2();
//valid normal
if (lenSqr < 0.0001)
{
m_degenerateSimplex = 5;
}
if (lenSqr > SIMD_EPSILON*SIMD_EPSILON)
{
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
normalInB *= rlen; //normalize
btScalar s = btSqrt(squaredDistance);
btAssert(s > btScalar(0.0));
pointOnA -= m_cachedSeparatingAxis * (marginA / s);
pointOnB += m_cachedSeparatingAxis * (marginB / s);
distance = ((btScalar(1.)/rlen) - margin);
isValid = true;
m_lastUsedMethod = 1;
} else
{
m_lastUsedMethod = 2;
}
}
bool catchDegeneratePenetrationCase =
(m_catchDegeneracies && m_degenerateSimplex && ((distance+margin) < 0.01));
//if (checkPenetration && !isValid)
if (checkPenetration && (!isValid || catchDegeneratePenetrationCase ))
{
//penetration case
//if there is no way to handle penetrations, bail out
// Penetration depth case.
btVector3 tmpPointOnA,tmpPointOnB;
m_cachedSeparatingAxis.setZero();
bool isValid2 = btGjkEpaCalcPenDepth(a,b,
colDesc,
m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB);
if (isValid2)
{
btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA;
btScalar lenSqr = tmpNormalInB.length2();
if (lenSqr <= (SIMD_EPSILON*SIMD_EPSILON))
{
tmpNormalInB = m_cachedSeparatingAxis;
lenSqr = m_cachedSeparatingAxis.length2();
}
if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
{
tmpNormalInB /= btSqrt(lenSqr);
btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length();
//only replace valid penetrations when the result is deeper (check)
if (!isValid || (distance2 < distance))
{
distance = distance2;
pointOnA = tmpPointOnA;
pointOnB = tmpPointOnB;
normalInB = tmpNormalInB;
isValid = true;
m_lastUsedMethod = 3;
} else
{
m_lastUsedMethod = 8;
}
} else
{
m_lastUsedMethod = 9;
}
} else
{
///this is another degenerate case, where the initial GJK calculation reports a degenerate case
///EPA reports no penetration, and the second GJK (using the supporting vector without margin)
///reports a valid positive distance. Use the results of the second GJK instead of failing.
///thanks to Jacob.Langford for the reproduction case
///http://code.google.com/p/bullet/issues/detail?id=250
if (m_cachedSeparatingAxis.length2() > btScalar(0.))
{
btScalar distance2 = (tmpPointOnA-tmpPointOnB).length()-margin;
//only replace valid distances when the distance is less
if (!isValid || (distance2 < distance))
{
distance = distance2;
pointOnA = tmpPointOnA;
pointOnB = tmpPointOnB;
pointOnA -= m_cachedSeparatingAxis * marginA ;
pointOnB += m_cachedSeparatingAxis * marginB ;
normalInB = m_cachedSeparatingAxis;
normalInB.normalize();
isValid = true;
m_lastUsedMethod = 6;
} else
{
m_lastUsedMethod = 5;
}
}
}
}
}
if (isValid && ((distance < 0) || (distance*distance < colDesc.m_maximumDistanceSquared)))
{
m_cachedSeparatingAxis = normalInB;
m_cachedSeparatingDistance = distance;
distInfo->m_distance = distance;
distInfo->m_normalBtoA = normalInB;
distInfo->m_pointOnB = pointOnB;
distInfo->m_pointOnA = pointOnB+normalInB*distance;
return 0;
}
return -m_lastUsedMethod;
}
#endif //BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H

View file

@ -1,6 +1,6 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2010 Erwin Coumans http://bulletphysics.org
Copyright (c) 2003-2014 Erwin Coumans http://bulletphysics.org
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.
@ -14,24 +14,28 @@ subject to the following restrictions:
*/
#ifndef BT_PPU_ADDRESS_SPACE_H
#define BT_PPU_ADDRESS_SPACE_H
#ifndef GJK_COLLISION_DESCRIPTION_H
#define GJK_COLLISION_DESCRIPTION_H
#include "LinearMath/btVector3.h"
#ifdef _WIN32
//stop those casting warnings until we have a better solution for ppu_address_t / void* / uint64 conversions
#pragma warning (disable: 4311)
#pragma warning (disable: 4312)
#endif //_WIN32
struct btGjkCollisionDescription
{
btVector3 m_firstDir;
int m_maxGjkIterations;
btScalar m_maximumDistanceSquared;
btScalar m_gjkRelError2;
btGjkCollisionDescription()
:m_firstDir(0,1,0),
m_maxGjkIterations(1000),
m_maximumDistanceSquared(1e30f),
m_gjkRelError2(1.0e-6)
{
}
virtual ~btGjkCollisionDescription()
{
}
};
#if defined(_WIN64)
typedef unsigned __int64 ppu_address_t;
#elif defined(__LP64__) || defined(__x86_64__)
typedef uint64_t ppu_address_t;
#else
typedef uint32_t ppu_address_t;
#endif //defined(_WIN64)
#endif //BT_PPU_ADDRESS_SPACE_H
#endif //GJK_COLLISION_DESCRIPTION_H

View file

@ -41,21 +41,38 @@ namespace gjkepa2_impl
/* GJK */
#define GJK_MAX_ITERATIONS 128
#define GJK_ACCURARY ((btScalar)0.0001)
#define GJK_MIN_DISTANCE ((btScalar)0.0001)
#define GJK_DUPLICATED_EPS ((btScalar)0.0001)
#ifdef BT_USE_DOUBLE_PRECISION
#define GJK_ACCURACY ((btScalar)1e-12)
#define GJK_MIN_DISTANCE ((btScalar)1e-12)
#define GJK_DUPLICATED_EPS ((btScalar)1e-12)
#else
#define GJK_ACCURACY ((btScalar)0.0001)
#define GJK_MIN_DISTANCE ((btScalar)0.0001)
#define GJK_DUPLICATED_EPS ((btScalar)0.0001)
#endif //BT_USE_DOUBLE_PRECISION
#define GJK_SIMPLEX2_EPS ((btScalar)0.0)
#define GJK_SIMPLEX3_EPS ((btScalar)0.0)
#define GJK_SIMPLEX4_EPS ((btScalar)0.0)
/* EPA */
#define EPA_MAX_VERTICES 64
#define EPA_MAX_FACES (EPA_MAX_VERTICES*2)
#define EPA_MAX_VERTICES 128
#define EPA_MAX_ITERATIONS 255
#define EPA_ACCURACY ((btScalar)0.0001)
#define EPA_FALLBACK (10*EPA_ACCURACY)
#define EPA_PLANE_EPS ((btScalar)0.00001)
#define EPA_INSIDE_EPS ((btScalar)0.01)
#ifdef BT_USE_DOUBLE_PRECISION
#define EPA_ACCURACY ((btScalar)1e-12)
#define EPA_PLANE_EPS ((btScalar)1e-14)
#define EPA_INSIDE_EPS ((btScalar)1e-9)
#else
#define EPA_ACCURACY ((btScalar)0.0001)
#define EPA_PLANE_EPS ((btScalar)0.00001)
#define EPA_INSIDE_EPS ((btScalar)0.01)
#endif
#define EPA_FALLBACK (10*EPA_ACCURACY)
#define EPA_MAX_FACES (EPA_MAX_VERTICES*2)
// Shorthands
@ -242,7 +259,7 @@ namespace gjkepa2_impl
/* Check for termination */
const btScalar omega=btDot(m_ray,w)/rl;
alpha=btMax(omega,alpha);
if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
if(((rl-alpha)-(GJK_ACCURACY*rl))<=0)
{/* Return old simplex */
removevertice(m_simplices[m_current]);
break;
@ -1015,7 +1032,7 @@ bool btGjkEpaSolver2::SignedDistance(const btConvexShape* shape0,
/* Symbols cleanup */
#undef GJK_MAX_ITERATIONS
#undef GJK_ACCURARY
#undef GJK_ACCURACY
#undef GJK_MIN_DISTANCE
#undef GJK_DUPLICATED_EPS
#undef GJK_SIMPLEX2_EPS

File diff suppressed because it is too large Load diff

View file

@ -26,12 +26,17 @@ subject to the following restrictions:
#ifdef __SPU__
#include <spu_printf.h>
#define printf spu_printf
//#define DEBUG_SPU_COLLISION_DETECTION 1
#endif //__SPU__
#endif
//must be above the machine epsilon
#define REL_ERROR2 btScalar(1.0e-6)
#ifdef BT_USE_DOUBLE_PRECISION
#define REL_ERROR2 btScalar(1.0e-12)
btScalar gGjkEpaPenetrationTolerance = 1e-7;
#else
#define REL_ERROR2 btScalar(1.0e-6)
btScalar gGjkEpaPenetrationTolerance = 0.001;
#endif
//temp globals, to improve GJK/EPA/penetration calculations
int gNumDeepPenetrationChecks = 0;
@ -81,17 +86,18 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
#ifdef __SPU__
void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
#else
void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw)
#endif
{
m_cachedSeparatingDistance = 0.f;
btScalar distance=btScalar(0.);
btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
btVector3 pointOnA,pointOnB;
btTransform localTransA = input.m_transformA;
btTransform localTransB = input.m_transformB;
btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5);
btVector3 positionOffset=(localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5);
localTransA.getOrigin() -= positionOffset;
localTransB.getOrigin() -= positionOffset;
@ -102,17 +108,11 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
gNumGjkChecks++;
#ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("inside gjk\n");
#endif
//for CCD we don't use margins
if (m_ignoreMargin)
{
marginA = btScalar(0.);
marginB = btScalar(0.);
#ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("ignoring margin\n");
#endif
}
m_curIter = 0;
@ -143,37 +143,13 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis();
btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis();
#if 1
btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
// btVector3 pInA = localGetSupportingVertexWithoutMargin(m_shapeTypeA, m_minkowskiA, seperatingAxisInA,input.m_convexVertexData[0]);//, &featureIndexA);
// btVector3 qInB = localGetSupportingVertexWithoutMargin(m_shapeTypeB, m_minkowskiB, seperatingAxisInB,input.m_convexVertexData[1]);//, &featureIndexB);
#else
#ifdef __SPU__
btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
#else
btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
#ifdef TEST_NON_VIRTUAL
btVector3 pInAv = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
btVector3 qInBv = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
btAssert((pInAv-pInA).length() < 0.0001);
btAssert((qInBv-qInB).length() < 0.0001);
#endif //
#endif //__SPU__
#endif
btVector3 pWorld = localTransA(pInA);
btVector3 qWorld = localTransB(qInB);
#ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("got local supporting vertices\n");
#endif
if (check2d)
{
@ -217,14 +193,8 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
break;
}
#ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("addVertex 1\n");
#endif
//add current vertex to simplex
m_simplexSolver->addVertex(w, pWorld, qWorld);
#ifdef DEBUG_SPU_COLLISION_DETECTION
spu_printf("addVertex 2\n");
#endif
btVector3 newCachedSeparatingAxis;
//calculate the closest point to the origin (update vector v)
@ -274,7 +244,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
//degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject
if (m_curIter++ > gGjkMaxIter)
{
#if defined(DEBUG) || defined (_DEBUG) || defined (DEBUG_SPU_COLLISION_DETECTION)
#if defined(DEBUG) || defined (_DEBUG)
printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter);
printf("sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n",
@ -307,10 +277,11 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
{
m_simplexSolver->compute_points(pointOnA, pointOnB);
normalInB = m_cachedSeparatingAxis;
btScalar lenSqr =m_cachedSeparatingAxis.length2();
//valid normal
if (lenSqr < 0.0001)
if (lenSqr < REL_ERROR2)
{
m_degenerateSimplex = 5;
}
@ -318,6 +289,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
{
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
normalInB *= rlen; //normalize
btScalar s = btSqrt(squaredDistance);
btAssert(s > btScalar(0.0));
@ -334,7 +306,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
}
bool catchDegeneratePenetrationCase =
(m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < 0.01));
(m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < gGjkEpaPenetrationTolerance));
//if (checkPenetration && !isValid)
if (checkPenetration && (!isValid || catchDegeneratePenetrationCase ))
@ -373,6 +345,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
{
tmpNormalInB /= btSqrt(lenSqr);
btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length();
m_lastUsedMethod = 3;
//only replace valid penetrations when the result is deeper (check)
if (!isValid || (distance2 < distance))
{
@ -380,8 +353,9 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
pointOnA = tmpPointOnA;
pointOnB = tmpPointOnB;
normalInB = tmpNormalInB;
isValid = true;
m_lastUsedMethod = 3;
} else
{
m_lastUsedMethod = 8;
@ -413,6 +387,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
pointOnB += m_cachedSeparatingAxis * marginB ;
normalInB = m_cachedSeparatingAxis;
normalInB.normalize();
isValid = true;
m_lastUsedMethod = 6;
} else
@ -431,39 +406,51 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
if (isValid && ((distance < 0) || (distance*distance < input.m_maximumDistanceSquared)))
{
#if 0
///some debugging
// if (check2d)
{
printf("n = %2.3f,%2.3f,%2.3f. ",normalInB[0],normalInB[1],normalInB[2]);
printf("distance = %2.3f exit=%d deg=%d\n",distance,m_lastUsedMethod,m_degenerateSimplex);
}
#endif
if (m_fixContactNormalDirection)
{
///@workaround for sticky convex collisions
//in some degenerate cases (usually when the use uses very small margins)
//the contact normal is pointing the wrong direction
//so fix it now (until we can deal with all degenerate cases in GJK and EPA)
//contact normals need to point from B to A in all cases, so we can simply check if the contact normal really points from B to A
//We like to use a dot product of the normal against the difference of the centroids,
//once the centroid is available in the API
//until then we use the center of the aabb to approximate the centroid
btVector3 aabbMin,aabbMax;
m_minkowskiA->getAabb(localTransA,aabbMin,aabbMax);
btVector3 posA = (aabbMax+aabbMin)*btScalar(0.5);
m_minkowskiB->getAabb(localTransB,aabbMin,aabbMax);
btVector3 posB = (aabbMin+aabbMax)*btScalar(0.5);
btVector3 diff = posA-posB;
if (diff.dot(normalInB) < 0.f)
normalInB *= -1.f;
}
m_cachedSeparatingAxis = normalInB;
m_cachedSeparatingDistance = distance;
{
///todo: need to track down this EPA penetration solver degeneracy
///the penetration solver reports penetration but the contact normal
///connecting the contact points is pointing in the opposite direction
///until then, detect the issue and revert the normal
btScalar d1=0;
{
btVector3 seperatingAxisInA = (normalInB)* input.m_transformA.getBasis();
btVector3 seperatingAxisInB = -normalInB* input.m_transformB.getBasis();
btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
btVector3 pWorld = localTransA(pInA);
btVector3 qWorld = localTransB(qInB);
btVector3 w = pWorld - qWorld;
d1 = (-normalInB).dot(w);
}
btScalar d0 = 0.f;
{
btVector3 seperatingAxisInA = (-normalInB)* input.m_transformA.getBasis();
btVector3 seperatingAxisInB = normalInB* input.m_transformB.getBasis();
btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
btVector3 pWorld = localTransA(pInA);
btVector3 qWorld = localTransB(qInB);
btVector3 w = pWorld - qWorld;
d0 = normalInB.dot(w);
}
if (d1>d0)
{
m_lastUsedMethod = 10;
normalInB*=-1;
}
}
output.addContactPoint(
normalInB,
pointOnB+positionOffset,

View file

@ -35,7 +35,13 @@ typedef sce::PhysicsEffects::PfxConstraintRow btConstraintRow;
typedef btConstraintRow PfxConstraintRow;
#endif //PFX_USE_FREE_VECTORMATH
enum btContactPointFlags
{
BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED=1,
BT_CONTACT_FLAG_HAS_CONTACT_CFM=2,
BT_CONTACT_FLAG_HAS_CONTACT_ERP=4,
BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING = 8,
};
/// ManifoldContactPoint collects and maintains persistent contactpoints.
/// used to improve stability and performance of rigidbody dynamics response.
@ -44,14 +50,15 @@ class btManifoldPoint
public:
btManifoldPoint()
:m_userPersistentData(0),
m_lateralFrictionInitialized(false),
m_appliedImpulse(0.f),
m_contactPointFlags(0),
m_appliedImpulse(0.f),
m_appliedImpulseLateral1(0.f),
m_appliedImpulseLateral2(0.f),
m_contactMotion1(0.f),
m_contactMotion2(0.f),
m_contactCFM1(0.f),
m_contactCFM2(0.f),
m_contactCFM(0.f),
m_contactERP(0.f),
m_frictionCFM(0.f),
m_lifeTime(0)
{
}
@ -65,16 +72,18 @@ class btManifoldPoint
m_distance1( distance ),
m_combinedFriction(btScalar(0.)),
m_combinedRollingFriction(btScalar(0.)),
m_combinedRestitution(btScalar(0.)),
m_combinedSpinningFriction(btScalar(0.)),
m_combinedRestitution(btScalar(0.)),
m_userPersistentData(0),
m_lateralFrictionInitialized(false),
m_appliedImpulse(0.f),
m_contactPointFlags(0),
m_appliedImpulse(0.f),
m_appliedImpulseLateral1(0.f),
m_appliedImpulseLateral2(0.f),
m_contactMotion1(0.f),
m_contactMotion2(0.f),
m_contactCFM1(0.f),
m_contactCFM2(0.f),
m_contactCFM(0.f),
m_contactERP(0.f),
m_frictionCFM(0.f),
m_lifeTime(0)
{
@ -91,8 +100,9 @@ class btManifoldPoint
btScalar m_distance1;
btScalar m_combinedFriction;
btScalar m_combinedRollingFriction;
btScalar m_combinedRestitution;
btScalar m_combinedRollingFriction;//torsional friction orthogonal to contact normal, useful to make spheres stop rolling forever
btScalar m_combinedSpinningFriction;//torsional friction around contact normal, useful for grasping objects
btScalar m_combinedRestitution;
//BP mod, store contact triangles.
int m_partId0;
@ -101,15 +111,28 @@ class btManifoldPoint
int m_index1;
mutable void* m_userPersistentData;
bool m_lateralFrictionInitialized;
//bool m_lateralFrictionInitialized;
int m_contactPointFlags;
btScalar m_appliedImpulse;
btScalar m_appliedImpulseLateral1;
btScalar m_appliedImpulseLateral2;
btScalar m_contactMotion1;
btScalar m_contactMotion2;
btScalar m_contactCFM1;
btScalar m_contactCFM2;
union
{
btScalar m_contactCFM;
btScalar m_combinedContactStiffness1;
};
union
{
btScalar m_contactERP;
btScalar m_combinedContactDamping1;
};
btScalar m_frictionCFM;
int m_lifeTime;//lifetime of the contactpoint in frames

View file

@ -0,0 +1,908 @@
/***
* ---------------------------------
* Copyright (c)2012 Daniel Fiser <danfis@danfis.cz>
*
* This file was ported from mpr.c file, part of libccd.
* The Minkoski Portal Refinement implementation was ported
* to OpenCL by Erwin Coumans for the Bullet 3 Physics library.
* The original MPR idea and implementation is by Gary Snethen
* in XenoCollide, see http://github.com/erwincoumans/xenocollide
*
* Distributed under the OSI-approved BSD License (the "License");
* see <http://www.opensource.org/licenses/bsd-license.php>.
* This software is distributed WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the License for more information.
*/
///2014 Oct, Erwin Coumans, Use templates to avoid void* casts
#ifndef BT_MPR_PENETRATION_H
#define BT_MPR_PENETRATION_H
#define BT_DEBUG_MPR1
#include "LinearMath/btTransform.h"
#include "LinearMath/btAlignedObjectArray.h"
//#define MPR_AVERAGE_CONTACT_POSITIONS
struct btMprCollisionDescription
{
btVector3 m_firstDir;
int m_maxGjkIterations;
btScalar m_maximumDistanceSquared;
btScalar m_gjkRelError2;
btMprCollisionDescription()
: m_firstDir(0,1,0),
m_maxGjkIterations(1000),
m_maximumDistanceSquared(1e30f),
m_gjkRelError2(1.0e-6)
{
}
virtual ~btMprCollisionDescription()
{
}
};
struct btMprDistanceInfo
{
btVector3 m_pointOnA;
btVector3 m_pointOnB;
btVector3 m_normalBtoA;
btScalar m_distance;
};
#ifdef __cplusplus
#define BT_MPR_SQRT sqrtf
#else
#define BT_MPR_SQRT sqrt
#endif
#define BT_MPR_FMIN(x, y) ((x) < (y) ? (x) : (y))
#define BT_MPR_FABS fabs
#define BT_MPR_TOLERANCE 1E-6f
#define BT_MPR_MAX_ITERATIONS 1000
struct _btMprSupport_t
{
btVector3 v; //!< Support point in minkowski sum
btVector3 v1; //!< Support point in obj1
btVector3 v2; //!< Support point in obj2
};
typedef struct _btMprSupport_t btMprSupport_t;
struct _btMprSimplex_t
{
btMprSupport_t ps[4];
int last; //!< index of last added point
};
typedef struct _btMprSimplex_t btMprSimplex_t;
inline btMprSupport_t* btMprSimplexPointW(btMprSimplex_t *s, int idx)
{
return &s->ps[idx];
}
inline void btMprSimplexSetSize(btMprSimplex_t *s, int size)
{
s->last = size - 1;
}
#ifdef DEBUG_MPR
inline void btPrintPortalVertex(_btMprSimplex_t* portal, int index)
{
printf("portal[%d].v = %f,%f,%f, v1=%f,%f,%f, v2=%f,%f,%f\n", index, portal->ps[index].v.x(),portal->ps[index].v.y(),portal->ps[index].v.z(),
portal->ps[index].v1.x(),portal->ps[index].v1.y(),portal->ps[index].v1.z(),
portal->ps[index].v2.x(),portal->ps[index].v2.y(),portal->ps[index].v2.z());
}
#endif //DEBUG_MPR
inline int btMprSimplexSize(const btMprSimplex_t *s)
{
return s->last + 1;
}
inline const btMprSupport_t* btMprSimplexPoint(const btMprSimplex_t* s, int idx)
{
// here is no check on boundaries
return &s->ps[idx];
}
inline void btMprSupportCopy(btMprSupport_t *d, const btMprSupport_t *s)
{
*d = *s;
}
inline void btMprSimplexSet(btMprSimplex_t *s, size_t pos, const btMprSupport_t *a)
{
btMprSupportCopy(s->ps + pos, a);
}
inline void btMprSimplexSwap(btMprSimplex_t *s, size_t pos1, size_t pos2)
{
btMprSupport_t supp;
btMprSupportCopy(&supp, &s->ps[pos1]);
btMprSupportCopy(&s->ps[pos1], &s->ps[pos2]);
btMprSupportCopy(&s->ps[pos2], &supp);
}
inline int btMprIsZero(float val)
{
return BT_MPR_FABS(val) < FLT_EPSILON;
}
inline int btMprEq(float _a, float _b)
{
float ab;
float a, b;
ab = BT_MPR_FABS(_a - _b);
if (BT_MPR_FABS(ab) < FLT_EPSILON)
return 1;
a = BT_MPR_FABS(_a);
b = BT_MPR_FABS(_b);
if (b > a){
return ab < FLT_EPSILON * b;
}else{
return ab < FLT_EPSILON * a;
}
}
inline int btMprVec3Eq(const btVector3* a, const btVector3 *b)
{
return btMprEq((*a).x(), (*b).x())
&& btMprEq((*a).y(), (*b).y())
&& btMprEq((*a).z(), (*b).z());
}
template <typename btConvexTemplate>
inline void btFindOrigin(const btConvexTemplate& a, const btConvexTemplate& b, const btMprCollisionDescription& colDesc,btMprSupport_t *center)
{
center->v1 = a.getObjectCenterInWorld();
center->v2 = b.getObjectCenterInWorld();
center->v = center->v1 - center->v2;
}
inline void btMprVec3Set(btVector3 *v, float x, float y, float z)
{
v->setValue(x,y,z);
}
inline void btMprVec3Add(btVector3 *v, const btVector3 *w)
{
*v += *w;
}
inline void btMprVec3Copy(btVector3 *v, const btVector3 *w)
{
*v = *w;
}
inline void btMprVec3Scale(btVector3 *d, float k)
{
*d *= k;
}
inline float btMprVec3Dot(const btVector3 *a, const btVector3 *b)
{
float dot;
dot = btDot(*a,*b);
return dot;
}
inline float btMprVec3Len2(const btVector3 *v)
{
return btMprVec3Dot(v, v);
}
inline void btMprVec3Normalize(btVector3 *d)
{
float k = 1.f / BT_MPR_SQRT(btMprVec3Len2(d));
btMprVec3Scale(d, k);
}
inline void btMprVec3Cross(btVector3 *d, const btVector3 *a, const btVector3 *b)
{
*d = btCross(*a,*b);
}
inline void btMprVec3Sub2(btVector3 *d, const btVector3 *v, const btVector3 *w)
{
*d = *v - *w;
}
inline void btPortalDir(const btMprSimplex_t *portal, btVector3 *dir)
{
btVector3 v2v1, v3v1;
btMprVec3Sub2(&v2v1, &btMprSimplexPoint(portal, 2)->v,
&btMprSimplexPoint(portal, 1)->v);
btMprVec3Sub2(&v3v1, &btMprSimplexPoint(portal, 3)->v,
&btMprSimplexPoint(portal, 1)->v);
btMprVec3Cross(dir, &v2v1, &v3v1);
btMprVec3Normalize(dir);
}
inline int portalEncapsulesOrigin(const btMprSimplex_t *portal,
const btVector3 *dir)
{
float dot;
dot = btMprVec3Dot(dir, &btMprSimplexPoint(portal, 1)->v);
return btMprIsZero(dot) || dot > 0.f;
}
inline int portalReachTolerance(const btMprSimplex_t *portal,
const btMprSupport_t *v4,
const btVector3 *dir)
{
float dv1, dv2, dv3, dv4;
float dot1, dot2, dot3;
// find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4}
dv1 = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, dir);
dv2 = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, dir);
dv3 = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, dir);
dv4 = btMprVec3Dot(&v4->v, dir);
dot1 = dv4 - dv1;
dot2 = dv4 - dv2;
dot3 = dv4 - dv3;
dot1 = BT_MPR_FMIN(dot1, dot2);
dot1 = BT_MPR_FMIN(dot1, dot3);
return btMprEq(dot1, BT_MPR_TOLERANCE) || dot1 < BT_MPR_TOLERANCE;
}
inline int portalCanEncapsuleOrigin(const btMprSimplex_t *portal,
const btMprSupport_t *v4,
const btVector3 *dir)
{
float dot;
dot = btMprVec3Dot(&v4->v, dir);
return btMprIsZero(dot) || dot > 0.f;
}
inline void btExpandPortal(btMprSimplex_t *portal,
const btMprSupport_t *v4)
{
float dot;
btVector3 v4v0;
btMprVec3Cross(&v4v0, &v4->v, &btMprSimplexPoint(portal, 0)->v);
dot = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, &v4v0);
if (dot > 0.f){
dot = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, &v4v0);
if (dot > 0.f){
btMprSimplexSet(portal, 1, v4);
}else{
btMprSimplexSet(portal, 3, v4);
}
}else{
dot = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, &v4v0);
if (dot > 0.f){
btMprSimplexSet(portal, 2, v4);
}else{
btMprSimplexSet(portal, 1, v4);
}
}
}
template <typename btConvexTemplate>
inline void btMprSupport(const btConvexTemplate& a, const btConvexTemplate& b,
const btMprCollisionDescription& colDesc,
const btVector3& dir, btMprSupport_t *supp)
{
btVector3 seperatingAxisInA = dir* a.getWorldTransform().getBasis();
btVector3 seperatingAxisInB = -dir* b.getWorldTransform().getBasis();
btVector3 pInA = a.getLocalSupportWithMargin(seperatingAxisInA);
btVector3 qInB = b.getLocalSupportWithMargin(seperatingAxisInB);
supp->v1 = a.getWorldTransform()(pInA);
supp->v2 = b.getWorldTransform()(qInB);
supp->v = supp->v1 - supp->v2;
}
template <typename btConvexTemplate>
static int btDiscoverPortal(const btConvexTemplate& a, const btConvexTemplate& b,
const btMprCollisionDescription& colDesc,
btMprSimplex_t *portal)
{
btVector3 dir, va, vb;
float dot;
int cont;
// vertex 0 is center of portal
btFindOrigin(a,b,colDesc, btMprSimplexPointW(portal, 0));
// vertex 0 is center of portal
btMprSimplexSetSize(portal, 1);
btVector3 zero = btVector3(0,0,0);
btVector3* org = &zero;
if (btMprVec3Eq(&btMprSimplexPoint(portal, 0)->v, org)){
// Portal's center lies on origin (0,0,0) => we know that objects
// intersect but we would need to know penetration info.
// So move center little bit...
btMprVec3Set(&va, FLT_EPSILON * 10.f, 0.f, 0.f);
btMprVec3Add(&btMprSimplexPointW(portal, 0)->v, &va);
}
// vertex 1 = support in direction of origin
btMprVec3Copy(&dir, &btMprSimplexPoint(portal, 0)->v);
btMprVec3Scale(&dir, -1.f);
btMprVec3Normalize(&dir);
btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 1));
btMprSimplexSetSize(portal, 2);
// test if origin isn't outside of v1
dot = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, &dir);
if (btMprIsZero(dot) || dot < 0.f)
return -1;
// vertex 2
btMprVec3Cross(&dir, &btMprSimplexPoint(portal, 0)->v,
&btMprSimplexPoint(portal, 1)->v);
if (btMprIsZero(btMprVec3Len2(&dir))){
if (btMprVec3Eq(&btMprSimplexPoint(portal, 1)->v, org)){
// origin lies on v1
return 1;
}else{
// origin lies on v0-v1 segment
return 2;
}
}
btMprVec3Normalize(&dir);
btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 2));
dot = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, &dir);
if (btMprIsZero(dot) || dot < 0.f)
return -1;
btMprSimplexSetSize(portal, 3);
// vertex 3 direction
btMprVec3Sub2(&va, &btMprSimplexPoint(portal, 1)->v,
&btMprSimplexPoint(portal, 0)->v);
btMprVec3Sub2(&vb, &btMprSimplexPoint(portal, 2)->v,
&btMprSimplexPoint(portal, 0)->v);
btMprVec3Cross(&dir, &va, &vb);
btMprVec3Normalize(&dir);
// it is better to form portal faces to be oriented "outside" origin
dot = btMprVec3Dot(&dir, &btMprSimplexPoint(portal, 0)->v);
if (dot > 0.f){
btMprSimplexSwap(portal, 1, 2);
btMprVec3Scale(&dir, -1.f);
}
while (btMprSimplexSize(portal) < 4){
btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 3));
dot = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, &dir);
if (btMprIsZero(dot) || dot < 0.f)
return -1;
cont = 0;
// test if origin is outside (v1, v0, v3) - set v2 as v3 and
// continue
btMprVec3Cross(&va, &btMprSimplexPoint(portal, 1)->v,
&btMprSimplexPoint(portal, 3)->v);
dot = btMprVec3Dot(&va, &btMprSimplexPoint(portal, 0)->v);
if (dot < 0.f && !btMprIsZero(dot)){
btMprSimplexSet(portal, 2, btMprSimplexPoint(portal, 3));
cont = 1;
}
if (!cont){
// test if origin is outside (v3, v0, v2) - set v1 as v3 and
// continue
btMprVec3Cross(&va, &btMprSimplexPoint(portal, 3)->v,
&btMprSimplexPoint(portal, 2)->v);
dot = btMprVec3Dot(&va, &btMprSimplexPoint(portal, 0)->v);
if (dot < 0.f && !btMprIsZero(dot)){
btMprSimplexSet(portal, 1, btMprSimplexPoint(portal, 3));
cont = 1;
}
}
if (cont){
btMprVec3Sub2(&va, &btMprSimplexPoint(portal, 1)->v,
&btMprSimplexPoint(portal, 0)->v);
btMprVec3Sub2(&vb, &btMprSimplexPoint(portal, 2)->v,
&btMprSimplexPoint(portal, 0)->v);
btMprVec3Cross(&dir, &va, &vb);
btMprVec3Normalize(&dir);
}else{
btMprSimplexSetSize(portal, 4);
}
}
return 0;
}
template <typename btConvexTemplate>
static int btRefinePortal(const btConvexTemplate& a, const btConvexTemplate& b,const btMprCollisionDescription& colDesc,
btMprSimplex_t *portal)
{
btVector3 dir;
btMprSupport_t v4;
for (int i=0;i<BT_MPR_MAX_ITERATIONS;i++)
//while (1)
{
// compute direction outside the portal (from v0 throught v1,v2,v3
// face)
btPortalDir(portal, &dir);
// test if origin is inside the portal
if (portalEncapsulesOrigin(portal, &dir))
return 0;
// get next support point
btMprSupport(a,b,colDesc, dir, &v4);
// test if v4 can expand portal to contain origin and if portal
// expanding doesn't reach given tolerance
if (!portalCanEncapsuleOrigin(portal, &v4, &dir)
|| portalReachTolerance(portal, &v4, &dir))
{
return -1;
}
// v1-v2-v3 triangle must be rearranged to face outside Minkowski
// difference (direction from v0).
btExpandPortal(portal, &v4);
}
return -1;
}
static void btFindPos(const btMprSimplex_t *portal, btVector3 *pos)
{
btVector3 zero = btVector3(0,0,0);
btVector3* origin = &zero;
btVector3 dir;
size_t i;
float b[4], sum, inv;
btVector3 vec, p1, p2;
btPortalDir(portal, &dir);
// use barycentric coordinates of tetrahedron to find origin
btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 1)->v,
&btMprSimplexPoint(portal, 2)->v);
b[0] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 3)->v);
btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 3)->v,
&btMprSimplexPoint(portal, 2)->v);
b[1] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 0)->v);
btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 0)->v,
&btMprSimplexPoint(portal, 1)->v);
b[2] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 3)->v);
btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 2)->v,
&btMprSimplexPoint(portal, 1)->v);
b[3] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 0)->v);
sum = b[0] + b[1] + b[2] + b[3];
if (btMprIsZero(sum) || sum < 0.f){
b[0] = 0.f;
btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 2)->v,
&btMprSimplexPoint(portal, 3)->v);
b[1] = btMprVec3Dot(&vec, &dir);
btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 3)->v,
&btMprSimplexPoint(portal, 1)->v);
b[2] = btMprVec3Dot(&vec, &dir);
btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 1)->v,
&btMprSimplexPoint(portal, 2)->v);
b[3] = btMprVec3Dot(&vec, &dir);
sum = b[1] + b[2] + b[3];
}
inv = 1.f / sum;
btMprVec3Copy(&p1, origin);
btMprVec3Copy(&p2, origin);
for (i = 0; i < 4; i++){
btMprVec3Copy(&vec, &btMprSimplexPoint(portal, i)->v1);
btMprVec3Scale(&vec, b[i]);
btMprVec3Add(&p1, &vec);
btMprVec3Copy(&vec, &btMprSimplexPoint(portal, i)->v2);
btMprVec3Scale(&vec, b[i]);
btMprVec3Add(&p2, &vec);
}
btMprVec3Scale(&p1, inv);
btMprVec3Scale(&p2, inv);
#ifdef MPR_AVERAGE_CONTACT_POSITIONS
btMprVec3Copy(pos, &p1);
btMprVec3Add(pos, &p2);
btMprVec3Scale(pos, 0.5);
#else
btMprVec3Copy(pos, &p2);
#endif//MPR_AVERAGE_CONTACT_POSITIONS
}
inline float btMprVec3Dist2(const btVector3 *a, const btVector3 *b)
{
btVector3 ab;
btMprVec3Sub2(&ab, a, b);
return btMprVec3Len2(&ab);
}
inline float _btMprVec3PointSegmentDist2(const btVector3 *P,
const btVector3 *x0,
const btVector3 *b,
btVector3 *witness)
{
// The computation comes from solving equation of segment:
// S(t) = x0 + t.d
// where - x0 is initial point of segment
// - d is direction of segment from x0 (|d| > 0)
// - t belongs to <0, 1> interval
//
// Than, distance from a segment to some point P can be expressed:
// D(t) = |x0 + t.d - P|^2
// which is distance from any point on segment. Minimization
// of this function brings distance from P to segment.
// Minimization of D(t) leads to simple quadratic equation that's
// solving is straightforward.
//
// Bonus of this method is witness point for free.
float dist, t;
btVector3 d, a;
// direction of segment
btMprVec3Sub2(&d, b, x0);
// precompute vector from P to x0
btMprVec3Sub2(&a, x0, P);
t = -1.f * btMprVec3Dot(&a, &d);
t /= btMprVec3Len2(&d);
if (t < 0.f || btMprIsZero(t)){
dist = btMprVec3Dist2(x0, P);
if (witness)
btMprVec3Copy(witness, x0);
}else if (t > 1.f || btMprEq(t, 1.f)){
dist = btMprVec3Dist2(b, P);
if (witness)
btMprVec3Copy(witness, b);
}else{
if (witness){
btMprVec3Copy(witness, &d);
btMprVec3Scale(witness, t);
btMprVec3Add(witness, x0);
dist = btMprVec3Dist2(witness, P);
}else{
// recycling variables
btMprVec3Scale(&d, t);
btMprVec3Add(&d, &a);
dist = btMprVec3Len2(&d);
}
}
return dist;
}
inline float btMprVec3PointTriDist2(const btVector3 *P,
const btVector3 *x0, const btVector3 *B,
const btVector3 *C,
btVector3 *witness)
{
// Computation comes from analytic expression for triangle (x0, B, C)
// T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and
// Then equation for distance is:
// D(s, t) = | T(s, t) - P |^2
// This leads to minimization of quadratic function of two variables.
// The solution from is taken only if s is between 0 and 1, t is
// between 0 and 1 and t + s < 1, otherwise distance from segment is
// computed.
btVector3 d1, d2, a;
float u, v, w, p, q, r;
float s, t, dist, dist2;
btVector3 witness2;
btMprVec3Sub2(&d1, B, x0);
btMprVec3Sub2(&d2, C, x0);
btMprVec3Sub2(&a, x0, P);
u = btMprVec3Dot(&a, &a);
v = btMprVec3Dot(&d1, &d1);
w = btMprVec3Dot(&d2, &d2);
p = btMprVec3Dot(&a, &d1);
q = btMprVec3Dot(&a, &d2);
r = btMprVec3Dot(&d1, &d2);
btScalar div = (w * v - r * r);
if (btMprIsZero(div))
{
s=-1;
} else
{
s = (q * r - w * p) / div;
t = (-s * r - q) / w;
}
if ((btMprIsZero(s) || s > 0.f)
&& (btMprEq(s, 1.f) || s < 1.f)
&& (btMprIsZero(t) || t > 0.f)
&& (btMprEq(t, 1.f) || t < 1.f)
&& (btMprEq(t + s, 1.f) || t + s < 1.f)){
if (witness){
btMprVec3Scale(&d1, s);
btMprVec3Scale(&d2, t);
btMprVec3Copy(witness, x0);
btMprVec3Add(witness, &d1);
btMprVec3Add(witness, &d2);
dist = btMprVec3Dist2(witness, P);
}else{
dist = s * s * v;
dist += t * t * w;
dist += 2.f * s * t * r;
dist += 2.f * s * p;
dist += 2.f * t * q;
dist += u;
}
}else{
dist = _btMprVec3PointSegmentDist2(P, x0, B, witness);
dist2 = _btMprVec3PointSegmentDist2(P, x0, C, &witness2);
if (dist2 < dist){
dist = dist2;
if (witness)
btMprVec3Copy(witness, &witness2);
}
dist2 = _btMprVec3PointSegmentDist2(P, B, C, &witness2);
if (dist2 < dist){
dist = dist2;
if (witness)
btMprVec3Copy(witness, &witness2);
}
}
return dist;
}
template <typename btConvexTemplate>
static void btFindPenetr(const btConvexTemplate& a, const btConvexTemplate& b,
const btMprCollisionDescription& colDesc,
btMprSimplex_t *portal,
float *depth, btVector3 *pdir, btVector3 *pos)
{
btVector3 dir;
btMprSupport_t v4;
unsigned long iterations;
btVector3 zero = btVector3(0,0,0);
btVector3* origin = &zero;
iterations = 1UL;
for (int i=0;i<BT_MPR_MAX_ITERATIONS;i++)
//while (1)
{
// compute portal direction and obtain next support point
btPortalDir(portal, &dir);
btMprSupport(a,b,colDesc, dir, &v4);
// reached tolerance -> find penetration info
if (portalReachTolerance(portal, &v4, &dir)
|| iterations ==BT_MPR_MAX_ITERATIONS)
{
*depth = btMprVec3PointTriDist2(origin,&btMprSimplexPoint(portal, 1)->v,&btMprSimplexPoint(portal, 2)->v,&btMprSimplexPoint(portal, 3)->v,pdir);
*depth = BT_MPR_SQRT(*depth);
if (btMprIsZero((*pdir).x()) && btMprIsZero((*pdir).y()) && btMprIsZero((*pdir).z()))
{
*pdir = dir;
}
btMprVec3Normalize(pdir);
// barycentric coordinates:
btFindPos(portal, pos);
return;
}
btExpandPortal(portal, &v4);
iterations++;
}
}
static void btFindPenetrTouch(btMprSimplex_t *portal,float *depth, btVector3 *dir, btVector3 *pos)
{
// Touching contact on portal's v1 - so depth is zero and direction
// is unimportant and pos can be guessed
*depth = 0.f;
btVector3 zero = btVector3(0,0,0);
btVector3* origin = &zero;
btMprVec3Copy(dir, origin);
#ifdef MPR_AVERAGE_CONTACT_POSITIONS
btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v1);
btMprVec3Add(pos, &btMprSimplexPoint(portal, 1)->v2);
btMprVec3Scale(pos, 0.5);
#else
btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v2);
#endif
}
static void btFindPenetrSegment(btMprSimplex_t *portal,
float *depth, btVector3 *dir, btVector3 *pos)
{
// Origin lies on v0-v1 segment.
// Depth is distance to v1, direction also and position must be
// computed
#ifdef MPR_AVERAGE_CONTACT_POSITIONS
btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v1);
btMprVec3Add(pos, &btMprSimplexPoint(portal, 1)->v2);
btMprVec3Scale(pos, 0.5f);
#else
btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v2);
#endif//MPR_AVERAGE_CONTACT_POSITIONS
btMprVec3Copy(dir, &btMprSimplexPoint(portal, 1)->v);
*depth = BT_MPR_SQRT(btMprVec3Len2(dir));
btMprVec3Normalize(dir);
}
template <typename btConvexTemplate>
inline int btMprPenetration( const btConvexTemplate& a, const btConvexTemplate& b,
const btMprCollisionDescription& colDesc,
float *depthOut, btVector3* dirOut, btVector3* posOut)
{
btMprSimplex_t portal;
// Phase 1: Portal discovery
int result = btDiscoverPortal(a,b,colDesc, &portal);
//sepAxis[pairIndex] = *pdir;//or -dir?
switch (result)
{
case 0:
{
// Phase 2: Portal refinement
result = btRefinePortal(a,b,colDesc, &portal);
if (result < 0)
return -1;
// Phase 3. Penetration info
btFindPenetr(a,b,colDesc, &portal, depthOut, dirOut, posOut);
break;
}
case 1:
{
// Touching contact on portal's v1.
btFindPenetrTouch(&portal, depthOut, dirOut, posOut);
result=0;
break;
}
case 2:
{
btFindPenetrSegment( &portal, depthOut, dirOut, posOut);
result=0;
break;
}
default:
{
//if (res < 0)
//{
// Origin isn't inside portal - no collision.
result = -1;
//}
}
};
return result;
};
template<typename btConvexTemplate, typename btMprDistanceTemplate>
inline int btComputeMprPenetration( const btConvexTemplate& a, const btConvexTemplate& b, const
btMprCollisionDescription& colDesc, btMprDistanceTemplate* distInfo)
{
btVector3 dir,pos;
float depth;
int res = btMprPenetration(a,b,colDesc,&depth, &dir, &pos);
if (res==0)
{
distInfo->m_distance = -depth;
distInfo->m_pointOnB = pos;
distInfo->m_normalBtoA = -dir;
distInfo->m_pointOnA = pos-distInfo->m_distance*dir;
return 0;
}
return -1;
}
#endif //BT_MPR_PENETRATION_H

View file

@ -163,7 +163,7 @@ public:
//get rid of duplicated userPersistentData pointer
m_pointCache[lastUsedIndex].m_userPersistentData = 0;
m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false;
m_pointCache[lastUsedIndex].m_contactPointFlags = 0;
m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
m_pointCache[lastUsedIndex].m_lifeTime = 0;
@ -190,16 +190,11 @@ public:
void* cache = m_pointCache[insertIndex].m_userPersistentData;
m_pointCache[insertIndex] = newPoint;
m_pointCache[insertIndex].m_userPersistentData = cache;
m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
m_pointCache[insertIndex].m_lifeTime = lifeTime;
#else

View file

@ -116,7 +116,7 @@ static int gActualSATPairTests=0;
inline bool IsAlmostZero(const btVector3& v)
{
if(fabsf(v.x())>1e-6 || fabsf(v.y())>1e-6 || fabsf(v.z())>1e-6) return false;
if(btFabs(v.x())>1e-6 || btFabs(v.y())>1e-6 || btFabs(v.z())>1e-6) return false;
return true;
}
@ -313,7 +313,7 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
int edgeB=-1;
btVector3 worldEdgeA;
btVector3 worldEdgeB;
btVector3 witnessPointA,witnessPointB;
btVector3 witnessPointA(0,0,0),witnessPointB(0,0,0);
int curEdgeEdge = 0;
@ -411,9 +411,9 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
return true;
}
void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut)
void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1,btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut)
{
btVertexArray worldVertsB2;
worldVertsB2.resize(0);
btVertexArray* pVtxIn = &worldVertsB1;
btVertexArray* pVtxOut = &worldVertsB2;
pVtxOut->reserve(pVtxIn->size());
@ -527,7 +527,7 @@ void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatin
void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut)
void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btVertexArray& worldVertsB1,btVertexArray& worldVertsB2,btDiscreteCollisionDetectorInterface::Result& resultOut)
{
btVector3 separatingNormal = separatingNormal1.normalized();
@ -552,7 +552,7 @@ void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatin
}
}
}
btVertexArray worldVertsB1;
worldVertsB1.resize(0);
{
const btFace& polyB = hullB.m_faces[closestFaceB];
const int numVertices = polyB.m_indices.size();
@ -565,6 +565,6 @@ void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatin
if (closestFaceB>=0)
clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, minDist, maxDist,resultOut);
clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, worldVertsB2,minDist, maxDist,resultOut);
}

View file

@ -32,8 +32,11 @@ typedef btAlignedObjectArray<btVector3> btVertexArray;
// Clips a face to the back of a plane
struct btPolyhedralContactClipping
{
static void clipHullAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut);
static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut);
static void clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btVertexArray& worldVertsB1,btVertexArray& worldVertsB2,btDiscreteCollisionDetectorInterface::Result& resultOut);
static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1,btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut);
static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut);

View file

@ -32,10 +32,12 @@ public:
//@BP Mod - allow backface filtering and unflipped normals
enum EFlags
{
kF_None = 0,
kF_None = 0,
kF_FilterBackfaces = 1 << 0,
kF_KeepUnflippedNormal = 1 << 1, // Prevents returned face normal getting flipped when a ray hits a back-facing triangle
kF_UseSubSimplexConvexCastRaytest = 1 << 2, // Uses an approximate but faster ray versus convex intersection algorithm
///SubSimplexConvexCastRaytest is the default, even if kF_None is set.
kF_UseSubSimplexConvexCastRaytest = 1 << 2, // Uses an approximate but faster ray versus convex intersection algorithm
kF_UseGjkConvexCastRaytest = 1 << 3,
kF_Terminator = 0xFFFFFFFF
};
unsigned int m_flags;

View file

@ -65,10 +65,10 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
btVector3 n;
n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
bool hasResult = false;
btVector3 c;
btScalar lastLambda = lambda;
btScalar dist2 = v.length2();
@ -109,9 +109,9 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
//m_simplexSolver->reset();
//check next line
w = supVertexA-supVertexB;
lastLambda = lambda;
n = v;
hasResult = true;
}
}
///Just like regular GJK only add the vertex if it isn't already (close) to current vertex, it would lead to divisions by zero and NaN etc.
@ -121,7 +121,7 @@ bool btSubsimplexConvexCast::calcTimeOfImpact(
if (m_simplexSolver->closest(v))
{
dist2 = v.length2();
hasResult = true;
//todo: check this normal for validity
//n=v;
//printf("V=%f , %f, %f\n",v[0],v[1],v[2]);

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