Merge branch 'master' into soc-2013-rigid_body_sim
Conflicts: intern/rigidbody/CMakeLists.txt release/datafiles/splash.png source/blender/editors/space_view3d/drawobject.c source/blender/makesdna/DNA_view3d_types.h
This commit is contained in:
6
.arcconfig
Normal file
6
.arcconfig
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"project_id" : "Blender",
|
||||
"conduit_uri" : "http://developer.blender.org/",
|
||||
"git.default-relative-commit" : "origin/master",
|
||||
"arc.land.update.default" : "rebase"
|
||||
}
|
25
.gitignore
vendored
Normal file
25
.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# generic files to ignore
|
||||
.*
|
||||
|
||||
# python temp paths
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# editors
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
*#
|
||||
|
||||
# ms-windows
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
Desktop.ini
|
||||
|
||||
# commonly used paths in blender
|
||||
/blender.bin
|
||||
/user-config.py
|
||||
|
||||
# local patches
|
||||
/*.patch
|
||||
/*.diff
|
16
.gitmodules
vendored
Normal file
16
.gitmodules
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
[submodule "release/scripts/addons"]
|
||||
path = release/scripts/addons
|
||||
url = ../blender-addons.git
|
||||
ignore = all
|
||||
[submodule "release/scripts/addons_contrib"]
|
||||
path = release/scripts/addons_contrib
|
||||
url = ../blender-addons-contrib.git
|
||||
ignore = all
|
||||
[submodule "release/datafiles/locale"]
|
||||
path = release/datafiles/locale
|
||||
url = ../blender-translations.git
|
||||
ignore = all
|
||||
[submodule "scons"]
|
||||
path = scons
|
||||
url = ../scons.git
|
||||
ignore = all
|
117
CMakeLists.txt
117
CMakeLists.txt
@@ -216,15 +216,22 @@ option(WITH_IMAGE_FRAMESERVER "Enable image FrameServer Support for rendering"
|
||||
# Audio/Video format support
|
||||
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)
|
||||
option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF)
|
||||
|
||||
option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
|
||||
if(APPLE OR (WIN32 AND NOT UNIX))
|
||||
option(WITH_CODEC_QUICKTIME "Enable Quicktime Support" OFF)
|
||||
|
||||
if(APPLE)
|
||||
option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" ON)
|
||||
option(WITH_CODEC_QUICKTIME "Enable Quicktime Support" ON)
|
||||
else()
|
||||
option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF)
|
||||
endif()
|
||||
|
||||
# 3D format support
|
||||
# disable opencollada on non-apple unix because opencollada has no package for debian
|
||||
option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" OFF)
|
||||
# Disable opencollada when we don't have precompiled libs
|
||||
if(APPLE OR WIN32)
|
||||
option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ON)
|
||||
else()
|
||||
option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" OFF)
|
||||
endif()
|
||||
|
||||
# Sound output
|
||||
option(WITH_SDL "Enable SDL for sound and joystick support" ON)
|
||||
@@ -290,7 +297,7 @@ mark_as_advanced(WITH_CXX_GUARDEDALLOC)
|
||||
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" OFF)
|
||||
mark_as_advanced(WITH_ASSERT_ABORT)
|
||||
|
||||
option(WITH_BOOST "Enable features depending no boost" ON)
|
||||
option(WITH_BOOST "Enable features depending on boost" ON)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
option(WITH_GCC_MUDFLAP "Enable mudflap" OFF)
|
||||
@@ -367,10 +374,17 @@ if(APPLE)
|
||||
message(STATUS "OSX_SYSROOT_PREFIX: " ${OSX_SYSROOT_PREFIX})
|
||||
set(OSX_DEVELOPER_PREFIX /Developer/SDKs/MacOSX${OSX_SYSTEM}.sdk) # use guaranteed existing sdk
|
||||
set(CMAKE_OSX_SYSROOT ${OSX_SYSROOT_PREFIX}/${OSX_DEVELOPER_PREFIX} CACHE PATH "" FORCE)
|
||||
if(${CMAKE_GENERATOR} MATCHES "Xcode")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_SDKROOT macosx${OSX_SYSTEM}) # to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if(OSX_SYSTEM MATCHES 10.9)
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_OSX_SYSROOT}) # make sure syslibs and headers are looked up in sdk ( expecially for 10.9 openGL atm. )
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.5" CACHE STRING "" FORCE) # 10.5 is our min. target, if you use higher sdk, weak linking happens
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.6" CACHE STRING "" FORCE) # 10.6 is our min. target, if you use higher sdk, weak linking happens
|
||||
endif()
|
||||
|
||||
if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
|
||||
@@ -380,12 +394,7 @@ if(APPLE)
|
||||
add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
endif()
|
||||
|
||||
option(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON)
|
||||
option(USE_QTKIT "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF)
|
||||
option(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF)
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES x86_64)
|
||||
set(USE_QTKIT ON CACHE BOOL "ON" FORCE) # no Quicktime in 64bit
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -492,14 +501,6 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
if(WITH_CODEC_QUICKTIME)
|
||||
message(FATAL_ERROR "MINGW requires WITH_CODEC_QUICKTIME to be OFF "
|
||||
"because it is currently unsupported, remove this "
|
||||
"line if youre a developer who wants to add support.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
|
||||
|
||||
TEST_STDBOOL_SUPPORT()
|
||||
@@ -1030,13 +1031,6 @@ elseif(WIN32)
|
||||
set(SDL_LIBPATH ${SDL}/lib)
|
||||
endif()
|
||||
|
||||
if(WITH_CODEC_QUICKTIME)
|
||||
set(QUICKTIME ${LIBDIR}/QTDevWin)
|
||||
set(QUICKTIME_INCLUDE_DIRS ${QUICKTIME}/CIncludes)
|
||||
set(QUICKTIME_LIBRARIES qtmlClient)
|
||||
set(QUICKTIME_LIBPATH ${QUICKTIME}/Libraries)
|
||||
endif()
|
||||
|
||||
if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
|
||||
add_definitions(-D__SSE__ -D__MMX__)
|
||||
endif()
|
||||
@@ -1500,7 +1494,7 @@ elseif(WIN32)
|
||||
elseif(APPLE)
|
||||
|
||||
if(${CMAKE_OSX_DEPLOYMENT_TARGET} STREQUAL "10.5" OR ${CMAKE_OSX_DEPLOYMENT_TARGET} STRGREATER "10.5")
|
||||
set(WITH_LIBS10.5 ON CACHE BOOL "Use 10.5 libs" FORCE) # valid also for 10.6/10.7
|
||||
set(WITH_LIBS10.5 ON CACHE BOOL "Use 10.5 libs" FORCE) # valid also for 10.6/7/8/9
|
||||
endif()
|
||||
|
||||
if(WITH_LIBS10.5)
|
||||
@@ -1612,47 +1606,37 @@ elseif(APPLE)
|
||||
set(PLATFORM_LINKLIBS stdc++)
|
||||
endif()
|
||||
|
||||
if(WITH_COCOA)
|
||||
set(PLATFORM_CFLAGS "-pipe -funsigned-char -DGHOST_COCOA")
|
||||
set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio")
|
||||
if(USE_QTKIT)
|
||||
set(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -DUSE_QTKIT")
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QTKit")
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES i386)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
|
||||
# libSDL still needs 32bit carbon quicktime
|
||||
endif()
|
||||
elseif(WITH_CODEC_QUICKTIME)
|
||||
set(PLATFORM_CFLAGS "-pipe -funsigned-char")
|
||||
set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio")
|
||||
if(WITH_CODEC_QUICKTIME)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QTKit")
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES i386)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
|
||||
# libSDL still needs 32bit carbon quicktime
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED!
|
||||
# ALSO SHOULD BE MOVED INTO OWN MODULE WHEN FUNCTIONAL
|
||||
if(WITH_INPUT_NDOF)
|
||||
# This thread it *should* work and check the framework - campbell
|
||||
# http://www.cmake.org/pipermail/cmake/2005-December/007740.html
|
||||
find_library(3DCONNEXION_CLIENT_FRAMEWORK
|
||||
NAMES 3DconnexionClient
|
||||
)
|
||||
if(NOT 3DCONNEXION_CLIENT_FRAMEWORK)
|
||||
set(WITH_INPUT_NDOF OFF)
|
||||
endif()
|
||||
|
||||
# XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED!
|
||||
# ALSO SHOULD BE MOVED INTO OWN MODULE WHEN FUNCTIONAL
|
||||
if(WITH_INPUT_NDOF)
|
||||
# This thread it *should* work and check the framework - campbell
|
||||
# http://www.cmake.org/pipermail/cmake/2005-December/007740.html
|
||||
find_library(3DCONNEXION_CLIENT_FRAMEWORK
|
||||
NAMES 3DconnexionClient
|
||||
)
|
||||
if(NOT 3DCONNEXION_CLIENT_FRAMEWORK)
|
||||
set(WITH_INPUT_NDOF OFF)
|
||||
endif()
|
||||
|
||||
if(WITH_INPUT_NDOF)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework 3DconnexionClient")
|
||||
set(NDOF_INCLUDE_DIRS /Library/Frameworks/3DconnexionClient.framework/Headers )
|
||||
endif()
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework 3DconnexionClient")
|
||||
set(NDOF_INCLUDE_DIRS /Library/Frameworks/3DconnexionClient.framework/Headers )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_JACK)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework jackmp")
|
||||
endif()
|
||||
|
||||
else()
|
||||
set(PLATFORM_CFLAGS "-pipe -funsigned-char")
|
||||
set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
|
||||
set(WITH_INPUT_NDOF OFF) # unsupported
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON_MODULE OR WITH_PYTHON_FRAMEWORK)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/Python")# force cmake to link right framework
|
||||
@@ -1805,13 +1789,9 @@ elseif(APPLE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if(${CMAKE_GENERATOR} MATCHES "Xcode")
|
||||
if(${XCODE_VERSION} VERSION_EQUAL 5 OR ${XCODE_VERSION} VERSION_GREATER 5)
|
||||
# Xcode 5 has too low template depth of 128 for libmv
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024")
|
||||
endif()
|
||||
endif()
|
||||
if(${XCODE_VERSION} VERSION_EQUAL 5 OR ${XCODE_VERSION} VERSION_GREATER 5)
|
||||
# Xcode 5 is always using CLANG, which has too low template depth of 128 for libmv
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -2078,6 +2058,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
|
||||
|
||||
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_VARIABLE_DECLARATIONS -Wno-missing-variable-declarations)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_INCOMPAT_PTR_DISCARD_QUAL -Wno-incompatible-pointer-types-discards-qualifiers)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_INT_TO_VOID_POINTER_CAST -Wno-int-to-void-pointer-cast)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_PROTOTYPES -Wno-missing-prototypes)
|
||||
|
84
GNUmakefile
84
GNUmakefile
@@ -40,7 +40,7 @@ ifndef BUILD_CMAKE_ARGS
|
||||
endif
|
||||
|
||||
ifndef BUILD_DIR
|
||||
BUILD_DIR:=$(shell dirname $(BLENDER_DIR))/build_$(OS_NCASE)
|
||||
BUILD_DIR:=$(shell dirname "$(BLENDER_DIR)")/build_$(OS_NCASE)
|
||||
endif
|
||||
|
||||
|
||||
@@ -54,15 +54,15 @@ ifneq "$(findstring debug, $(MAKECMDGOALS))" ""
|
||||
endif
|
||||
ifneq "$(findstring lite, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_lite
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C$(BLENDER_DIR)/build_files/cmake/config/blender_lite.cmake
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/blender_lite.cmake"
|
||||
endif
|
||||
ifneq "$(findstring headless, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_bpy
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C$(BLENDER_DIR)/build_files/cmake/config/blender_headless.cmake
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/blender_headless.cmake"
|
||||
endif
|
||||
ifneq "$(findstring bpy, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_bpy
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C$(BLENDER_DIR)/build_files/cmake/config/bpy_module.cmake
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/bpy_module.cmake"
|
||||
endif
|
||||
|
||||
|
||||
@@ -87,8 +87,8 @@ endif
|
||||
# Macro for configuring cmake
|
||||
|
||||
CMAKE_CONFIG = cmake $(BUILD_CMAKE_ARGS) \
|
||||
-H$(BLENDER_DIR) \
|
||||
-B$(BUILD_DIR) \
|
||||
-H"$(BLENDER_DIR)" \
|
||||
-B"$(BUILD_DIR)" \
|
||||
-DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE)
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ all:
|
||||
|
||||
@echo
|
||||
@echo Building Blender ...
|
||||
$(MAKE) -C $(BUILD_DIR) -s -j $(NPROCS) install
|
||||
$(MAKE) -C "$(BUILD_DIR)" -s -j $(NPROCS) install
|
||||
@echo
|
||||
@echo edit build configuration with: "$(BUILD_DIR)/CMakeCache.txt" run make again to rebuild.
|
||||
@echo blender installed, run from: "$(BUILD_DIR)/bin/blender"
|
||||
@@ -133,7 +133,7 @@ bpy: all
|
||||
# -----------------------------------------------------------------------------
|
||||
# Configuration (save some cd'ing around)
|
||||
config:
|
||||
$(CMAKE_CONFIG_TOOL) $(BUILD_DIR)
|
||||
$(CMAKE_CONFIG_TOOL) "$(BUILD_DIR)"
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -205,7 +205,7 @@ package_pacman:
|
||||
cd build_files/package_spec/pacman ; MAKEFLAGS="-j$(NPROCS)" makepkg --asroot
|
||||
|
||||
package_archive:
|
||||
make -C $(BUILD_DIR) -s package_archive
|
||||
make -C "$(BUILD_DIR)" -s package_archive
|
||||
@echo archive in "$(BUILD_DIR)/release"
|
||||
|
||||
|
||||
@@ -231,25 +231,25 @@ test_deprecated:
|
||||
|
||||
test_style_c:
|
||||
# run our own checks on C/C++ style
|
||||
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check
|
||||
PYTHONIOENCODING=utf_8 python3 "$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" "$(BLENDER_DIR)/source/blender" "$(BLENDER_DIR)/source/creator" --no-length-check
|
||||
|
||||
test_style_c_qtc:
|
||||
# run our own checks on C/C++ style
|
||||
USE_QTC_TASK=1 \
|
||||
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/source/blender $(BLENDER_DIR)/source/creator --no-length-check > \
|
||||
PYTHONIOENCODING=utf_8 python3 "$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" "$(BLENDER_DIR)/source/blender" "$(BLENDER_DIR)/source/creator" --no-length-check > \
|
||||
test_style.tasks
|
||||
@echo "written: test_style.tasks"
|
||||
|
||||
|
||||
test_style_osl:
|
||||
# run our own checks on C/C++ style
|
||||
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/shaders
|
||||
PYTHONIOENCODING=utf_8 python3 "$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" "$(BLENDER_DIR)/intern/cycles/kernel/shaders"
|
||||
|
||||
|
||||
test_style_osl_qtc:
|
||||
# run our own checks on C/C++ style
|
||||
USE_QTC_TASK=1 \
|
||||
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/check_style_c.py $(BLENDER_DIR)/intern/cycles/kernel/shaders > \
|
||||
PYTHONIOENCODING=utf_8 python3 "$(BLENDER_DIR)/source/tools/check_source/check_style_c.py" "$(BLENDER_DIR)/intern/cycles/kernel/shaders" > \
|
||||
test_style.tasks
|
||||
@echo "written: test_style.tasks"
|
||||
|
||||
@@ -258,13 +258,13 @@ test_style_osl_qtc:
|
||||
#
|
||||
|
||||
project_qtcreator:
|
||||
python3 build_files/cmake/cmake_qtcreator_project.py $(BUILD_DIR)
|
||||
python3 build_files/cmake/cmake_qtcreator_project.py "$(BUILD_DIR)"
|
||||
|
||||
project_netbeans:
|
||||
python3 build_files/cmake/cmake_netbeans_project.py $(BUILD_DIR)
|
||||
python3 build_files/cmake/cmake_netbeans_project.py "$(BUILD_DIR)"
|
||||
|
||||
project_eclipse:
|
||||
cmake -G"Eclipse CDT4 - Unix Makefiles" -H$(BLENDER_DIR) -B$(BUILD_DIR)
|
||||
cmake -G"Eclipse CDT4 - Unix Makefiles" -H"$(BLENDER_DIR)" -B"$(BUILD_DIR)"
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -273,49 +273,49 @@ project_eclipse:
|
||||
|
||||
check_cppcheck:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; \
|
||||
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py 2> \
|
||||
$(BLENDER_DIR)/check_cppcheck.txt
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py" 2> \
|
||||
"$(BLENDER_DIR)/check_cppcheck.txt"
|
||||
@echo "written: check_cppcheck.txt"
|
||||
|
||||
check_clang_array:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; \
|
||||
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py"
|
||||
|
||||
check_splint:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; \
|
||||
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py"
|
||||
|
||||
check_sparse:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; \
|
||||
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py"
|
||||
|
||||
check_smatch:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; \
|
||||
python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
python3 "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py"
|
||||
|
||||
check_spelling_py:
|
||||
cd $(BUILD_DIR) ; \
|
||||
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
PYTHONIOENCODING=utf_8 python3 "$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" "$(BLENDER_DIR)/release/scripts"
|
||||
|
||||
check_spelling_c:
|
||||
cd $(BUILD_DIR) ; \
|
||||
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
PYTHONIOENCODING=utf_8 python3 "$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" "$(BLENDER_DIR)/source"
|
||||
|
||||
check_spelling_c_qtc:
|
||||
cd $(BUILD_DIR) ; USE_QTC_TASK=1 \
|
||||
PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/source > \
|
||||
$(BLENDER_DIR)/check_spelling_c.tasks
|
||||
cd "$(BUILD_DIR)" ; USE_QTC_TASK=1 \
|
||||
PYTHONIOENCODING=utf_8 python3 "$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" "$(BLENDER_DIR)/source" > \
|
||||
"$(BLENDER_DIR)/check_spelling_c.tasks"
|
||||
|
||||
check_spelling_osl:
|
||||
cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/intern/cycles/kernel/shaders
|
||||
cd "$(BUILD_DIR)" ; PYTHONIOENCODING=utf_8 python3 "$(BLENDER_DIR)/source/tools/check_source/check_spelling.py" "$(BLENDER_DIR)/intern/cycles/kernel/shaders"
|
||||
|
||||
check_descriptions:
|
||||
$(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python $(BLENDER_DIR)/source/tools/check_descriptions.py
|
||||
"$(BUILD_DIR)/bin/blender" --background -noaudio --factory-startup --python "$(BLENDER_DIR)/source/tools/check_source/check_descriptions.py"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Utilities
|
||||
@@ -328,8 +328,8 @@ tbz:
|
||||
@echo "blender_archive.tar.bz2 written"
|
||||
|
||||
icons:
|
||||
$(BLENDER_DIR)/release/datafiles/blender_icons.sh
|
||||
$(BLENDER_DIR)/release/datafiles/prvicons.sh
|
||||
"$(BLENDER_DIR)/release/datafiles/blender_icons.sh"
|
||||
"$(BLENDER_DIR)/release/datafiles/prvicons.sh"
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -338,7 +338,7 @@ icons:
|
||||
|
||||
# Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation.
|
||||
doc_py:
|
||||
$(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python doc/python_api/sphinx_doc_gen.py
|
||||
"$(BUILD_DIR)/bin/blender" --background -noaudio --factory-startup --python doc/python_api/sphinx_doc_gen.py
|
||||
cd doc/python_api ; sphinx-build -b html sphinx-in sphinx-out
|
||||
@echo "docs written into: '$(BLENDER_DIR)/doc/python_api/sphinx-out/contents.html'"
|
||||
|
||||
@@ -347,14 +347,14 @@ doc_doxy:
|
||||
@echo "docs written into: '$(BLENDER_DIR)/doc/doxygen/html/index.html'"
|
||||
|
||||
doc_dna:
|
||||
$(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python doc/blender_file_format/BlendFileDnaExporter_25.py
|
||||
"$(BUILD_DIR)/bin/blender" --background -noaudio --factory-startup --python doc/blender_file_format/BlendFileDnaExporter_25.py
|
||||
@echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'"
|
||||
|
||||
doc_man:
|
||||
python3 doc/manpage/blender.1.py $(BUILD_DIR)/bin/blender
|
||||
python3 doc/manpage/blender.1.py "$(BUILD_DIR)/bin/blender"
|
||||
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(BUILD_DIR) clean
|
||||
$(MAKE) -C "$(BUILD_DIR)" clean
|
||||
|
||||
.PHONY: all
|
||||
|
200
SConstruct
200
SConstruct
@@ -285,52 +285,153 @@ if 'cudakernels' in B.targets:
|
||||
env['WITH_BF_CYCLES_CUDA_BINARIES'] = True
|
||||
env['WITH_BF_PYTHON'] = False
|
||||
|
||||
# Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY and JAckOSX detection for OSX
|
||||
|
||||
#############################################################################
|
||||
################### Automatic configuration for OSX ##################
|
||||
#############################################################################
|
||||
|
||||
if env['OURPLATFORM']=='darwin':
|
||||
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --"
|
||||
print "Available " + env['MACOSX_SDK_CHECK']
|
||||
if not 'Mac OS X 10.6' in env['MACOSX_SDK_CHECK']:
|
||||
print B.bc.OKGREEN + "Building with user-defined OS X SDK ( Xcode 4.4 or newer )"
|
||||
elif not 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
|
||||
print B.bc.OKGREEN + "Auto-setting available MacOSX SDK -> " + B.bc.ENDC + "MacOSX10.6.sdk"
|
||||
|
||||
import commands
|
||||
|
||||
cmd = 'sw_vers -productVersion'
|
||||
MAC_CUR_VER=cmd_res=commands.getoutput(cmd)
|
||||
cmd = 'xcodebuild -version'
|
||||
cmd_xcode=commands.getoutput(cmd)
|
||||
env['XCODE_CUR_VER']=cmd_xcode[6:][:3] # truncate output to major.minor version
|
||||
cmd = 'xcodebuild -showsdks'
|
||||
cmd_sdk=commands.getoutput(cmd)
|
||||
MACOSX_SDK_CHECK=cmd_sdk
|
||||
cmd = 'xcode-select --print-path'
|
||||
XCODE_SELECT_PATH=commands.getoutput(cmd)
|
||||
if XCODE_SELECT_PATH.endswith("/Contents/Developer"):
|
||||
XCODE_BUNDLE=XCODE_SELECT_PATH[:-19]
|
||||
else:
|
||||
print B.bc.OKGREEN + "Found recommended sdk :" + B.bc.ENDC + " using MacOSX10.5.sdk"
|
||||
XCODE_BUNDLE=XCODE_SELECT_PATH
|
||||
|
||||
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --"
|
||||
print B.bc.OKGREEN + "Available SDK's: \n" + B.bc.ENDC + MACOSX_SDK_CHECK.replace('\t', '')
|
||||
|
||||
if env['MACOSX_SDK'] == '': # no set sdk, choosing best one found
|
||||
if 'OS X 10.9' in MACOSX_SDK_CHECK:
|
||||
env['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
|
||||
env['MACOSX_SDK']='/Developer/SDKs/MacOSX10.9.sdk'
|
||||
elif 'OS X 10.8' in MACOSX_SDK_CHECK:
|
||||
env['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
|
||||
env['MACOSX_SDK']='/Developer/SDKs/MacOSX10.8.sdk'
|
||||
elif 'OS X 10.7' in MACOSX_SDK_CHECK:
|
||||
env['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
|
||||
env['MACOSX_SDK']='/Developer/SDKs/MacOSX10.7.sdk'
|
||||
elif 'OS X 10.6' in MACOSX_SDK_CHECK:
|
||||
env['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
|
||||
env['MACOSX_SDK']='/Developer/SDKs/MacOSX10.6.sdk'
|
||||
elif 'OS X 10.5' in MACOSX_SDK_CHECK:
|
||||
env['MACOSX_DEPLOYMENT_TARGET'] = '10.5'
|
||||
env['MACOSX_SDK']='/Developer/SDKs/MacOSX10.5.sdk'
|
||||
else:
|
||||
env['MACOSX_SDK']='/Developer/SDKs/MacOSX' + env['MACOSX_SDK'] + '.sdk'
|
||||
|
||||
if env['XCODE_CUR_VER'] >= '4.3': ## since version 4.3, XCode and developer dir are bundled ##
|
||||
env['MACOSX_SDK'] = XCODE_BUNDLE + '/Contents/Developer/Platforms/MacOSX.platform' + env['MACOSX_SDK']
|
||||
|
||||
print B.bc.OKGREEN + "Using OSX SDK :" + B.bc.ENDC + env['MACOSX_SDK']
|
||||
|
||||
if env['XCODE_CUR_VER'] >= '5' and not (env['CXX'][:-2].endswith('4.6') or env['CXX'][:-2].endswith('4.8')):
|
||||
if not env['WITH_OSX_STATICPYTHON'] == 1:
|
||||
# python 3.3 uses Python-framework additionally installed in /Library/Frameworks
|
||||
env['BF_PYTHON'] = '/Library/Frameworks/Python.framework/Versions/'
|
||||
env['BF_PYTHON_INC'] = env['BF_PYTHON'] + env['BF_PYTHON_VERSION'] + '/include/python' + env['BF_PYTHON_VERSION'] + 'm'
|
||||
env['BF_PYTHON_BINARY'] = env['BF_PYTHON'] + env['BF_PYTHON_VERSION'] + '/bin/python' + env['BF_PYTHON_VERSION']
|
||||
env['BF_PYTHON_LIB'] = ''
|
||||
env['BF_PYTHON_LIBPATH'] = env['BF_PYTHON'] + env['BF_PYTHON_VERSION'] + '/lib/python' + env['BF_PYTHON_VERSION'] + '/config-' + env['BF_PYTHON_VERSION'] +'m'
|
||||
env['PLATFORM_LINKFLAGS'] = env['PLATFORM_LINKFLAGS']+['-framework','Python'] # link to python framework
|
||||
|
||||
#Ray trace optimization
|
||||
if env['WITH_BF_RAYOPTIMIZATION'] == 1:
|
||||
if env['MACOSX_ARCHITECTURE'] == 'x86_64' or env['MACOSX_ARCHITECTURE'] == 'i386':
|
||||
env['WITH_BF_RAYOPTIMIZATION'] = 1
|
||||
else:
|
||||
env['WITH_BF_RAYOPTIMIZATION'] = 0
|
||||
if env['MACOSX_ARCHITECTURE'] == 'i386':
|
||||
env['BF_RAYOPTIMIZATION_SSE_FLAGS'] = env['BF_RAYOPTIMIZATION_SSE_FLAGS']+['-msse']
|
||||
elif env['MACOSX_ARCHITECTURE'] == 'x86_64':
|
||||
env['BF_RAYOPTIMIZATION_SSE_FLAGS'] = env['BF_RAYOPTIMIZATION_SSE_FLAGS']+['-msse','-msse2']
|
||||
|
||||
if env['MACOSX_ARCHITECTURE'] == 'x86_64' or env['MACOSX_ARCHITECTURE'] == 'ppc64':
|
||||
ARCH_FLAGS = ['-m64']
|
||||
else:
|
||||
ARCH_FLAGS = ['-m32']
|
||||
|
||||
env.Append(CPPFLAGS=ARCH_FLAGS)
|
||||
|
||||
SDK_FLAGS=['-isysroot', env['MACOSX_SDK'],'-mmacosx-version-min='+ env['MACOSX_DEPLOYMENT_TARGET'],'-arch',env['MACOSX_ARCHITECTURE']] # always used
|
||||
env['PLATFORM_LINKFLAGS'] = ['-mmacosx-version-min='+ env['MACOSX_DEPLOYMENT_TARGET'],'-isysroot', env['MACOSX_SDK'],'-arch',env['MACOSX_ARCHITECTURE']]+ARCH_FLAGS+env['PLATFORM_LINKFLAGS']
|
||||
env['CCFLAGS']=SDK_FLAGS+env['CCFLAGS']
|
||||
env['CXXFLAGS']=SDK_FLAGS+env['CXXFLAGS']
|
||||
|
||||
#Intel Macs are CoreDuo and Up
|
||||
if env['MACOSX_ARCHITECTURE'] == 'i386' or env['MACOSX_ARCHITECTURE'] == 'x86_64':
|
||||
env['REL_CCFLAGS'] = env['REL_CCFLAGS']+['-ftree-vectorize','-msse','-msse2','-msse3']
|
||||
else:
|
||||
env['CCFLAGS'] = env['CCFLAGS']+['-fno-strict-aliasing']
|
||||
|
||||
# Intel 64bit Macs are Core2Duo and up
|
||||
if env['MACOSX_ARCHITECTURE'] == 'x86_64':
|
||||
env['REL_CCFLAGS'] = env['REL_CCFLAGS']+['-mssse3']
|
||||
|
||||
if env['XCODE_CUR_VER'] >= '5' and not env['CC'].split('/')[len(env['CC'].split('/'))-1][4:] >= '4.6.1':
|
||||
env['CCFLAGS'].append('-ftemplate-depth=1024') # only valid for clang bundled with xcode 5
|
||||
|
||||
# for now, Mac builders must download and install the 3DxWare 10 Beta 4 driver framework from 3Dconnexion
|
||||
# necessary header file lives here when installed:
|
||||
# /Library/Frameworks/3DconnexionClient.framework/Versions/Current/Headers/ConnexionClientAPI.h
|
||||
# 3DconnexionClient.framework, optionally install
|
||||
if env['WITH_BF_3DMOUSE'] == 1:
|
||||
if not os.path.exists('/Library/Frameworks/3DconnexionClient.framework'):
|
||||
print "3D_CONNEXION_CLIENT_LIBRARY not found, disabling WITH_BF_3DMOUSE" # avoid build errors !
|
||||
env['WITH_BF_3DMOUSE'] = 0
|
||||
print B.bc.OKGREEN + "3DconnexionClient install not found, disabling WITH_BF_3DMOUSE" # avoid build errors !
|
||||
else:
|
||||
env.Append(LINKFLAGS=['-F/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','3DconnexionClient'])
|
||||
env['BF_3DMOUSE_INC'] = '/Library/Frameworks/3DconnexionClient.framework/Headers'
|
||||
print B.bc.OKGREEN + "Using 3Dconnexion"
|
||||
|
||||
# for now, Mac builders must download and install the JackOSX framework
|
||||
# necessary header file lives here when installed:
|
||||
# /Library/Frameworks/Jackmp.framework/Versions/A/Headers/jack.h
|
||||
# Jackmp.framework, optionally install
|
||||
if env['WITH_BF_JACK'] == 1:
|
||||
if not os.path.exists('/Library/Frameworks/Jackmp.framework'):
|
||||
print "JackOSX install not found, disabling WITH_BF_JACK" # avoid build errors !
|
||||
env['WITH_BF_JACK'] = 0
|
||||
print B.bc.OKGREEN + "JackOSX install not found, disabling WITH_BF_JACK" # avoid build errors !
|
||||
else:
|
||||
env.Append(LINKFLAGS=['-F/Library/Frameworks','-Xlinker','-weak_framework','-Xlinker','Jackmp'])
|
||||
print B.bc.OKGREEN + "Using Jack"
|
||||
|
||||
if env['WITH_BF_QUICKTIME'] == 1:
|
||||
env['PLATFORM_LINKFLAGS'] = env['PLATFORM_LINKFLAGS']+['-framework','QTKit']
|
||||
|
||||
#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
|
||||
# if your compiler does not have accurate suffix you may have to enable it by hand !
|
||||
if env['WITH_BF_OPENMP'] == 1:
|
||||
if env['CC'].split('/')[len(env['CC'].split('/'))-1][4:] >= '4.6.1':
|
||||
env['WITH_BF_OPENMP'] = 1 # multithreading for fluids, cloth, sculpt and smoke
|
||||
print B.bc.OKGREEN + "Using OpenMP"
|
||||
else:
|
||||
env['WITH_BF_OPENMP'] = 0
|
||||
print B.bc.OKGREEN + "Disabled OpenMP, not supported by compiler"
|
||||
|
||||
if env['WITH_BF_CYCLES_OSL'] == 1:
|
||||
OSX_OSL_LIBPATH = Dir(env.subst(env['BF_OSL_LIBPATH'])).abspath
|
||||
# we need 2 variants of passing the oslexec with the force_load option, string and list type atm
|
||||
if env['CC'][:-2].endswith('4.8'):
|
||||
env.Append(LINKFLAGS=['-L'+OSX_OSL_LIBPATH,'-loslcomp','-loslexec','-loslquery'])
|
||||
if env['CC'].split('/')[len(env['CC'].split('/'))-1][4:] >= '4.8':
|
||||
env.Append(LINKFLAGS=['-L'+OSX_OSL_LIBPATH,'-loslcomp','-loslexec','-loslquery'])
|
||||
else:
|
||||
env.Append(LINKFLAGS=['-L'+OSX_OSL_LIBPATH,'-loslcomp','-force_load '+ OSX_OSL_LIBPATH +'/liboslexec.a','-loslquery'])
|
||||
env.Append(BF_PROGRAM_LINKFLAGS=['-Xlinker','-force_load','-Xlinker',OSX_OSL_LIBPATH +'/liboslexec.a'])
|
||||
|
||||
# Trying to get rid of eventually clashes, we export some explicite as local symbols
|
||||
# Trying to get rid of eventually clashes, we export some symbols explicite as local
|
||||
env.Append(LINKFLAGS=['-Xlinker','-unexported_symbols_list','-Xlinker','./source/creator/osx_locals.map'])
|
||||
|
||||
#for < 10.7.sdk, SystemStubs needs to be linked
|
||||
if env['MACOSX_SDK'].endswith("10.6.sdk") or env['MACOSX_SDK'].endswith("10.5.sdk"):
|
||||
env['LLIBS'].append('SystemStubs')
|
||||
|
||||
#############################################################################
|
||||
################### End Automatic configuration for OSX ##################
|
||||
#############################################################################
|
||||
|
||||
if env['WITH_BF_OPENMP'] == 1:
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||
@@ -342,12 +443,6 @@ if env['WITH_BF_OPENMP'] == 1:
|
||||
else:
|
||||
env.Append(CCFLAGS=['-fopenmp'])
|
||||
|
||||
if env['WITH_GHOST_COCOA'] == True:
|
||||
env.Append(CPPFLAGS=['-DGHOST_COCOA'])
|
||||
|
||||
if env['USE_QTKIT'] == True:
|
||||
env.Append(CPPFLAGS=['-DUSE_QTKIT'])
|
||||
|
||||
#check for additional debug libnames
|
||||
|
||||
if env.has_key('BF_DEBUG_LIBS'):
|
||||
@@ -689,6 +784,8 @@ if env['OURPLATFORM']=='darwin':
|
||||
dn.remove('.svn')
|
||||
if '_svn' in dn:
|
||||
dn.remove('_svn')
|
||||
if '.git' in df:
|
||||
df.remove('.git')
|
||||
dir=env['BF_INSTALLDIR']+dp[len(bundledir):]
|
||||
source=[dp+os.sep+f for f in df]
|
||||
blenderinstall.append(env.Install(dir=dir,source=source))
|
||||
@@ -718,10 +815,8 @@ if env['OURPLATFORM']!='darwin':
|
||||
scriptpaths=['release/scripts']
|
||||
for scriptpath in scriptpaths:
|
||||
for dp, dn, df in os.walk(scriptpath):
|
||||
if '.svn' in dn:
|
||||
dn.remove('.svn')
|
||||
if '_svn' in dn:
|
||||
dn.remove('_svn')
|
||||
if '.git' in df:
|
||||
df.remove('.git')
|
||||
if '__pycache__' in dn: # py3.2 cache dir
|
||||
dn.remove('__pycache__')
|
||||
|
||||
@@ -745,8 +840,6 @@ if env['OURPLATFORM']!='darwin':
|
||||
# cycles python code
|
||||
dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles')
|
||||
source=os.listdir('intern/cycles/blender/addon')
|
||||
if '.svn' in source: source.remove('.svn')
|
||||
if '_svn' in source: source.remove('_svn')
|
||||
if '__pycache__' in source: source.remove('__pycache__')
|
||||
source=['intern/cycles/blender/addon/'+s for s in source]
|
||||
scriptinstall.append(env.Install(dir=dir,source=source))
|
||||
@@ -754,8 +847,6 @@ if env['OURPLATFORM']!='darwin':
|
||||
# cycles kernel code
|
||||
dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'kernel')
|
||||
source=os.listdir('intern/cycles/kernel')
|
||||
if '.svn' in source: source.remove('.svn')
|
||||
if '_svn' in source: source.remove('_svn')
|
||||
if '__pycache__' in source: source.remove('__pycache__')
|
||||
source.remove('kernel.cpp')
|
||||
source.remove('CMakeLists.txt')
|
||||
@@ -772,16 +863,12 @@ if env['OURPLATFORM']!='darwin':
|
||||
# svm
|
||||
dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'kernel', 'svm')
|
||||
source=os.listdir('intern/cycles/kernel/svm')
|
||||
if '.svn' in source: source.remove('.svn')
|
||||
if '_svn' in source: source.remove('_svn')
|
||||
if '__pycache__' in source: source.remove('__pycache__')
|
||||
source=['intern/cycles/kernel/svm/'+s for s in source]
|
||||
scriptinstall.append(env.Install(dir=dir,source=source))
|
||||
# closure
|
||||
dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'kernel', 'closure')
|
||||
source=os.listdir('intern/cycles/kernel/closure')
|
||||
if '.svn' in source: source.remove('.svn')
|
||||
if '_svn' in source: source.remove('_svn')
|
||||
if '__pycache__' in source: source.remove('__pycache__')
|
||||
source=['intern/cycles/kernel/closure/'+s for s in source]
|
||||
scriptinstall.append(env.Install(dir=dir,source=source))
|
||||
@@ -789,8 +876,6 @@ if env['OURPLATFORM']!='darwin':
|
||||
# licenses
|
||||
dir=os.path.join(env['BF_INSTALLDIR'], VERSION, 'scripts', 'addons','cycles', 'license')
|
||||
source=os.listdir('intern/cycles/doc/license')
|
||||
if '.svn' in source: source.remove('.svn')
|
||||
if '_svn' in source: source.remove('_svn')
|
||||
if '__pycache__' in source: source.remove('__pycache__')
|
||||
source.remove('CMakeLists.txt')
|
||||
source=['intern/cycles/doc/license/'+s for s in source]
|
||||
@@ -825,11 +910,6 @@ if env['OURPLATFORM']!='darwin':
|
||||
colormanagement = os.path.join('release', 'datafiles', 'colormanagement')
|
||||
|
||||
for dp, dn, df in os.walk(colormanagement):
|
||||
if '.svn' in dn:
|
||||
dn.remove('.svn')
|
||||
if '_svn' in dn:
|
||||
dn.remove('_svn')
|
||||
|
||||
dir = os.path.join(env['BF_INSTALLDIR'], VERSION, 'datafiles')
|
||||
dir += os.sep + os.path.basename(colormanagement) + dp[len(colormanagement):]
|
||||
|
||||
@@ -847,15 +927,15 @@ if env['OURPLATFORM']!='darwin':
|
||||
def check_path(path, member):
|
||||
return (member in path.split(os.sep))
|
||||
|
||||
po_dir = os.path.join("release", "datafiles", "locale", "po")
|
||||
|
||||
for intpath in internationalpaths:
|
||||
for dp, dn, df in os.walk(intpath):
|
||||
if '.svn' in dn:
|
||||
dn.remove('.svn')
|
||||
if '_svn' in dn:
|
||||
dn.remove('_svn')
|
||||
if '.git' in df:
|
||||
df.remove('.git')
|
||||
|
||||
# we only care about release/datafiles/fonts, release/datafiles/locales
|
||||
if check_path(dp, "fonts") or check_path(dp, "locale"):
|
||||
if check_path(dp, "fonts"):
|
||||
pass
|
||||
else:
|
||||
continue
|
||||
@@ -869,16 +949,24 @@ if env['OURPLATFORM']!='darwin':
|
||||
env.Execute(Mkdir(dir))
|
||||
scriptinstall.append(env.Install(dir=dir,source=source))
|
||||
|
||||
for f in os.listdir(po_dir):
|
||||
if not f.endswith(".po"):
|
||||
continue
|
||||
|
||||
locale_name = os.path.splitext(f)[0]
|
||||
|
||||
mo_file = os.path.join(B.root_build_dir, "locale", locale_name + ".mo")
|
||||
|
||||
dir = os.path.join(env['BF_INSTALLDIR'], VERSION)
|
||||
dir = os.path.join(dir, "datafiles", "locale", locale_name, "LC_MESSAGES")
|
||||
scriptinstall.append(env.InstallAs(os.path.join(dir, "blender.mo"), mo_file))
|
||||
|
||||
#-- icons
|
||||
if env['OURPLATFORM']=='linux':
|
||||
iconlist = []
|
||||
icontargetlist = []
|
||||
|
||||
for tp, tn, tf in os.walk('release/freedesktop/icons'):
|
||||
if '.svn' in tn:
|
||||
tn.remove('.svn')
|
||||
if '_svn' in tn:
|
||||
tn.remove('_svn')
|
||||
for f in tf:
|
||||
iconlist.append(os.path.join(tp, f))
|
||||
icontargetlist.append( os.path.join(*([env['BF_INSTALLDIR']] + tp.split(os.sep)[2:] + [f])) )
|
||||
@@ -904,10 +992,6 @@ if env['OURPLATFORM']=='linuxcross':
|
||||
textlist = []
|
||||
texttargetlist = []
|
||||
for tp, tn, tf in os.walk('release/text'):
|
||||
if '.svn' in tn:
|
||||
tn.remove('.svn')
|
||||
if '_svn' in tn:
|
||||
tn.remove('_svn')
|
||||
for f in tf:
|
||||
textlist.append(tp+os.sep+f)
|
||||
|
||||
|
@@ -200,10 +200,10 @@ OCIO_VERSION_MIN="1.0"
|
||||
OCIO_FORCE_REBUILD=false
|
||||
OCIO_SKIP=false
|
||||
|
||||
OPENEXR_VERSION="2.0.0"
|
||||
OPENEXR_VERSION="2.0.1"
|
||||
OPENEXR_SOURCE="http://download.savannah.nongnu.org/releases/openexr/openexr-$OPENEXR_VERSION.tar.gz"
|
||||
OPENEXR_VERSION_MIN="2.0"
|
||||
ILMBASE_VERSION="2.0.0"
|
||||
ILMBASE_VERSION="2.0.1"
|
||||
ILMBASE_SOURCE="http://download.savannah.nongnu.org/releases/openexr/ilmbase-$ILMBASE_VERSION.tar.gz"
|
||||
OPENEXR_FORCE_REBUILD=false
|
||||
OPENEXR_SKIP=false
|
||||
@@ -855,7 +855,7 @@ clean_ILMBASE() {
|
||||
|
||||
compile_ILMBASE() {
|
||||
# To be changed each time we make edits that would modify the compiled result!
|
||||
ilmbase_magic=5
|
||||
ilmbase_magic=6
|
||||
_init_ilmbase
|
||||
|
||||
# Clean install if needed!
|
||||
@@ -958,7 +958,7 @@ clean_OPENEXR() {
|
||||
|
||||
compile_OPENEXR() {
|
||||
# To be changed each time we make edits that would modify the compiled result!
|
||||
openexr_magic=10
|
||||
openexr_magic=11
|
||||
|
||||
# Clean install if needed!
|
||||
magic_compile_check openexr-$OPENEXR_VERSION $openexr_magic
|
||||
@@ -1033,12 +1033,13 @@ compile_OPENEXR() {
|
||||
TARGET_LINK_LIBRARIES ( IlmImfFuzzTest IlmImf Iex Imath Half IlmThread ${PTHREAD_LIB} ${Z_LIB})
|
||||
--- a/IlmImfTest/CMakeLists.txt
|
||||
+++ b/IlmImfTest/CMakeLists.txt
|
||||
@@ -19,22 +19,26 @@
|
||||
@@ -19,22 +19,28 @@
|
||||
testCustomAttributes.cpp
|
||||
testDeepScanLineBasic.cpp
|
||||
testDeepScanLineHuge.cpp
|
||||
+ testDeepScanLineMultipleRead.cpp
|
||||
testDeepTiledBasic.cpp
|
||||
+ testBadTypeAttributes.cpp
|
||||
testExistingStreams.cpp
|
||||
+ testFutureProofing.cpp
|
||||
testHuf.cpp
|
||||
@@ -1056,6 +1057,7 @@ compile_OPENEXR() {
|
||||
testMultiView.cpp
|
||||
testNativeFormat.cpp
|
||||
+ testOptimized.cpp
|
||||
+ testOptimizedInterleavePatterns.cpp
|
||||
+ testPartHelper.cpp
|
||||
testPreviewImage.cpp
|
||||
testRgba.cpp
|
||||
@@ -1089,11 +1091,12 @@ compile_OPENEXR() {
|
||||
DESTINATION
|
||||
\${CMAKE_INSTALL_PREFIX}/lib
|
||||
)
|
||||
@@ -168,6 +167,7 @@
|
||||
@@ -168,6 +167,8 @@
|
||||
INSTALL ( FILES
|
||||
${CMAKE_SOURCE_DIR}/config/OpenEXRConfig.h
|
||||
ImfForward.h
|
||||
+ ImfNamespace.h
|
||||
+ ImfPartHelper.h
|
||||
ImfExport.h
|
||||
ImfAttribute.h
|
||||
ImfBoxAttribute.h
|
||||
|
@@ -1,425 +1,3 @@
|
||||
#
|
||||
# Note : if you want to alter this file
|
||||
# copy it as a whole in the upper folder
|
||||
# as user-config.py
|
||||
# dont create a new file with only some
|
||||
# vars changed.
|
||||
|
||||
import commands
|
||||
|
||||
# IMPORTANT NOTE : OFFICIAL BUILDS SHOULD BE DONE WITH SDKs
|
||||
USE_SDK=True
|
||||
|
||||
#############################################################################
|
||||
################### Cocoa & architecture settings ##################
|
||||
#############################################################################
|
||||
WITH_GHOST_COCOA=True
|
||||
MACOSX_ARCHITECTURE = 'i386' # valid archs: ppc, i386, ppc64, x86_64
|
||||
|
||||
|
||||
cmd = 'uname -p'
|
||||
MAC_PROC=commands.getoutput(cmd)
|
||||
cmd = 'uname -r'
|
||||
cmd_res=commands.getoutput(cmd)
|
||||
|
||||
if cmd_res[:1]=='7':
|
||||
MAC_CUR_VER='10.3'
|
||||
elif cmd_res[:1]=='8':
|
||||
MAC_CUR_VER='10.4'
|
||||
elif cmd_res[:1]=='9':
|
||||
MAC_CUR_VER='10.5'
|
||||
elif cmd_res[:2]=='10':
|
||||
MAC_CUR_VER='10.6'
|
||||
elif cmd_res[:2]=='11':
|
||||
MAC_CUR_VER='10.7'
|
||||
elif cmd_res[:2]=='12':
|
||||
MAC_CUR_VER='10.8'
|
||||
elif cmd_res[:2]=='13':
|
||||
MAC_CUR_VER='10.9'
|
||||
cmd = 'xcodebuild -version'
|
||||
cmd_xcode=commands.getoutput(cmd)
|
||||
XCODE_CUR_VER=cmd_xcode[6:][:3] # truncate output to major.minor version
|
||||
cmd = 'xcodebuild -showsdks'
|
||||
cmd_sdk=commands.getoutput(cmd)
|
||||
MACOSX_SDK_CHECK=cmd_sdk
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||
USE_QTKIT=True # Carbon quicktime is not available for 64bit
|
||||
|
||||
|
||||
# Default target OSX settings per architecture
|
||||
# Can be customized
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4':
|
||||
# all releases are now made for 10.5 !
|
||||
# MAC_MIN_VERS = '10.3'
|
||||
# MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
|
||||
# LCGDIR = '#../lib/darwin-6.1-powerpc'
|
||||
# CC = 'gcc-3.3'
|
||||
# CXX = 'g++-3.3'
|
||||
MAC_MIN_VERS = '10.4'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||
LCGDIR = '#../lib/darwin-8.0.0-powerpc'
|
||||
CC = 'gcc-4.0'
|
||||
CXX = 'g++-4.0'
|
||||
elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4':
|
||||
MAC_MIN_VERS = '10.4'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||
LCGDIR = '#../lib/darwin-8.x.i386'
|
||||
CC = 'gcc-4.0'
|
||||
CXX = 'g++-4.0'
|
||||
else :
|
||||
if 'Mac OS X 10.5' in MACOSX_SDK_CHECK:
|
||||
# OSX 10.5/6 with Xcode 3.x
|
||||
MAC_MIN_VERS = '10.5'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.5'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
elif 'Mac OS X 10.6' in MACOSX_SDK_CHECK:
|
||||
# OSX 10.6/7 with Xcode 4.x
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
else:
|
||||
# OSX 10.8 with Xcode 4.4 and higher (no 10.6sdk! )
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.7.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
|
||||
LIBDIR = '${LCGDIR}'
|
||||
|
||||
if XCODE_CUR_VER >= '4.3': ## since version 4.3, XCode and developer dir are bundled ##
|
||||
MACOSX_SDK = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform' + MACOSX_SDK
|
||||
|
||||
#############################################################################
|
||||
################### Dependency settings ##################
|
||||
#############################################################################
|
||||
|
||||
#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
|
||||
# if your compiler does not have accurate suffix you may have to enable it by hand !
|
||||
if CC[:-2].endswith('4.6'):
|
||||
WITH_BF_OPENMP = True # multithreading for fluids, cloth, sculpt and smoke
|
||||
else:
|
||||
WITH_BF_OPENMP = False
|
||||
|
||||
# enable ffmpeg support
|
||||
WITH_BF_FFMPEG = True
|
||||
BF_FFMPEG = LIBDIR + '/ffmpeg'
|
||||
BF_FFMPEG_INC = "${BF_FFMPEG}/include"
|
||||
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
||||
BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2'
|
||||
#bz2 is a standard osx dynlib
|
||||
|
||||
BF_PYTHON_VERSION = '3.3'
|
||||
WITH_OSX_STATICPYTHON = True
|
||||
|
||||
if WITH_OSX_STATICPYTHON:
|
||||
# python 3.3 uses precompiled libraries in bf svn /lib by default
|
||||
|
||||
BF_PYTHON = LIBDIR + '/python'
|
||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}m'
|
||||
# BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
||||
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}m'
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
|
||||
# BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
|
||||
else:
|
||||
# python 3.2 uses Python-framework additionally installed in /Library/Frameworks
|
||||
|
||||
BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
|
||||
BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}m'
|
||||
BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
|
||||
#BF_PYTHON_LIB = ''
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config-${BF_PYTHON_VERSION}m'
|
||||
|
||||
WITH_BF_OPENAL = True
|
||||
#different lib must be used following version of gcc
|
||||
# for gcc 3.3
|
||||
#BF_OPENAL = LIBDIR + '/openal'
|
||||
# for gcc 3.4 and ulterior
|
||||
if MAC_PROC == 'powerpc':
|
||||
BF_OPENAL = '#../lib/darwin-8.0.0-powerpc/openal'
|
||||
else :
|
||||
BF_OPENAL = LIBDIR + '/openal'
|
||||
|
||||
WITH_BF_STATICOPENAL = False
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include' # only headers from libdir needed for proper use of framework !!!!
|
||||
#BF_OPENAL_LIB = 'openal'
|
||||
#BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
|
||||
# Warning, this static lib configuration is untested! users of this OS please confirm.
|
||||
#BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
|
||||
|
||||
# Warning, this static lib configuration is untested! users of this OS please confirm.
|
||||
BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = False
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
# we use simply jack framework
|
||||
WITH_BF_JACK = True
|
||||
BF_JACK = '/Library/Frameworks/Jackmp.framework'
|
||||
BF_JACK_INC = '${BF_JACK}/headers'
|
||||
#BF_JACK_LIB = 'jack' # not used due framework
|
||||
BF_JACK_LIBPATH = '${BF_JACK}'
|
||||
|
||||
WITH_BF_SNDFILE = True
|
||||
BF_SNDFILE = LIBDIR + '/sndfile'
|
||||
BF_SNDFILE_INC = '${BF_SNDFILE}/include'
|
||||
BF_SNDFILE_LIB = 'sndfile FLAC ogg vorbis vorbisenc'
|
||||
BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib ${BF_FFMPEG}/lib' #ogg libs are stored in ffmpeg dir
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = LIBDIR + '/sdl' #$(shell sdl-config --prefix)
|
||||
BF_SDL_INC = '${BF_SDL}/include' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
|
||||
BF_SDL_LIB = 'SDL' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
|
||||
BF_SDL_LIBPATH = '${BF_SDL}/lib'
|
||||
|
||||
WITH_BF_OPENEXR = True
|
||||
WITH_BF_STATICOPENEXR = False
|
||||
BF_OPENEXR = '${LCGDIR}/openexr'
|
||||
BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
|
||||
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread'
|
||||
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
|
||||
# Warning, this static lib configuration is untested! users of this OS please confirm.
|
||||
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
|
||||
|
||||
WITH_BF_DDS = True
|
||||
|
||||
#Color Management System
|
||||
WITH_BF_LCMS = False
|
||||
BF_LCMS = LIBDIR + '/lcms'
|
||||
BF_LCMS_INC = '${BF_LCMS}/include'
|
||||
BF_LCMS_LIB = 'lcms'
|
||||
BF_LCMS_LIBPATH = '${BF_LCMS}/lib'
|
||||
|
||||
WITH_BF_JPEG = True
|
||||
BF_JPEG = LIBDIR + '/jpeg'
|
||||
BF_JPEG_INC = '${BF_JPEG}/include'
|
||||
BF_JPEG_LIB = 'jpeg'
|
||||
BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
|
||||
|
||||
WITH_BF_PNG = True
|
||||
BF_PNG = LIBDIR + '/png'
|
||||
BF_PNG_INC = '${BF_PNG}/include'
|
||||
BF_PNG_LIB = 'png'
|
||||
BF_PNG_LIBPATH = '${BF_PNG}/lib'
|
||||
|
||||
WITH_BF_TIFF = True
|
||||
BF_TIFF = LIBDIR + '/tiff'
|
||||
BF_TIFF_INC = '${BF_TIFF}/include'
|
||||
BF_TIFF_LIB = 'tiff'
|
||||
BF_TIFF_LIBPATH = '${BF_TIFF}/lib'
|
||||
|
||||
WITH_BF_ZLIB = True
|
||||
BF_ZLIB = '/usr'
|
||||
BF_ZLIB_INC = '${BF_ZLIB}/include'
|
||||
BF_ZLIB_LIB = 'z'
|
||||
|
||||
WITH_BF_INTERNATIONAL = True
|
||||
|
||||
WITH_BF_GAMEENGINE = True
|
||||
WITH_BF_PLAYER = True
|
||||
WITH_BF_OCEANSIM = True
|
||||
|
||||
WITH_BF_BULLET = True
|
||||
BF_BULLET = '#extern/bullet2/src'
|
||||
BF_BULLET_INC = '${BF_BULLET}'
|
||||
BF_BULLET_LIB = 'extern_bullet'
|
||||
|
||||
WITH_BF_FFTW3 = True
|
||||
BF_FFTW3 = LIBDIR + '/fftw3'
|
||||
BF_FFTW3_INC = '${BF_FFTW3}/include'
|
||||
BF_FFTW3_LIB = 'libfftw3'
|
||||
BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
|
||||
|
||||
BF_FREETYPE = LIBDIR + '/freetype'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = True
|
||||
|
||||
WITH_BF_ICONV = True
|
||||
BF_ICONV = '/usr'
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
BF_ICONV_LIB = 'iconv'
|
||||
#BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||
|
||||
# Mesa Libs should go here if your using them as well....
|
||||
WITH_BF_STATICOPENGL = True
|
||||
BF_OPENGL_LIB = 'GL GLU'
|
||||
BF_OPENGL_LIBPATH = '/System/Library/Frameworks/OpenGL.framework/Libraries'
|
||||
BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
|
||||
|
||||
#OpenCollada flags
|
||||
WITH_BF_COLLADA = True
|
||||
BF_COLLADA = '#source/blender/collada'
|
||||
BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils OpenCOLLADAStreamWriter MathMLSolver GeneratedSaxParser UTF xml2 buffer ftoa'
|
||||
BF_OPENCOLLADA_LIBPATH = LIBDIR + '/opencollada'
|
||||
BF_PCRE = LIBDIR + '/opencollada'
|
||||
BF_PCRE_LIB = 'pcre'
|
||||
BF_PCRE_LIBPATH = '${BF_PCRE}/lib'
|
||||
#BF_EXPAT = '/usr'
|
||||
#BF_EXPAT_LIB = 'expat'
|
||||
#BF_EXPAT_LIBPATH = '/usr/lib'
|
||||
|
||||
# Cycles
|
||||
WITH_BF_CYCLES = True
|
||||
|
||||
#OSL
|
||||
|
||||
WITH_BF_CYCLES_OSL = True
|
||||
BF_OSL = LIBDIR + '/osl'
|
||||
BF_OSL_INC = '${BF_OSL}/include'
|
||||
# note oslexec would passed via program linkflags, which is needed to
|
||||
# make llvm happy with osl_allocate_closure_component
|
||||
#BF_OSL_LIB = 'oslcomp oslquery'
|
||||
BF_OSL_LIBPATH = '${BF_OSL}/lib'
|
||||
BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
|
||||
|
||||
WITH_BF_LLVM = True
|
||||
BF_LLVM = LIBDIR + '/llvm'
|
||||
BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
|
||||
'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
|
||||
'LLVMTarget LLVMMC LLVMCore LLVMSupport'
|
||||
BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
|
||||
|
||||
WITH_BF_OIIO = True
|
||||
BF_OIIO = LIBDIR + '/openimageio'
|
||||
BF_OIIO_INC = '${BF_OIIO}/include'
|
||||
BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
|
||||
|
||||
WITH_BF_OCIO = True
|
||||
BF_OCIO = LIBDIR + '/opencolorio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB = 'OpenColorIO tinyxml yaml-cpp'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
BF_BOOST = LIBDIR + '/boost'
|
||||
BF_BOOST_INC = '${BF_BOOST}/include'
|
||||
BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt boost_wave-mt'
|
||||
BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mt'
|
||||
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = True
|
||||
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
|
||||
|
||||
#Freestyle
|
||||
WITH_BF_FREESTYLE = True
|
||||
|
||||
#Ray trace optimization
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'i386':
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
else:
|
||||
WITH_BF_RAYOPTIMIZATION = False
|
||||
if MACOSX_ARCHITECTURE == 'i386':
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
|
||||
elif MACOSX_ARCHITECTURE == 'x86_64':
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
|
||||
|
||||
# SpaceNavigator and related 3D mice, driver must be 3DxWare 10 Beta 4 (Mac OS X) or later !
|
||||
WITH_BF_3DMOUSE = True
|
||||
|
||||
#############################################################################
|
||||
################### various compile settings and flags ##################
|
||||
#############################################################################
|
||||
|
||||
BF_QUIET = '1' # suppress verbose output
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||
ARCH_FLAGS = ['-m64']
|
||||
else:
|
||||
ARCH_FLAGS = ['-m32']
|
||||
|
||||
CFLAGS = []
|
||||
CXXFLAGS = []
|
||||
CCFLAGS = ['-pipe','-funsigned-char']
|
||||
|
||||
CPPFLAGS = list(ARCH_FLAGS)
|
||||
|
||||
if WITH_GHOST_COCOA:
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
|
||||
if WITH_BF_QUICKTIME:
|
||||
if USE_QTKIT:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
|
||||
|
||||
if not WITH_OSX_STATICPYTHON:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
|
||||
|
||||
|
||||
#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
|
||||
#for > 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
|
||||
if MACOSX_SDK.endswith("10.7.sdk") or MACOSX_SDK.endswith("10.8.sdk") or MACOSX_SDK.endswith("10.9.sdk"):
|
||||
LLIBS = ['stdc++']
|
||||
else:
|
||||
LLIBS = ['stdc++', 'SystemStubs']
|
||||
|
||||
# some flags shuffling for different OS versions
|
||||
if MAC_MIN_VERS == '10.3':
|
||||
CCFLAGS = ['-fuse-cxa-atexit'] + CCFLAGS
|
||||
PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit'] + PLATFORM_LINKFLAGS
|
||||
LLIBS.append('crt3.o')
|
||||
|
||||
if USE_SDK:
|
||||
SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS,'-arch',MACOSX_ARCHITECTURE]
|
||||
PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-isysroot',MACOSX_SDK,'-arch',MACOSX_ARCHITECTURE]+PLATFORM_LINKFLAGS
|
||||
CCFLAGS=SDK_FLAGS+CCFLAGS
|
||||
CXXFLAGS=SDK_FLAGS+CXXFLAGS
|
||||
|
||||
#Intel Macs are CoreDuo and Up
|
||||
if MACOSX_ARCHITECTURE == 'i386' or MACOSX_ARCHITECTURE == 'x86_64':
|
||||
REL_CFLAGS = []
|
||||
REL_CXXFLAGS = []
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2','-ftree-vectorize','-msse','-msse2','-msse3','-mfpmath=sse']
|
||||
else:
|
||||
CCFLAGS += ['-fno-strict-aliasing']
|
||||
REL_CFLAGS = []
|
||||
REL_CXXFLAGS = []
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2']
|
||||
|
||||
# Intel 64bit Macs are Core2Duo and up
|
||||
if MACOSX_ARCHITECTURE == 'x86_64':
|
||||
REL_CCFLAGS += ['-march=core2','-mssse3','-with-tune=core2','-enable-threads']
|
||||
|
||||
CC_WARN = ['-Wall']
|
||||
C_WARN = ['-Wno-char-subscripts', '-Wpointer-arith', '-Wcast-align', '-Wdeclaration-after-statement', '-Wno-unknown-pragmas', '-Wstrict-prototypes']
|
||||
CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
|
||||
|
||||
##FIX_STUBS_WARNINGS = -Wno-unused
|
||||
|
||||
##LOPTS = --dynamic
|
||||
##DYNLDFLAGS = -shared $(LDFLAGS)
|
||||
|
||||
BF_PROFILE_CCFLAGS = ['-pg', '-g ']
|
||||
BF_PROFILE_LINKFLAGS = ['-pg']
|
||||
BF_PROFILE = False
|
||||
|
||||
BF_DEBUG = False
|
||||
BF_DEBUG_CCFLAGS = ['-g', '-D_DEBUG']
|
||||
|
||||
#############################################################################
|
||||
################### Output directories ##################
|
||||
#############################################################################
|
||||
|
||||
BF_BUILDDIR='../build/darwin'
|
||||
BF_INSTALLDIR='../install/darwin'
|
||||
|
@@ -1,425 +1,2 @@
|
||||
#
|
||||
# Note : if you want to alter this file
|
||||
# copy it as a whole in the upper folder
|
||||
# as user-config.py
|
||||
# dont create a new file with only some
|
||||
# vars changed.
|
||||
|
||||
import commands
|
||||
|
||||
# IMPORTANT NOTE : OFFICIAL BUILDS SHOULD BE DONE WITH SDKs
|
||||
USE_SDK=True
|
||||
|
||||
#############################################################################
|
||||
################### Cocoa & architecture settings ##################
|
||||
#############################################################################
|
||||
WITH_GHOST_COCOA=True
|
||||
MACOSX_ARCHITECTURE = 'x86_64' # valid archs: ppc, i386, ppc64, x86_64
|
||||
|
||||
|
||||
cmd = 'uname -p'
|
||||
MAC_PROC=commands.getoutput(cmd)
|
||||
cmd = 'uname -r'
|
||||
cmd_res=commands.getoutput(cmd)
|
||||
|
||||
if cmd_res[:1]=='7':
|
||||
MAC_CUR_VER='10.3'
|
||||
elif cmd_res[:1]=='8':
|
||||
MAC_CUR_VER='10.4'
|
||||
elif cmd_res[:1]=='9':
|
||||
MAC_CUR_VER='10.5'
|
||||
elif cmd_res[:2]=='10':
|
||||
MAC_CUR_VER='10.6'
|
||||
elif cmd_res[:2]=='11':
|
||||
MAC_CUR_VER='10.7'
|
||||
elif cmd_res[:2]=='12':
|
||||
MAC_CUR_VER='10.8'
|
||||
elif cmd_res[:2]=='13':
|
||||
MAC_CUR_VER='10.9'
|
||||
cmd = 'xcodebuild -version'
|
||||
cmd_xcode=commands.getoutput(cmd)
|
||||
XCODE_CUR_VER=cmd_xcode[6:][:3] # truncate output to major.minor version
|
||||
cmd = 'xcodebuild -showsdks'
|
||||
cmd_sdk=commands.getoutput(cmd)
|
||||
MACOSX_SDK_CHECK=cmd_sdk
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||
USE_QTKIT=True # Carbon quicktime is not available for 64bit
|
||||
|
||||
|
||||
# Default target OSX settings per architecture
|
||||
# Can be customized
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4':
|
||||
# all releases are now made for 10.5 !
|
||||
# MAC_MIN_VERS = '10.3'
|
||||
# MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
|
||||
# LCGDIR = '#../lib/darwin-6.1-powerpc'
|
||||
# CC = 'gcc-3.3'
|
||||
# CXX = 'g++-3.3'
|
||||
MAC_MIN_VERS = '10.4'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||
LCGDIR = '#../lib/darwin-8.0.0-powerpc'
|
||||
CC = 'gcc-4.0'
|
||||
CXX = 'g++-4.0'
|
||||
elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4':
|
||||
MAC_MIN_VERS = '10.4'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||
LCGDIR = '#../lib/darwin-8.x.i386'
|
||||
CC = 'gcc-4.0'
|
||||
CXX = 'g++-4.0'
|
||||
else :
|
||||
if 'Mac OS X 10.5' in MACOSX_SDK_CHECK:
|
||||
# OSX 10.5/6 with Xcode 3.x
|
||||
MAC_MIN_VERS = '10.5'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.5'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
elif 'Mac OS X 10.6' in MACOSX_SDK_CHECK:
|
||||
# OSX 10.6/7 with Xcode 4.x
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
else:
|
||||
# OSX 10.8 with Xcode 4.4 and higher (no 10.6sdk! )
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.7.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
|
||||
LIBDIR = '${LCGDIR}'
|
||||
|
||||
if XCODE_CUR_VER >= '4.3': ## since version 4.3, XCode and developer dir are bundled ##
|
||||
MACOSX_SDK = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform' + MACOSX_SDK
|
||||
|
||||
#############################################################################
|
||||
################### Dependency settings ##################
|
||||
#############################################################################
|
||||
|
||||
#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
|
||||
# if your compiler does not have accurate suffix you may have to enable it by hand !
|
||||
if CC[:-2].endswith('4.6'):
|
||||
WITH_BF_OPENMP = True # multithreading for fluids, cloth, sculpt and smoke
|
||||
else:
|
||||
WITH_BF_OPENMP = False
|
||||
|
||||
# enable ffmpeg support
|
||||
WITH_BF_FFMPEG = True
|
||||
BF_FFMPEG = LIBDIR + '/ffmpeg'
|
||||
BF_FFMPEG_INC = "${BF_FFMPEG}/include"
|
||||
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
||||
BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2'
|
||||
#bz2 is a standard osx dynlib
|
||||
|
||||
BF_PYTHON_VERSION = '3.3'
|
||||
WITH_OSX_STATICPYTHON = True
|
||||
|
||||
if WITH_OSX_STATICPYTHON:
|
||||
# python 3.3 uses precompiled libraries in bf svn /lib by default
|
||||
|
||||
BF_PYTHON = LIBDIR + '/python'
|
||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}m'
|
||||
# BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
||||
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}m'
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
|
||||
# BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
|
||||
else:
|
||||
# python 3.2 uses Python-framework additionally installed in /Library/Frameworks
|
||||
|
||||
BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
|
||||
BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}m'
|
||||
BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
|
||||
#BF_PYTHON_LIB = ''
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config-${BF_PYTHON_VERSION}m'
|
||||
|
||||
WITH_BF_OPENAL = True
|
||||
#different lib must be used following version of gcc
|
||||
# for gcc 3.3
|
||||
#BF_OPENAL = LIBDIR + '/openal'
|
||||
# for gcc 3.4 and ulterior
|
||||
if MAC_PROC == 'powerpc':
|
||||
BF_OPENAL = '#../lib/darwin-8.0.0-powerpc/openal'
|
||||
else :
|
||||
BF_OPENAL = LIBDIR + '/openal'
|
||||
|
||||
WITH_BF_STATICOPENAL = False
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include' # only headers from libdir needed for proper use of framework !!!!
|
||||
#BF_OPENAL_LIB = 'openal'
|
||||
#BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
|
||||
# Warning, this static lib configuration is untested! users of this OS please confirm.
|
||||
#BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
|
||||
|
||||
# Warning, this static lib configuration is untested! users of this OS please confirm.
|
||||
BF_CXX = '/usr'
|
||||
WITH_BF_STATICCXX = False
|
||||
BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
|
||||
|
||||
# we use simply jack framework
|
||||
WITH_BF_JACK = True
|
||||
BF_JACK = '/Library/Frameworks/Jackmp.framework'
|
||||
BF_JACK_INC = '${BF_JACK}/headers'
|
||||
#BF_JACK_LIB = 'jack' # not used due framework
|
||||
BF_JACK_LIBPATH = '${BF_JACK}'
|
||||
|
||||
WITH_BF_SNDFILE = True
|
||||
BF_SNDFILE = LIBDIR + '/sndfile'
|
||||
BF_SNDFILE_INC = '${BF_SNDFILE}/include'
|
||||
BF_SNDFILE_LIB = 'sndfile FLAC ogg vorbis vorbisenc'
|
||||
BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib ${BF_FFMPEG}/lib' #ogg libs are stored in ffmpeg dir
|
||||
|
||||
WITH_BF_SDL = True
|
||||
BF_SDL = LIBDIR + '/sdl' #$(shell sdl-config --prefix)
|
||||
BF_SDL_INC = '${BF_SDL}/include' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
|
||||
BF_SDL_LIB = 'SDL' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
|
||||
BF_SDL_LIBPATH = '${BF_SDL}/lib'
|
||||
|
||||
WITH_BF_OPENEXR = True
|
||||
WITH_BF_STATICOPENEXR = False
|
||||
BF_OPENEXR = '${LCGDIR}/openexr'
|
||||
BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
|
||||
BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread'
|
||||
BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
|
||||
# Warning, this static lib configuration is untested! users of this OS please confirm.
|
||||
BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
|
||||
|
||||
WITH_BF_DDS = True
|
||||
|
||||
#Color Management System
|
||||
WITH_BF_LCMS = False
|
||||
BF_LCMS = LIBDIR + '/lcms'
|
||||
BF_LCMS_INC = '${BF_LCMS}/include'
|
||||
BF_LCMS_LIB = 'lcms'
|
||||
BF_LCMS_LIBPATH = '${BF_LCMS}/lib'
|
||||
|
||||
WITH_BF_JPEG = True
|
||||
BF_JPEG = LIBDIR + '/jpeg'
|
||||
BF_JPEG_INC = '${BF_JPEG}/include'
|
||||
BF_JPEG_LIB = 'jpeg'
|
||||
BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
|
||||
|
||||
WITH_BF_PNG = True
|
||||
BF_PNG = LIBDIR + '/png'
|
||||
BF_PNG_INC = '${BF_PNG}/include'
|
||||
BF_PNG_LIB = 'png'
|
||||
BF_PNG_LIBPATH = '${BF_PNG}/lib'
|
||||
|
||||
WITH_BF_TIFF = True
|
||||
BF_TIFF = LIBDIR + '/tiff'
|
||||
BF_TIFF_INC = '${BF_TIFF}/include'
|
||||
BF_TIFF_LIB = 'tiff'
|
||||
BF_TIFF_LIBPATH = '${BF_TIFF}/lib'
|
||||
|
||||
WITH_BF_ZLIB = True
|
||||
BF_ZLIB = '/usr'
|
||||
BF_ZLIB_INC = '${BF_ZLIB}/include'
|
||||
BF_ZLIB_LIB = 'z'
|
||||
|
||||
WITH_BF_INTERNATIONAL = True
|
||||
|
||||
WITH_BF_GAMEENGINE = True
|
||||
WITH_BF_PLAYER = True
|
||||
WITH_BF_OCEANSIM = True
|
||||
|
||||
WITH_BF_BULLET = True
|
||||
BF_BULLET = '#extern/bullet2/src'
|
||||
BF_BULLET_INC = '${BF_BULLET}'
|
||||
BF_BULLET_LIB = 'extern_bullet'
|
||||
|
||||
WITH_BF_FFTW3 = True
|
||||
BF_FFTW3 = LIBDIR + '/fftw3'
|
||||
BF_FFTW3_INC = '${BF_FFTW3}/include'
|
||||
BF_FFTW3_LIB = 'libfftw3'
|
||||
BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
|
||||
|
||||
BF_FREETYPE = LIBDIR + '/freetype'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = True
|
||||
|
||||
WITH_BF_ICONV = True
|
||||
BF_ICONV = '/usr'
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
BF_ICONV_LIB = 'iconv'
|
||||
#BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
|
||||
|
||||
# Mesa Libs should go here if your using them as well....
|
||||
WITH_BF_STATICOPENGL = True
|
||||
BF_OPENGL_LIB = 'GL GLU'
|
||||
BF_OPENGL_LIBPATH = '/System/Library/Frameworks/OpenGL.framework/Libraries'
|
||||
BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
|
||||
|
||||
#OpenCollada flags
|
||||
WITH_BF_COLLADA = True
|
||||
BF_COLLADA = '#source/blender/collada'
|
||||
BF_COLLADA_INC = '${BF_COLLADA}'
|
||||
BF_COLLADA_LIB = 'bf_collada'
|
||||
BF_OPENCOLLADA = LIBDIR + '/opencollada'
|
||||
BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
|
||||
BF_OPENCOLLADA_LIB = 'OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils OpenCOLLADAStreamWriter MathMLSolver GeneratedSaxParser UTF xml2 buffer ftoa'
|
||||
BF_OPENCOLLADA_LIBPATH = LIBDIR + '/opencollada'
|
||||
BF_PCRE = LIBDIR + '/opencollada'
|
||||
BF_PCRE_LIB = 'pcre'
|
||||
BF_PCRE_LIBPATH = '${BF_PCRE}/lib'
|
||||
#BF_EXPAT = '/usr'
|
||||
#BF_EXPAT_LIB = 'expat'
|
||||
#BF_EXPAT_LIBPATH = '/usr/lib'
|
||||
|
||||
# Cycles
|
||||
WITH_BF_CYCLES = True
|
||||
|
||||
#OSL
|
||||
|
||||
WITH_BF_CYCLES_OSL = True
|
||||
BF_OSL = LIBDIR + '/osl'
|
||||
BF_OSL_INC = '${BF_OSL}/include'
|
||||
# note oslexec would passed via program linkflags, which is needed to
|
||||
# make llvm happy with osl_allocate_closure_component
|
||||
#BF_OSL_LIB = 'oslcomp oslquery'
|
||||
BF_OSL_LIBPATH = '${BF_OSL}/lib'
|
||||
BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
|
||||
|
||||
WITH_BF_LLVM = True
|
||||
BF_LLVM = LIBDIR + '/llvm'
|
||||
BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
|
||||
'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
|
||||
'LLVMTarget LLVMMC LLVMCore LLVMSupport'
|
||||
BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
|
||||
|
||||
WITH_BF_OIIO = True
|
||||
BF_OIIO = LIBDIR + '/openimageio'
|
||||
BF_OIIO_INC = '${BF_OIIO}/include'
|
||||
BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
|
||||
|
||||
WITH_BF_OCIO = True
|
||||
BF_OCIO = LIBDIR + '/opencolorio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB = 'OpenColorIO tinyxml yaml-cpp'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
BF_BOOST = LIBDIR + '/boost'
|
||||
BF_BOOST_INC = '${BF_BOOST}/include'
|
||||
BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt boost_wave-mt'
|
||||
BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mt'
|
||||
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = True
|
||||
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
|
||||
|
||||
#Freestyle
|
||||
WITH_BF_FREESTYLE = True
|
||||
|
||||
#Ray trace optimization
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'i386':
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
else:
|
||||
WITH_BF_RAYOPTIMIZATION = False
|
||||
if MACOSX_ARCHITECTURE == 'i386':
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
|
||||
elif MACOSX_ARCHITECTURE == 'x86_64':
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
|
||||
|
||||
# SpaceNavigator and related 3D mice, driver must be 3DxWare 10 Beta 4 (Mac OS X) or later !
|
||||
WITH_BF_3DMOUSE = True
|
||||
|
||||
#############################################################################
|
||||
################### various compile settings and flags ##################
|
||||
#############################################################################
|
||||
|
||||
BF_QUIET = '1' # suppress verbose output
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||
ARCH_FLAGS = ['-m64']
|
||||
else:
|
||||
ARCH_FLAGS = ['-m32']
|
||||
|
||||
CFLAGS = []
|
||||
CXXFLAGS = []
|
||||
CCFLAGS = ['-pipe','-funsigned-char']
|
||||
|
||||
CPPFLAGS = list(ARCH_FLAGS)
|
||||
|
||||
if WITH_GHOST_COCOA:
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
|
||||
if WITH_BF_QUICKTIME:
|
||||
if USE_QTKIT:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
|
||||
|
||||
if not WITH_OSX_STATICPYTHON:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
|
||||
|
||||
|
||||
#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
|
||||
#for > 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
|
||||
if MACOSX_SDK.endswith("10.7.sdk") or MACOSX_SDK.endswith("10.8.sdk") or MACOSX_SDK.endswith("10.9.sdk"):
|
||||
LLIBS = ['stdc++']
|
||||
else:
|
||||
LLIBS = ['stdc++', 'SystemStubs']
|
||||
|
||||
# some flags shuffling for different OS versions
|
||||
if MAC_MIN_VERS == '10.3':
|
||||
CCFLAGS = ['-fuse-cxa-atexit'] + CCFLAGS
|
||||
PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit'] + PLATFORM_LINKFLAGS
|
||||
LLIBS.append('crt3.o')
|
||||
|
||||
if USE_SDK:
|
||||
SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS,'-arch',MACOSX_ARCHITECTURE]
|
||||
PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-isysroot',MACOSX_SDK,'-arch',MACOSX_ARCHITECTURE]+PLATFORM_LINKFLAGS
|
||||
CCFLAGS=SDK_FLAGS+CCFLAGS
|
||||
CXXFLAGS=SDK_FLAGS+CXXFLAGS
|
||||
|
||||
#Intel Macs are CoreDuo and Up
|
||||
if MACOSX_ARCHITECTURE == 'i386' or MACOSX_ARCHITECTURE == 'x86_64':
|
||||
REL_CFLAGS = []
|
||||
REL_CXXFLAGS = []
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2','-ftree-vectorize','-msse','-msse2','-msse3','-mfpmath=sse']
|
||||
else:
|
||||
CCFLAGS += ['-fno-strict-aliasing']
|
||||
REL_CFLAGS = []
|
||||
REL_CXXFLAGS = []
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2']
|
||||
|
||||
# Intel 64bit Macs are Core2Duo and up
|
||||
if MACOSX_ARCHITECTURE == 'x86_64':
|
||||
REL_CCFLAGS += ['-march=core2','-mssse3','-with-tune=core2','-enable-threads']
|
||||
|
||||
CC_WARN = ['-Wall']
|
||||
C_WARN = ['-Wno-char-subscripts', '-Wpointer-arith', '-Wcast-align', '-Wdeclaration-after-statement', '-Wno-unknown-pragmas', '-Wstrict-prototypes']
|
||||
CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
|
||||
|
||||
##FIX_STUBS_WARNINGS = -Wno-unused
|
||||
|
||||
##LOPTS = --dynamic
|
||||
##DYNLDFLAGS = -shared $(LDFLAGS)
|
||||
|
||||
BF_PROFILE_CCFLAGS = ['-pg', '-g ']
|
||||
BF_PROFILE_LINKFLAGS = ['-pg']
|
||||
BF_PROFILE = False
|
||||
|
||||
BF_DEBUG = False
|
||||
BF_DEBUG_CCFLAGS = ['-g', '-D_DEBUG']
|
||||
|
||||
#############################################################################
|
||||
################### Output directories ##################
|
||||
#############################################################################
|
||||
|
||||
BF_BUILDDIR='../build/darwin'
|
||||
BF_INSTALLDIR='../install/darwin'
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = True
|
@@ -26,9 +26,10 @@ c['slavePortnum'] = 9989
|
||||
# CHANGE SOURCES
|
||||
|
||||
from buildbot.changes.svnpoller import SVNPoller
|
||||
from buildbot.changes.gitpoller import GitPoller
|
||||
|
||||
c['change_source'] = SVNPoller(
|
||||
'https://svn.blender.org/svnroot/bf-blender/trunk/',
|
||||
c['change_source'] = GitPoller(
|
||||
'git://git.blender.org/blender.git',
|
||||
pollinterval=1200)
|
||||
|
||||
# SCHEDULERS
|
||||
@@ -70,6 +71,7 @@ for i in range(0, schedule_cycle):
|
||||
|
||||
from buildbot.process.factory import BuildFactory
|
||||
from buildbot.steps.source import SVN
|
||||
from buildbot.steps.source import Git
|
||||
from buildbot.steps.shell import ShellCommand
|
||||
from buildbot.steps.shell import Compile
|
||||
from buildbot.steps.shell import Test
|
||||
@@ -100,12 +102,18 @@ def add_builder(c, name, libdir, factory, branch='', rsync=False, hour=3, minute
|
||||
|
||||
# common steps
|
||||
|
||||
def git_submodule_step(submodule):
|
||||
return Git(name=submodule+'.git', repourl='git://git.blender.org/' + submodule + '.git', mode='update', workdir=submodule + '.git')
|
||||
|
||||
def svn_step(branch=''):
|
||||
def git_step(branch=''):
|
||||
if branch:
|
||||
return SVN(baseURL='https://svn.blender.org/svnroot/bf-blender/branches/%%BRANCH%%', mode='update', defaultBranch=branch, workdir='blender')
|
||||
return Git(name='blender.git', repourl='git://git.blender.org/blender.git', mode='update', branch=branch, workdir='blender.git', submodules=True)
|
||||
else:
|
||||
return SVN(baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/blender', mode='update', defaultBranch='trunk', workdir='blender')
|
||||
return Git(name='blender.git', repourl='git://git.blender.org/blender.git', mode='update', workdir='blender.git', submodules=True)
|
||||
|
||||
def git_submodules_update():
|
||||
command = ['git', 'submodule', 'foreach', '--recursive', 'git', 'pull', 'origin', 'master']
|
||||
return ShellCommand(name='Submodules Update', command=command, description='updating', descriptionDone='up to date', workdir='blender.git')
|
||||
|
||||
def lib_svn_step(dir):
|
||||
return SVN(name='lib svn', baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir, mode='update', defaultBranch='trunk', workdir='lib/' + dir)
|
||||
@@ -118,14 +126,17 @@ def rsync_step(id, branch, rsync_script):
|
||||
|
||||
def generic_builder(id, libdir='', branch='', rsync=False):
|
||||
filename = 'uploaded/buildbot_upload_' + id + '.zip'
|
||||
compile_script = '../blender/build_files/buildbot/slave_compile.py'
|
||||
test_script = '../blender/build_files/buildbot/slave_test.py'
|
||||
pack_script = '../blender/build_files/buildbot/slave_pack.py'
|
||||
rsync_script = '../blender/build_files/buildbot/slave_rsync.py'
|
||||
compile_script = '../blender.git/build_files/buildbot/slave_compile.py'
|
||||
test_script = '../blender.git/build_files/buildbot/slave_test.py'
|
||||
pack_script = '../blender.git/build_files/buildbot/slave_pack.py'
|
||||
rsync_script = '../blender.git/build_files/buildbot/slave_rsync.py'
|
||||
unpack_script = 'master_unpack.py'
|
||||
|
||||
f = BuildFactory()
|
||||
f.addStep(svn_step(branch))
|
||||
for submodule in ('blender-translations', 'blender-addons', 'blender-addons-contrib', 'scons'):
|
||||
f.addStep(git_submodule_step(submodule))
|
||||
f.addStep(git_step(branch))
|
||||
f.addStep(git_submodules_update())
|
||||
if libdir != '':
|
||||
f.addStep(lib_svn_step(libdir))
|
||||
|
||||
@@ -149,6 +160,8 @@ add_builder(c, 'linux_glibc211_i386_scons', '', generic_builder, hour=1)
|
||||
add_builder(c, 'linux_glibc211_x86_64_scons', '', generic_builder, hour=2)
|
||||
add_builder(c, 'win32_scons', 'windows', generic_builder, hour=1)
|
||||
add_builder(c, 'win64_scons', 'win64', generic_builder, hour=2)
|
||||
add_builder(c, 'win32_scons_vc2012', 'windows_vc11', generic_builder, hour=1)
|
||||
add_builder(c, 'win64_scons_vc2012', 'win64_vc11', generic_builder, hour=2)
|
||||
#add_builder(c, 'mingw_win32_scons', 'mingw32', generic_builder, hour=4)
|
||||
add_builder(c, 'mingw_win64_scons', 'mingw64', generic_builder, hour=3)
|
||||
#add_builder(c, 'freebsd_i386_cmake', '', generic_builder, hour=1)
|
||||
|
@@ -31,7 +31,7 @@ if len(sys.argv) < 2:
|
||||
builder = sys.argv[1]
|
||||
|
||||
# we run from build/ directory
|
||||
blender_dir = '../blender'
|
||||
blender_dir = '../blender.git'
|
||||
|
||||
if builder.find('cmake') != -1:
|
||||
# cmake
|
||||
|
@@ -40,7 +40,7 @@ if len(sys.argv) >= 3:
|
||||
|
||||
# scons does own packaging
|
||||
if builder.find('scons') != -1:
|
||||
os.chdir('../blender')
|
||||
os.chdir('../blender.git')
|
||||
scons_options = ['BF_QUICK=slnt', 'BUILDBOT_BRANCH=' + branch, 'buildslave', 'BF_FANCY=False']
|
||||
|
||||
buildbot_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
@@ -29,7 +29,7 @@ if len(sys.argv) < 2:
|
||||
builder = sys.argv[1]
|
||||
|
||||
# we run from build/ directory
|
||||
blender_dir = '../blender'
|
||||
blender_dir = '../blender.git'
|
||||
|
||||
if "cmake" in builder:
|
||||
# cmake
|
||||
|
@@ -1,16 +1,57 @@
|
||||
# This is called by cmake as an extermal process from
|
||||
# ./source/creator/CMakeLists.txt to write ./source/creator/buildinfo.h
|
||||
|
||||
# The FindSubversion.cmake module is part of the standard distribution
|
||||
include(FindSubversion)
|
||||
|
||||
# Extract working copy information for SOURCE_DIR into MY_XXX variables
|
||||
# with a default in case anything fails, for examble when using git-svn
|
||||
set(MY_WC_REVISION "unknown")
|
||||
set(MY_WC_HASH "unknown")
|
||||
set(MY_WC_BRANCH "unknown")
|
||||
set(MY_WC_COMMIT_TIMESTAMP 0)
|
||||
|
||||
# Guess if this is a SVN working copy and then look up the revision
|
||||
if(EXISTS ${SOURCE_DIR}/.svn/)
|
||||
if(Subversion_FOUND)
|
||||
Subversion_WC_INFO(${SOURCE_DIR} MY)
|
||||
if(EXISTS ${SOURCE_DIR}/.git/)
|
||||
# The FindSubversion.cmake module is part of the standard distribution
|
||||
include(FindGit)
|
||||
if(GIT_FOUND)
|
||||
execute_process(COMMAND git rev-parse --short HEAD
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE MY_WC_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(COMMAND git rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE MY_WC_BRANCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(COMMAND git log -1 --format=%ct
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE MY_WC_COMMIT_TIMESTAMP
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# Update GIT index before getting dirty files
|
||||
execute_process(COMMAND git update-index -q --refresh
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(COMMAND git diff-index --name-only HEAD --
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE _git_changed_files
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(NOT _git_changed_files STREQUAL "")
|
||||
set(MY_WC_BRANCH "${MY_WC_BRANCH} (modified)")
|
||||
else()
|
||||
# Unpushed commits are also considered local odifications
|
||||
execute_process(COMMAND git log @{u}..
|
||||
WORKING_DIRECTORY ${SOURCE_DIR}
|
||||
OUTPUT_VARIABLE _git_unpushed_log
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT _git_unpushed_log STREQUAL "")
|
||||
set(MY_WC_BRANCH "${MY_WC_BRANCH} (modified)")
|
||||
endif()
|
||||
unset(_git_unpushed_log)
|
||||
endif()
|
||||
|
||||
unset(_git_changed_files)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -27,7 +68,9 @@ endif()
|
||||
|
||||
# Write a file with the SVNVERSION define
|
||||
file(WRITE buildinfo.h.txt
|
||||
"#define BUILD_REV \"${MY_WC_REVISION}\"\n"
|
||||
"#define BUILD_HASH \"${MY_WC_HASH}\"\n"
|
||||
"#define BUILD_COMMIT_TIMESTAMP ${MY_WC_COMMIT_TIMESTAMP}\n"
|
||||
"#define BUILD_BRANCH \"${MY_WC_BRANCH}\"\n"
|
||||
"#define BUILD_DATE \"${BUILD_DATE}\"\n"
|
||||
"#define BUILD_TIME \"${BUILD_TIME}\"\n"
|
||||
)
|
||||
|
@@ -48,6 +48,24 @@ macro(list_insert_before
|
||||
unset(_index)
|
||||
endmacro()
|
||||
|
||||
function (list_assert_duplicates
|
||||
list_id
|
||||
)
|
||||
|
||||
# message(STATUS "list data: ${list_id}")
|
||||
|
||||
list(LENGTH list_id _len_before)
|
||||
list(REMOVE_DUPLICATES list_id)
|
||||
list(LENGTH list_id _len_after)
|
||||
# message(STATUS "list size ${_len_before} -> ${_len_after}")
|
||||
if(NOT _len_before EQUAL _len_after)
|
||||
message(FATAL_ERROR "duplicate found in list which should not contain duplicates: ${list_id}")
|
||||
endif()
|
||||
unset(_len_before)
|
||||
unset(_len_after)
|
||||
endfunction()
|
||||
|
||||
|
||||
# foo_bar.spam --> foo_barMySuffix.spam
|
||||
macro(file_suffix
|
||||
file_name_new file_name file_suffix
|
||||
@@ -177,6 +195,11 @@ macro(blender_add_lib_nolist
|
||||
# listed is helpful for IDE's (QtCreator/MSVC)
|
||||
blender_source_group("${sources}")
|
||||
|
||||
list_assert_duplicates("${sources}")
|
||||
list_assert_duplicates("${includes}")
|
||||
# Not for system includes because they can resolve to the same path
|
||||
# list_assert_duplicates("${includes_sys}")
|
||||
|
||||
endmacro()
|
||||
|
||||
|
||||
@@ -847,3 +870,31 @@ macro(svg_to_png
|
||||
unset(_file_to)
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(msgfmt_simple
|
||||
file_from
|
||||
list_to_add)
|
||||
|
||||
# remove ../'s
|
||||
get_filename_component(_file_from_we ${file_from} NAME_WE)
|
||||
|
||||
get_filename_component(_file_from ${file_from} REALPATH)
|
||||
get_filename_component(_file_to ${CMAKE_CURRENT_BINARY_DIR}/${_file_from_we}.mo REALPATH)
|
||||
|
||||
list(APPEND ${list_to_add} ${_file_to})
|
||||
|
||||
get_filename_component(_file_to_path ${_file_to} PATH)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${_file_to}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/msgfmt ${_file_from} ${_file_to}
|
||||
DEPENDS msgfmt)
|
||||
|
||||
set_source_files_properties(${_file_to} PROPERTIES GENERATED TRUE)
|
||||
|
||||
unset(_file_from_we)
|
||||
unset(_file_from)
|
||||
unset(_file_to)
|
||||
unset(_file_to_path)
|
||||
endmacro()
|
||||
|
@@ -1,123 +1,23 @@
|
||||
#
|
||||
# Note : if you want to alter this file
|
||||
# copy it as a whole in the upper folder
|
||||
# as user-config.py
|
||||
# dont create a new file with only some
|
||||
# vars changed.
|
||||
|
||||
import commands
|
||||
|
||||
# IMPORTANT NOTE : OFFICIAL BUILDS SHOULD BE DONE WITH SDKs
|
||||
USE_SDK=True
|
||||
|
||||
#############################################################################
|
||||
################### Cocoa & architecture settings ##################
|
||||
################### Compiler & architecture settings ##################
|
||||
#############################################################################
|
||||
WITH_GHOST_COCOA=True
|
||||
MACOSX_ARCHITECTURE = 'i386' # valid archs: ppc, i386, ppc64, x86_64
|
||||
|
||||
MACOSX_ARCHITECTURE = 'x86_64' # valid archs: ppc, i386, ppc64, x86_64
|
||||
MACOSX_SDK='' # set an sdk name like '10.7' or leave empty for automatic choosing highest available
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
|
||||
cmd = 'uname -p'
|
||||
MAC_PROC=commands.getoutput(cmd)
|
||||
cmd = 'uname -r'
|
||||
cmd_res=commands.getoutput(cmd)
|
||||
|
||||
if cmd_res[:1]=='7':
|
||||
MAC_CUR_VER='10.3'
|
||||
elif cmd_res[:1]=='8':
|
||||
MAC_CUR_VER='10.4'
|
||||
elif cmd_res[:1]=='9':
|
||||
MAC_CUR_VER='10.5'
|
||||
elif cmd_res[:2]=='10':
|
||||
MAC_CUR_VER='10.6'
|
||||
elif cmd_res[:2]=='11':
|
||||
MAC_CUR_VER='10.7'
|
||||
elif cmd_res[:2]=='12':
|
||||
MAC_CUR_VER='10.8'
|
||||
elif cmd_res[:2]=='13':
|
||||
MAC_CUR_VER='10.9'
|
||||
cmd = 'xcodebuild -version'
|
||||
cmd_xcode=commands.getoutput(cmd)
|
||||
XCODE_CUR_VER=cmd_xcode[6:][:3] # truncate output to major.minor version
|
||||
cmd = 'xcodebuild -showsdks'
|
||||
cmd_sdk=commands.getoutput(cmd)
|
||||
MACOSX_SDK_CHECK=cmd_sdk
|
||||
cmd = 'xcode-select --print-path'
|
||||
XCODE_SELECT_PATH=commands.getoutput(cmd)
|
||||
if XCODE_SELECT_PATH.endswith("/Contents/Developer"):
|
||||
XCODE_BUNDLE=XCODE_SELECT_PATH[:-19]
|
||||
else:
|
||||
XCODE_BUNDLE=XCODE_SELECT_PATH
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||
USE_QTKIT=True # Carbon quicktime is not available for 64bit
|
||||
|
||||
|
||||
# Default target OSX settings per architecture
|
||||
# Can be customized
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4':
|
||||
# all releases are now made for 10.5 !
|
||||
# MAC_MIN_VERS = '10.3'
|
||||
# MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
|
||||
# LCGDIR = '#../lib/darwin-6.1-powerpc'
|
||||
# CC = 'gcc-3.3'
|
||||
# CXX = 'g++-3.3'
|
||||
MAC_MIN_VERS = '10.4'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||
LCGDIR = '#../lib/darwin-8.0.0-powerpc'
|
||||
CC = 'gcc-4.0'
|
||||
CXX = 'g++-4.0'
|
||||
elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4':
|
||||
MAC_MIN_VERS = '10.4'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||
LCGDIR = '#../lib/darwin-8.x.i386'
|
||||
CC = 'gcc-4.0'
|
||||
CXX = 'g++-4.0'
|
||||
else :
|
||||
if 'Mac OS X 10.5' in MACOSX_SDK_CHECK:
|
||||
# OSX 10.5/6 with Xcode 3.x
|
||||
MAC_MIN_VERS = '10.5'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.5'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
elif 'Mac OS X 10.6' in MACOSX_SDK_CHECK:
|
||||
# OSX 10.6/7 with Xcode 4.x
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
else:
|
||||
# OSX 10.8 with Xcode 4.4 and higher (no 10.6sdk! )
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.7.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
|
||||
# gcc always defaults to the system standard compiler linked by a shim or symlink
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
LIBDIR = '${LCGDIR}'
|
||||
|
||||
if XCODE_CUR_VER >= '4.3': ## since version 4.3, XCode and developer dir are bundled ##
|
||||
MACOSX_SDK = XCODE_BUNDLE + '/Contents/Developer/Platforms/MacOSX.platform' + MACOSX_SDK
|
||||
|
||||
#############################################################################
|
||||
################### Dependency settings ##################
|
||||
#############################################################################
|
||||
|
||||
#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
|
||||
# if your compiler does not have accurate suffix you may have to enable it by hand !
|
||||
if CC[:-2].endswith('4.6') or CC[:-2].endswith('4.8'):
|
||||
WITH_BF_OPENMP = True # multithreading for fluids, cloth, sculpt and smoke
|
||||
else:
|
||||
WITH_BF_OPENMP = False
|
||||
|
||||
# enable ffmpeg support
|
||||
WITH_BF_FFMPEG = True
|
||||
BF_FFMPEG = LIBDIR + '/ffmpeg'
|
||||
@@ -129,33 +29,16 @@ BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore
|
||||
BF_PYTHON_VERSION = '3.3'
|
||||
WITH_OSX_STATICPYTHON = True
|
||||
|
||||
if WITH_OSX_STATICPYTHON:
|
||||
# python 3.3 uses precompiled libraries in bf svn /lib by default
|
||||
|
||||
BF_PYTHON = LIBDIR + '/python'
|
||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}m'
|
||||
# BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
||||
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}m'
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
|
||||
# BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
|
||||
else:
|
||||
# python 3.2 uses Python-framework additionally installed in /Library/Frameworks
|
||||
|
||||
BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
|
||||
BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}m'
|
||||
BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
|
||||
#BF_PYTHON_LIB = ''
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config-${BF_PYTHON_VERSION}m'
|
||||
# python 3.3 uses precompiled libraries in bf svn /lib by default
|
||||
BF_PYTHON = LIBDIR + '/python'
|
||||
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}m'
|
||||
# BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
|
||||
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}m'
|
||||
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
|
||||
# BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
|
||||
|
||||
WITH_BF_OPENAL = True
|
||||
#different lib must be used following version of gcc
|
||||
# for gcc 3.3
|
||||
#BF_OPENAL = LIBDIR + '/openal'
|
||||
# for gcc 3.4 and ulterior
|
||||
if MAC_PROC == 'powerpc':
|
||||
BF_OPENAL = '#../lib/darwin-8.0.0-powerpc/openal'
|
||||
else :
|
||||
BF_OPENAL = LIBDIR + '/openal'
|
||||
BF_OPENAL = LIBDIR + '/openal'
|
||||
|
||||
WITH_BF_STATICOPENAL = False
|
||||
BF_OPENAL_INC = '${BF_OPENAL}/include' # only headers from libdir needed for proper use of framework !!!!
|
||||
@@ -328,15 +211,12 @@ BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30', 'sm_35']
|
||||
#Freestyle
|
||||
WITH_BF_FREESTYLE = True
|
||||
|
||||
#OpenMP ( will be checked for compiler support and turned off eventually )
|
||||
WITH_BF_OPENMP = True
|
||||
|
||||
#Ray trace optimization
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'i386':
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
else:
|
||||
WITH_BF_RAYOPTIMIZATION = False
|
||||
if MACOSX_ARCHITECTURE == 'i386':
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
|
||||
elif MACOSX_ARCHITECTURE == 'x86_64':
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = []
|
||||
|
||||
# SpaceNavigator and related 3D mice, driver must be 3DxWare 10 Beta 4 (Mac OS X) or later !
|
||||
WITH_BF_3DMOUSE = True
|
||||
@@ -347,66 +227,18 @@ WITH_BF_3DMOUSE = True
|
||||
|
||||
BF_QUIET = '1' # suppress verbose output
|
||||
|
||||
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||
ARCH_FLAGS = ['-m64']
|
||||
else:
|
||||
ARCH_FLAGS = ['-m32']
|
||||
|
||||
CFLAGS = []
|
||||
CXXFLAGS = []
|
||||
CCFLAGS = ['-pipe','-funsigned-char']
|
||||
CPPFLAGS = []
|
||||
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']
|
||||
|
||||
CPPFLAGS = list(ARCH_FLAGS)
|
||||
LLIBS = ['stdc++']
|
||||
|
||||
if WITH_GHOST_COCOA:
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
|
||||
|
||||
if WITH_BF_QUICKTIME:
|
||||
if USE_QTKIT:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||
else:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
|
||||
|
||||
if not WITH_OSX_STATICPYTHON:
|
||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
|
||||
|
||||
|
||||
#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
|
||||
#for > 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
|
||||
if MACOSX_SDK.endswith("10.7.sdk") or MACOSX_SDK.endswith("10.8.sdk") or MACOSX_SDK.endswith("10.9.sdk"):
|
||||
LLIBS = ['stdc++']
|
||||
else:
|
||||
LLIBS = ['stdc++', 'SystemStubs']
|
||||
|
||||
# some flags shuffling for different OS versions
|
||||
if MAC_MIN_VERS == '10.3':
|
||||
CCFLAGS = ['-fuse-cxa-atexit'] + CCFLAGS
|
||||
PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit'] + PLATFORM_LINKFLAGS
|
||||
LLIBS.append('crt3.o')
|
||||
|
||||
if USE_SDK:
|
||||
SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS,'-arch',MACOSX_ARCHITECTURE]
|
||||
PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-isysroot',MACOSX_SDK,'-arch',MACOSX_ARCHITECTURE]+PLATFORM_LINKFLAGS
|
||||
CCFLAGS=SDK_FLAGS+CCFLAGS
|
||||
CXXFLAGS=SDK_FLAGS+CXXFLAGS
|
||||
|
||||
#Intel Macs are CoreDuo and Up
|
||||
if MACOSX_ARCHITECTURE == 'i386' or MACOSX_ARCHITECTURE == 'x86_64':
|
||||
REL_CFLAGS = []
|
||||
REL_CXXFLAGS = []
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2','-ftree-vectorize','-msse','-msse2','-msse3','-mfpmath=sse']
|
||||
else:
|
||||
CCFLAGS += ['-fno-strict-aliasing']
|
||||
REL_CFLAGS = []
|
||||
REL_CXXFLAGS = []
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2']
|
||||
|
||||
# Intel 64bit Macs are Core2Duo and up
|
||||
if MACOSX_ARCHITECTURE == 'x86_64':
|
||||
REL_CCFLAGS += ['-march=core2','-mssse3','-with-tune=core2','-enable-threads']
|
||||
REL_CFLAGS = []
|
||||
REL_CXXFLAGS = []
|
||||
REL_CCFLAGS = ['-DNDEBUG', '-O2']
|
||||
|
||||
CC_WARN = ['-Wall']
|
||||
C_WARN = ['-Wno-char-subscripts', '-Wpointer-arith', '-Wcast-align', '-Wdeclaration-after-statement', '-Wno-unknown-pragmas', '-Wstrict-prototypes']
|
||||
|
@@ -90,11 +90,6 @@ BF_FREETYPE = '/usr/local'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
|
||||
### XXX Find what this actually wants; it doesn't want libquicktime.
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
WITH_BF_ICONV = True
|
||||
BF_ICONV = LIBDIR + "/iconv"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@@ -100,10 +100,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
#BF_FREETYPE_LIB_STATIC = '${BF_FREETYPE}/lib/libfreetype.a'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
WITH_BF_ICONV = False
|
||||
BF_ICONV = "/usr"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@@ -101,10 +101,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
WITH_BF_ICONV = False
|
||||
BF_ICONV = LIBDIR + "/gcc/iconv"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@@ -112,10 +112,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = '/usr/local'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/include'
|
||||
|
||||
WITH_BF_ICONV = False
|
||||
BF_ICONV = LIBDIR + "/iconv"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@@ -133,12 +133,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype2ST'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
BF_QUICKTIME = LIBDIR + '/QTDevWin'
|
||||
BF_QUICKTIME_INC = '${BF_QUICKTIME}/CIncludes'
|
||||
BF_QUICKTIME_LIB = 'qtmlClient'
|
||||
BF_QUICKTIME_LIBPATH = '${BF_QUICKTIME}/Libraries'
|
||||
|
||||
WITH_BF_OPENJPEG = True
|
||||
BF_OPENJPEG = '#extern/libopenjpeg'
|
||||
BF_OPENJPEG_LIB = ''
|
||||
|
@@ -111,8 +111,6 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2/'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
|
||||
|
||||
WITH_BF_QUICKTIME = False
|
||||
|
||||
WITH_BF_ICONV = False
|
||||
BF_ICONV = LIBDIR + "/iconv"
|
||||
BF_ICONV_INC = '${BF_ICONV}/include'
|
||||
|
@@ -410,9 +410,38 @@ def buildinfo(lenv, build_type):
|
||||
"""
|
||||
build_date = time.strftime ("%Y-%m-%d")
|
||||
build_time = time.strftime ("%H:%M:%S")
|
||||
build_rev = os.popen('svnversion').read()[:-1] # remove \n
|
||||
if build_rev == '':
|
||||
build_rev = '-UNKNOWN-'
|
||||
|
||||
if os.path.isdir(os.path.abspath('.git')):
|
||||
build_commit_timestamp = os.popen('git log -1 --format=%ct').read().strip()
|
||||
if not build_commit_timestamp:
|
||||
# Git command not found
|
||||
build_hash = 'unknown'
|
||||
build_commit_timestamp = '0'
|
||||
build_branch = 'unknown'
|
||||
else:
|
||||
build_hash = os.popen('git rev-parse --short HEAD').read().strip()
|
||||
build_branch = os.popen('git rev-parse --abbrev-ref HEAD').read().strip()
|
||||
|
||||
# ## Check for local modifications
|
||||
has_local_changes = False
|
||||
|
||||
# Update GIT index before getting dirty files
|
||||
os.system('git update-index -q --refresh')
|
||||
changed_files = os.popen('git diff-index --name-only HEAD --').read().strip()
|
||||
|
||||
if changed_files:
|
||||
has_local_changes = True
|
||||
else:
|
||||
unpushed_log = os.popen('git log @{u}..').read().strip()
|
||||
has_local_changes = unpushed_log != ''
|
||||
|
||||
if has_local_changes:
|
||||
build_branch += ' (modified)'
|
||||
else:
|
||||
build_hash = 'unknown'
|
||||
build_commit_timestamp = '0'
|
||||
build_branch = 'unknown'
|
||||
|
||||
if lenv['BF_DEBUG']:
|
||||
build_type = "Debug"
|
||||
build_cflags = ' '.join(lenv['CFLAGS'] + lenv['CCFLAGS'] + lenv['BF_DEBUG_CCFLAGS'] + lenv['CPPFLAGS'])
|
||||
@@ -429,7 +458,9 @@ def buildinfo(lenv, build_type):
|
||||
lenv.Append (CPPDEFINES = ['BUILD_TIME=\\"%s\\"'%(build_time),
|
||||
'BUILD_DATE=\\"%s\\"'%(build_date),
|
||||
'BUILD_TYPE=\\"%s\\"'%(build_type),
|
||||
'BUILD_REV=\\"%s\\"'%(build_rev),
|
||||
'BUILD_HASH=\\"%s\\"'%(build_hash),
|
||||
'BUILD_COMMIT_TIMESTAMP=%s'%(build_commit_timestamp),
|
||||
'BUILD_BRANCH=\\"%s\\"'%(build_branch),
|
||||
'WITH_BUILDINFO',
|
||||
'BUILD_PLATFORM=\\"%s:%s\\"'%(platform.system(), platform.architecture()[0]),
|
||||
'BUILD_CFLAGS=\\"%s\\"'%(build_cflags),
|
||||
@@ -626,13 +657,19 @@ def AppIt(target=None, source=None, env=None):
|
||||
if binary == 'blender':
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/datafiles'%(installdir, binary, VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/datafiles/locale %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/datafiles/fonts %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/datafiles/locale/languages %s/%s.app/Contents/MacOS/%s/datafiles/locale/'%(bldroot, installdir, binary, VERSION)
|
||||
commands.getoutput(cmd)
|
||||
mo_dir = os.path.join(builddir[:-4], "locale")
|
||||
for f in os.listdir(mo_dir):
|
||||
cmd = 'ditto %s/%s %s/%s.app/Contents/MacOS/%s/datafiles/locale/%s/LC_MESSAGES/blender.mo'%(mo_dir, f, installdir, binary, VERSION, f[:-3])
|
||||
commands.getoutput(cmd)
|
||||
|
||||
if env['WITH_BF_OCIO']:
|
||||
cmd = 'cp -R %s/release/datafiles/colormanagement %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
|
||||
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
|
||||
@@ -683,9 +720,8 @@ def AppIt(target=None, source=None, env=None):
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'find %s/%s.app -name __MACOSX -exec rm -rf {} \;'%(installdir, binary)
|
||||
commands.getoutput(cmd)
|
||||
if env['CC'][:-2].endswith('4.6') or env['CC'][:-2].endswith('4.8'): # for correct errorhandling with gcc 4.6/4.8.x we need the gcc.dylib and gomp.dylib to link, thus distribute in app-bundle
|
||||
cmd = 'mkdir %s/%s.app/Contents/MacOS/lib'%(installdir, binary)
|
||||
commands.getoutput(cmd)
|
||||
if env['CC'].split('/')[len(env['CC'].split('/'))-1][4:] >= '4.6.1': # for correct errorhandling with gcc <= 4.6.1 we need the gcc.dylib and gomp.dylib to link, thus distribute in app-bundle
|
||||
print "Bundling libgcc and libgomp"
|
||||
instname = env['BF_CXX']
|
||||
cmd = 'ditto --arch %s %s/lib/libgcc_s.1.dylib %s/%s.app/Contents/MacOS/lib/'%(osxarch, instname, installdir, binary) # copy libgcc
|
||||
commands.getoutput(cmd)
|
||||
|
@@ -55,12 +55,12 @@ def get_version():
|
||||
|
||||
raise Exception("%s: missing version string" % fname)
|
||||
|
||||
def get_revision():
|
||||
build_rev = os.popen('svnversion').read()[:-1] # remove \n
|
||||
if build_rev == '' or build_rev==None:
|
||||
build_rev = 'UNKNOWN'
|
||||
def get_hash():
|
||||
build_hash = os.popen('git rev-parse --short HEAD').read().strip()
|
||||
if build_hash == '' or build_hash == None:
|
||||
build_hash = 'UNKNOWN'
|
||||
|
||||
return 'r' + build_rev
|
||||
return build_hash
|
||||
|
||||
|
||||
# copied from: http://www.scons.org/wiki/AutoconfRecipes
|
||||
@@ -80,7 +80,7 @@ def checkEndian():
|
||||
|
||||
# This is used in creating the local config directories
|
||||
VERSION, VERSION_DISPLAY, VERSION_RELEASE_CYCLE = get_version()
|
||||
REVISION = get_revision()
|
||||
HASH = get_hash()
|
||||
ENDIAN = checkEndian()
|
||||
|
||||
|
||||
@@ -138,13 +138,11 @@ def validate_arguments(args, bc):
|
||||
'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_PYTHON_UNPACK', 'WITH_BF_PYTHON_INSTALL_NUMPY',
|
||||
'WITHOUT_BF_OVERWRITE_INSTALL',
|
||||
'WITH_BF_OPENMP', 'BF_OPENMP', 'BF_OPENMP_LIBPATH', 'WITH_BF_STATICOPENMP', 'BF_OPENMP_STATIC_STATIC',
|
||||
'WITH_GHOST_COCOA',
|
||||
'WITH_GHOST_SDL',
|
||||
'WITH_GHOST_XDND',
|
||||
'WITH_X11_XINPUT',
|
||||
'WITH_X11_XF86VMODE',
|
||||
'BF_GHOST_DEBUG',
|
||||
'USE_QTKIT',
|
||||
'BF_FANCY', 'BF_QUIET', 'BF_LINE_OVERWRITE',
|
||||
'BF_X264_CONFIG',
|
||||
'BF_XVIDCORE_CONFIG',
|
||||
@@ -181,7 +179,7 @@ def validate_arguments(args, bc):
|
||||
'BF_PROFILE_CFLAGS', 'BF_PROFILE_CCFLAGS', 'BF_PROFILE_CXXFLAGS', 'BF_PROFILE_LINKFLAGS',
|
||||
'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
|
||||
'C_WARN', 'CC_WARN', 'CXX_WARN',
|
||||
'LLIBS', 'PLATFORM_LINKFLAGS','MACOSX_ARCHITECTURE', 'MACOSX_SDK_CHECK', 'XCODE_CUR_VER',
|
||||
'LLIBS', 'PLATFORM_LINKFLAGS', 'MACOSX_ARCHITECTURE', 'MACOSX_SDK', 'XCODE_CUR_VER',
|
||||
'BF_CYCLES_CUDA_BINARIES_ARCH', 'BF_PROGRAM_LINKFLAGS', 'MACOSX_DEPLOYMENT_TARGET'
|
||||
]
|
||||
|
||||
@@ -424,11 +422,9 @@ def read_opts(env, cfg, args):
|
||||
('BF_OPENMP', 'Base path to OpenMP (used when cross-compiling with older versions of WinGW)', ''),
|
||||
('BF_OPENMP_INC', 'Path to OpenMP includes (used when cross-compiling with older versions of WinGW)', ''),
|
||||
('BF_OPENMP_LIBPATH', 'Path to OpenMP libraries (used when cross-compiling with older versions of WinGW)', ''),
|
||||
(BoolVariable('WITH_GHOST_COCOA', 'Use Cocoa-framework if true', False)),
|
||||
(BoolVariable('WITH_GHOST_SDL', 'Enable building blender against SDL for windowing rather then the native APIs', False)),
|
||||
(BoolVariable('WITH_X11_XINPUT', 'Enable X11 Xinput (tablet support and unicode input)', True)),
|
||||
(BoolVariable('WITH_X11_XF86VMODE', 'Enable X11 video mode switching', True)),
|
||||
(BoolVariable('USE_QTKIT', 'Use QTKIT if true', False)),
|
||||
('BF_OPENMP_LIB_STATIC', 'OpenMP static library', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_QUICKTIME', 'Use QuickTime if true', False)),
|
||||
@@ -505,7 +501,7 @@ def read_opts(env, cfg, args):
|
||||
('LLIBS', 'Platform libs', []),
|
||||
('PLATFORM_LINKFLAGS', 'Platform linkflags', []),
|
||||
('MACOSX_ARCHITECTURE', 'python_arch.zip select', ''),
|
||||
('MACOSX_SDK_CHECK', 'Detect available OS X SDK`s', ''),
|
||||
('MACOSX_SDK', 'Set OS X SDK', ''),
|
||||
('XCODE_CUR_VER', 'Detect XCode version', ''),
|
||||
('MACOSX_DEPLOYMENT_TARGET', 'Detect OS X target version', ''),
|
||||
|
||||
@@ -697,7 +693,7 @@ def buildslave(target=None, source=None, env=None):
|
||||
branch = env['BUILDBOT_BRANCH']
|
||||
|
||||
outdir = os.path.abspath(env['BF_INSTALLDIR'])
|
||||
package_name = 'blender-' + VERSION+'-'+REVISION + '-' + platform
|
||||
package_name = 'blender-' + VERSION+'-'+HASH + '-' + platform
|
||||
if branch != '':
|
||||
package_name = branch + '-' + package_name
|
||||
package_dir = os.path.normpath(outdir + os.sep + '..' + os.sep + package_name)
|
||||
|
674
doc/license/GPL3-license.txt
Normal file
674
doc/license/GPL3-license.txt
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
@@ -1,6 +1,4 @@
|
||||
"""
|
||||
Popup Menus
|
||||
+++++++++++
|
||||
Popup menus can be useful for creating menus without having to register menu classes.
|
||||
|
||||
Note that they will not block the scripts execution, so the caller can't wait for user input.
|
||||
|
@@ -466,7 +466,9 @@ ClassMethodDescriptorType = type(dict.__dict__['fromkeys'])
|
||||
MethodDescriptorType = type(dict.get)
|
||||
GetSetDescriptorType = type(int.real)
|
||||
StaticMethodType = type(staticmethod(lambda: None))
|
||||
from types import MemberDescriptorType
|
||||
from types import (MemberDescriptorType,
|
||||
MethodType,
|
||||
)
|
||||
|
||||
_BPY_STRUCT_FAKE = "bpy_struct"
|
||||
_BPY_PROP_COLLECTION_FAKE = "bpy_prop_collection"
|
||||
@@ -629,12 +631,12 @@ def pymethod2sphinx(ident, fw, identifier, py_func):
|
||||
fw("\n")
|
||||
|
||||
|
||||
def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
|
||||
def pyfunc2sphinx(ident, fw, module_name, type_name, identifier, py_func, is_class=True):
|
||||
'''
|
||||
function or class method to sphinx
|
||||
'''
|
||||
|
||||
if type(py_func) == type(bpy.types.Space.draw_handler_add):
|
||||
if type(py_func) == MethodType:
|
||||
return
|
||||
|
||||
arg_str = inspect.formatargspec(*inspect.getargspec(py_func))
|
||||
@@ -657,6 +659,11 @@ def pyfunc2sphinx(ident, fw, identifier, py_func, is_class=True):
|
||||
write_indented_lines(ident + " ", fw, py_func.__doc__)
|
||||
fw("\n")
|
||||
|
||||
if is_class:
|
||||
write_example_ref(ident + " ", fw, module_name + "." + type_name + "." + identifier)
|
||||
else:
|
||||
write_example_ref(ident + " ", fw, module_name + "." + identifier)
|
||||
|
||||
|
||||
def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
|
||||
if identifier.startswith("_"):
|
||||
@@ -867,7 +874,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
||||
|
||||
for attribute, value, value_type in module_dir_value_type:
|
||||
if value_type == types.FunctionType:
|
||||
pyfunc2sphinx("", fw, attribute, value, is_class=False)
|
||||
pyfunc2sphinx("", fw, module_name, None, attribute, value, is_class=False)
|
||||
elif value_type in (types.BuiltinMethodType, types.BuiltinFunctionType): # both the same at the moment but to be future proof
|
||||
# note: can't get args from these, so dump the string as is
|
||||
# this means any module used like this must have fully formatted docstrings.
|
||||
@@ -1316,7 +1323,7 @@ def pyrna2sphinx(basepath):
|
||||
py_func = None
|
||||
|
||||
for identifier, py_func in py_funcs:
|
||||
pyfunc2sphinx(" ", fw, identifier, py_func, is_class=True)
|
||||
pyfunc2sphinx(" ", fw, "bpy.types", struct_id, identifier, py_func, is_class=True)
|
||||
del py_funcs, py_func
|
||||
|
||||
py_funcs = struct.get_py_c_functions()
|
||||
|
32
extern/bullet2/CMakeLists.txt
vendored
32
extern/bullet2/CMakeLists.txt
vendored
@@ -67,6 +67,8 @@ set(SRC
|
||||
src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
|
||||
src/BulletCollision/CollisionDispatch/btUnionFind.cpp
|
||||
src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
|
||||
src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp
|
||||
src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp
|
||||
src/BulletCollision/CollisionShapes/btBoxShape.cpp
|
||||
src/BulletCollision/CollisionShapes/btBox2dShape.cpp
|
||||
src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
|
||||
@@ -140,6 +142,7 @@ set(SRC
|
||||
src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
|
||||
src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp
|
||||
src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp
|
||||
src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp
|
||||
src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
|
||||
src/BulletDynamics/Dynamics/btRigidBody.cpp
|
||||
src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
|
||||
@@ -147,6 +150,15 @@ set(SRC
|
||||
src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
|
||||
src/BulletDynamics/Vehicle/btWheelInfo.cpp
|
||||
src/BulletDynamics/Character/btKinematicCharacterController.cpp
|
||||
src/BulletDynamics/Featherstone/btMultiBody.cpp
|
||||
src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp
|
||||
src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
|
||||
src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp
|
||||
src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp
|
||||
src/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp
|
||||
src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp
|
||||
src/BulletDynamics/MLCPSolvers/btDantzigLCP.cpp
|
||||
src/BulletDynamics/MLCPSolvers/btMLCPSolver.cpp
|
||||
|
||||
src/BulletSoftBody/btSoftBody.cpp
|
||||
src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
|
||||
@@ -204,6 +216,8 @@ set(SRC
|
||||
src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
|
||||
src/BulletCollision/CollisionDispatch/btUnionFind.h
|
||||
src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
|
||||
src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h
|
||||
src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h
|
||||
src/BulletCollision/CollisionShapes/btBoxShape.h
|
||||
src/BulletCollision/CollisionShapes/btBox2dShape.h
|
||||
src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
|
||||
@@ -308,6 +322,7 @@ set(SRC
|
||||
src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
|
||||
src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
|
||||
src/BulletDynamics/ConstraintSolver/btGearConstraint.h
|
||||
src/BulletDynamics/ConstraintSolver/btFixedConstraint.h
|
||||
src/BulletDynamics/Dynamics/btActionInterface.h
|
||||
src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
|
||||
src/BulletDynamics/Dynamics/btDynamicsWorld.h
|
||||
@@ -318,6 +333,22 @@ set(SRC
|
||||
src/BulletDynamics/Vehicle/btWheelInfo.h
|
||||
src/BulletDynamics/Character/btCharacterControllerInterface.h
|
||||
src/BulletDynamics/Character/btKinematicCharacterController.h
|
||||
src/BulletDynamics/Featherstone/btMultiBody.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodyConstraint.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodyJointMotor.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodyLink.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.h
|
||||
src/BulletDynamics/Featherstone/btMultiBodySolverConstraint.h
|
||||
src/BulletDynamics/MLCPSolvers/btDantzigLCP.h
|
||||
src/BulletDynamics/MLCPSolvers/btDantzigSolver.h
|
||||
src/BulletDynamics/MLCPSolvers/btMLCPSolver.h
|
||||
src/BulletDynamics/MLCPSolvers/btMLCPSolverInterface.h
|
||||
src/BulletDynamics/MLCPSolvers/btPATHSolver.h
|
||||
src/BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h
|
||||
|
||||
src/BulletSoftBody/btSoftBody.h
|
||||
src/BulletSoftBody/btSoftBodyInternals.h
|
||||
@@ -359,6 +390,7 @@ set(SRC
|
||||
src/LinearMath/btTransformUtil.h
|
||||
src/LinearMath/btVector3.h
|
||||
src/LinearMath/btPolarDecomposition.h
|
||||
src/LinearMath/btMatrixX.h
|
||||
|
||||
|
||||
src/btBulletCollisionCommon.h
|
||||
|
28
extern/bullet2/patches/ghost_character.patch
vendored
28
extern/bullet2/patches/ghost_character.patch
vendored
@@ -1,28 +0,0 @@
|
||||
Index: extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
|
||||
===================================================================
|
||||
--- extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp (revision 49183)
|
||||
+++ extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp (working copy)
|
||||
@@ -77,6 +77,9 @@
|
||||
if (convexResult.m_hitCollisionObject == m_me)
|
||||
return btScalar(1.0);
|
||||
|
||||
+ if (!convexResult.m_hitCollisionObject->hasContactResponse())
|
||||
+ return btScalar(1.0);
|
||||
+
|
||||
btVector3 hitNormalWorld;
|
||||
if (normalInWorldSpace)
|
||||
{
|
||||
@@ -173,7 +176,12 @@
|
||||
m_manifoldArray.resize(0);
|
||||
|
||||
btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
|
||||
-
|
||||
+ btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
|
||||
+ btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
|
||||
+
|
||||
+ if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
|
||||
+ continue;
|
||||
+
|
||||
if (collisionPair->m_algorithm)
|
||||
collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
|
||||
|
42
extern/bullet2/patches/ghost_softbody.patch
vendored
42
extern/bullet2/patches/ghost_softbody.patch
vendored
@@ -1,42 +0,0 @@
|
||||
Index: extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
|
||||
===================================================================
|
||||
--- extern/bullet2/src/BulletSoftBody/btSoftBody.cpp (Revision 43904)
|
||||
+++ extern/bullet2/src/BulletSoftBody/btSoftBody.cpp (Revision 43905)
|
||||
@@ -2780,21 +2780,23 @@
|
||||
{
|
||||
const RContact& c = psb->m_rcontacts[i];
|
||||
const sCti& cti = c.m_cti;
|
||||
- btRigidBody* tmpRigid = btRigidBody::upcast(cti.m_colObj);
|
||||
|
||||
- const btVector3 va = tmpRigid ? tmpRigid->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0);
|
||||
- const btVector3 vb = c.m_node->m_x-c.m_node->m_q;
|
||||
- const btVector3 vr = vb-va;
|
||||
- const btScalar dn = btDot(vr, cti.m_normal);
|
||||
- if(dn<=SIMD_EPSILON)
|
||||
- {
|
||||
- const btScalar dp = btMin( (btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg );
|
||||
- const btVector3 fv = vr - (cti.m_normal * dn);
|
||||
- // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient
|
||||
- const btVector3 impulse = c.m_c0 * ( (vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst );
|
||||
- c.m_node->m_x -= impulse * c.m_c2;
|
||||
- if (tmpRigid)
|
||||
- tmpRigid->applyImpulse(impulse,c.m_c1);
|
||||
+ if (cti.m_colObj->hasContactResponse()) {
|
||||
+ btRigidBody* tmpRigid = btRigidBody::upcast(cti.m_colObj);
|
||||
+ const btVector3 va = tmpRigid ? tmpRigid->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0);
|
||||
+ const btVector3 vb = c.m_node->m_x-c.m_node->m_q;
|
||||
+ const btVector3 vr = vb-va;
|
||||
+ const btScalar dn = btDot(vr, cti.m_normal);
|
||||
+ if(dn<=SIMD_EPSILON)
|
||||
+ {
|
||||
+ const btScalar dp = btMin( (btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg );
|
||||
+ const btVector3 fv = vr - (cti.m_normal * dn);
|
||||
+ // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient
|
||||
+ const btVector3 impulse = c.m_c0 * ( (vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst );
|
||||
+ c.m_node->m_x -= impulse * c.m_c2;
|
||||
+ if (tmpRigid)
|
||||
+ tmpRigid->applyImpulse(impulse,c.m_c1);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
6
extern/bullet2/readme.txt
vendored
6
extern/bullet2/readme.txt
vendored
@@ -4,11 +4,5 @@ Questions? mail blender at erwincoumans.com, or check the bf-blender mailing lis
|
||||
Thanks,
|
||||
Erwin
|
||||
|
||||
Apply patches/ghost_softbody.patch to prevent softbodies being hit by ghost objects.
|
||||
Originally committed in blender svn revision: 43905.
|
||||
|
||||
Apply patches/ghost_character.patch to prevent characters from colliding with ghost objects.
|
||||
Mitchell
|
||||
|
||||
Apply patches/convex_hull.patch to add access to the convex hull
|
||||
operation, used in the BMesh convex hull operator.
|
||||
|
@@ -25,7 +25,6 @@ class btOverlappingPairCache;
|
||||
struct btCollisionObjectWrapper;
|
||||
|
||||
class btPersistentManifold;
|
||||
class btStackAlloc;
|
||||
class btPoolAllocator;
|
||||
|
||||
struct btDispatcherInfo
|
||||
@@ -47,8 +46,7 @@ struct btDispatcherInfo
|
||||
m_useEpa(true),
|
||||
m_allowedCcdPenetration(btScalar(0.04)),
|
||||
m_useConvexConservativeDistanceUtil(false),
|
||||
m_convexConservativeDistanceThreshold(0.0f),
|
||||
m_stackAllocator(0)
|
||||
m_convexConservativeDistanceThreshold(0.0f)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -64,7 +62,6 @@ struct btDispatcherInfo
|
||||
btScalar m_allowedCcdPenetration;
|
||||
bool m_useConvexConservativeDistanceUtil;
|
||||
btScalar m_convexConservativeDistanceThreshold;
|
||||
btStackAlloc* m_stackAllocator;
|
||||
};
|
||||
|
||||
///The btDispatcher interface class can be used in combination with broadphase to dispatch calculations for overlapping pairs.
|
||||
|
@@ -53,7 +53,7 @@ btHashedOverlappingPairCache::~btHashedOverlappingPairCache()
|
||||
|
||||
void btHashedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher)
|
||||
{
|
||||
if (pair.m_algorithm)
|
||||
if (pair.m_algorithm && dispatcher)
|
||||
{
|
||||
{
|
||||
pair.m_algorithm->~btCollisionAlgorithm();
|
||||
|
@@ -96,6 +96,12 @@ class btHashedOverlappingPairCache : public btOverlappingPairCache
|
||||
btOverlapFilterCallback* m_overlapFilterCallback;
|
||||
bool m_blockedForChanges;
|
||||
|
||||
protected:
|
||||
|
||||
btAlignedObjectArray<int> m_hashTable;
|
||||
btAlignedObjectArray<int> m_next;
|
||||
btOverlappingPairCallback* m_ghostPairCallback;
|
||||
|
||||
|
||||
public:
|
||||
btHashedOverlappingPairCache();
|
||||
@@ -265,11 +271,6 @@ private:
|
||||
virtual void sortOverlappingPairs(btDispatcher* dispatcher);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
btAlignedObjectArray<int> m_hashTable;
|
||||
btAlignedObjectArray<int> m_next;
|
||||
btOverlappingPairCallback* m_ghostPairCallback;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -18,7 +18,6 @@ subject to the following restrictions:
|
||||
|
||||
struct btCollisionAlgorithmCreateFunc;
|
||||
|
||||
class btStackAlloc;
|
||||
class btPoolAllocator;
|
||||
|
||||
///btCollisionConfiguration allows to configure Bullet collision detection
|
||||
@@ -38,7 +37,6 @@ public:
|
||||
|
||||
virtual btPoolAllocator* getCollisionAlgorithmPool() = 0;
|
||||
|
||||
virtual btStackAlloc* getStackAllocator() = 0;
|
||||
|
||||
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0;
|
||||
|
||||
|
@@ -38,7 +38,8 @@ btCollisionObject::btCollisionObject()
|
||||
m_hitFraction(btScalar(1.)),
|
||||
m_ccdSweptSphereRadius(btScalar(0.)),
|
||||
m_ccdMotionThreshold(btScalar(0.)),
|
||||
m_checkCollideWith(false)
|
||||
m_checkCollideWith(false),
|
||||
m_updateRevision(0)
|
||||
{
|
||||
m_worldTransform.setIdentity();
|
||||
}
|
||||
|
@@ -92,7 +92,11 @@ protected:
|
||||
int m_internalType;
|
||||
|
||||
///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
|
||||
void* m_userObjectPointer;
|
||||
union
|
||||
{
|
||||
void* m_userObjectPointer;
|
||||
int m_userIndex;
|
||||
};
|
||||
|
||||
///time of impact calculation
|
||||
btScalar m_hitFraction;
|
||||
@@ -106,6 +110,9 @@ protected:
|
||||
/// If some object should have elaborate collision filtering by sub-classes
|
||||
int m_checkCollideWith;
|
||||
|
||||
///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;
|
||||
@@ -135,7 +142,8 @@ public:
|
||||
CO_GHOST_OBJECT=4,
|
||||
CO_SOFT_BODY=8,
|
||||
CO_HF_FLUID=16,
|
||||
CO_USER_TYPE=32
|
||||
CO_USER_TYPE=32,
|
||||
CO_FEATHERSTONE_LINK=64
|
||||
};
|
||||
|
||||
enum AnisotropicFrictionFlags
|
||||
@@ -202,6 +210,7 @@ public:
|
||||
|
||||
virtual void setCollisionShape(btCollisionShape* collisionShape)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_collisionShape = collisionShape;
|
||||
m_rootCollisionShape = collisionShape;
|
||||
}
|
||||
@@ -257,6 +266,7 @@ public:
|
||||
|
||||
void setRestitution(btScalar rest)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_restitution = rest;
|
||||
}
|
||||
btScalar getRestitution() const
|
||||
@@ -265,6 +275,7 @@ public:
|
||||
}
|
||||
void setFriction(btScalar frict)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_friction = frict;
|
||||
}
|
||||
btScalar getFriction() const
|
||||
@@ -274,6 +285,7 @@ public:
|
||||
|
||||
void setRollingFriction(btScalar frict)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_rollingFriction = frict;
|
||||
}
|
||||
btScalar getRollingFriction() const
|
||||
@@ -300,6 +312,7 @@ public:
|
||||
|
||||
void setWorldTransform(const btTransform& worldTrans)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_worldTransform = worldTrans;
|
||||
}
|
||||
|
||||
@@ -332,16 +345,19 @@ public:
|
||||
|
||||
void setInterpolationWorldTransform(const btTransform& trans)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_interpolationWorldTransform = trans;
|
||||
}
|
||||
|
||||
void setInterpolationLinearVelocity(const btVector3& linvel)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_interpolationLinearVelocity = linvel;
|
||||
}
|
||||
|
||||
void setInterpolationAngularVelocity(const btVector3& angvel)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_interpolationAngularVelocity = angvel;
|
||||
}
|
||||
|
||||
@@ -431,13 +447,28 @@ public:
|
||||
{
|
||||
return m_userObjectPointer;
|
||||
}
|
||||
|
||||
|
||||
int getUserIndex() const
|
||||
{
|
||||
return m_userIndex;
|
||||
}
|
||||
///users can point to their objects, userPointer is not used by Bullet
|
||||
void setUserPointer(void* userPointer)
|
||||
{
|
||||
m_userObjectPointer = userPointer;
|
||||
}
|
||||
|
||||
///users can point to their objects, userPointer is not used by Bullet
|
||||
void setUserIndex(int index)
|
||||
{
|
||||
m_userIndex = index;
|
||||
}
|
||||
|
||||
int getUpdateRevisionInternal() const
|
||||
{
|
||||
return m_updateRevision;
|
||||
}
|
||||
|
||||
|
||||
inline bool checkCollideWith(const btCollisionObject* co) const
|
||||
{
|
||||
|
@@ -31,11 +31,10 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#include "LinearMath/btStackAlloc.h"
|
||||
#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
|
||||
|
||||
|
||||
@@ -73,8 +72,6 @@ m_broadphasePairCache(pairCache),
|
||||
m_debugDrawer(0),
|
||||
m_forceUpdateAllAabbs(true)
|
||||
{
|
||||
m_stackAlloc = collisionConfiguration->getStackAllocator();
|
||||
m_dispatchInfo.m_stackAllocator = m_stackAlloc;
|
||||
}
|
||||
|
||||
|
||||
@@ -290,13 +287,19 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
|
||||
|
||||
btConvexShape* convexShape = (btConvexShape*) collisionShape;
|
||||
btVoronoiSimplexSolver simplexSolver;
|
||||
#define USE_SUBSIMPLEX_CONVEX_CAST 1
|
||||
#ifdef USE_SUBSIMPLEX_CONVEX_CAST
|
||||
btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
|
||||
#else
|
||||
//btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver);
|
||||
btSubsimplexConvexCast subSimplexConvexCaster(castShape,convexShape,&simplexSolver);
|
||||
|
||||
btGjkConvexCast gjkConvexCaster(castShape,convexShape,&simplexSolver);
|
||||
|
||||
//btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
|
||||
#endif //#USE_SUBSIMPLEX_CONVEX_CAST
|
||||
bool condition = true;
|
||||
btConvexCast* convexCasterPtr = 0;
|
||||
if (resultCallback.m_flags & btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest)
|
||||
convexCasterPtr = &subSimplexConvexCaster;
|
||||
else
|
||||
convexCasterPtr = &gjkConvexCaster;
|
||||
|
||||
btConvexCast& convexCaster = *convexCasterPtr;
|
||||
|
||||
if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
|
||||
{
|
||||
@@ -328,34 +331,26 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
|
||||
} else {
|
||||
if (collisionShape->isConcave())
|
||||
{
|
||||
// BT_PROFILE("rayTestConcave");
|
||||
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||
{
|
||||
///optimized version for btBvhTriangleMeshShape
|
||||
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
|
||||
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
|
||||
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
|
||||
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
|
||||
|
||||
//ConvexCast::CastResult
|
||||
//ConvexCast::CastResult
|
||||
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
|
||||
{
|
||||
btCollisionWorld::RayResultCallback* m_resultCallback;
|
||||
const btCollisionObject* m_collisionObject;
|
||||
btTriangleMeshShape* m_triangleMesh;
|
||||
const btConcaveShape* m_triangleMesh;
|
||||
|
||||
btTransform m_colObjWorldTransform;
|
||||
|
||||
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
|
||||
btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh,const btTransform& colObjWorldTransform):
|
||||
//@BP Mod
|
||||
btTriangleRaycastCallback(from,to, resultCallback->m_flags),
|
||||
m_resultCallback(resultCallback),
|
||||
m_collisionObject(collisionObject),
|
||||
m_triangleMesh(triangleMesh),
|
||||
m_colObjWorldTransform(colObjWorldTransform)
|
||||
{
|
||||
}
|
||||
btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,const btConcaveShape* triangleMesh,const btTransform& colObjWorldTransform):
|
||||
//@BP Mod
|
||||
btTriangleRaycastCallback(from,to, resultCallback->m_flags),
|
||||
m_resultCallback(resultCallback),
|
||||
m_collisionObject(collisionObject),
|
||||
m_triangleMesh(triangleMesh),
|
||||
m_colObjWorldTransform(colObjWorldTransform)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
|
||||
@@ -378,10 +373,28 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con
|
||||
|
||||
};
|
||||
|
||||
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
|
||||
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
|
||||
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
|
||||
|
||||
// BT_PROFILE("rayTestConcave");
|
||||
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
|
||||
{
|
||||
///optimized version for btBvhTriangleMeshShape
|
||||
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
|
||||
|
||||
BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform);
|
||||
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
|
||||
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
|
||||
} else
|
||||
}
|
||||
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
|
||||
{
|
||||
//generic (slower) case
|
||||
btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://bulletphysics.com/Bullet/
|
||||
Copyright (c) 2003-2013 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.
|
||||
@@ -18,13 +18,11 @@ subject to the following restrictions:
|
||||
* @mainpage Bullet Documentation
|
||||
*
|
||||
* @section intro_sec Introduction
|
||||
* Bullet Collision Detection & Physics SDK
|
||||
*
|
||||
* Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ).
|
||||
*
|
||||
* The main documentation is Bullet_User_Manual.pdf, included in the source code distribution.
|
||||
* There is the Physics Forum for feedback and general Collision Detection and Physics discussions.
|
||||
* Please visit http://www.bulletphysics.com
|
||||
* Please visit http://www.bulletphysics.org
|
||||
*
|
||||
* @section install_sec Installation
|
||||
*
|
||||
@@ -32,7 +30,16 @@ subject to the following restrictions:
|
||||
* You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
|
||||
*
|
||||
* @subsection step2 Step 2: Building
|
||||
* Bullet main build system for all platforms is cmake, you can download http://www.cmake.org
|
||||
* Bullet has multiple build systems, including premake, cmake and autotools. Premake and cmake support all platforms.
|
||||
* Premake is included in the Bullet/build folder for Windows, Mac OSX and Linux.
|
||||
* Under Windows you can click on Bullet/build/vs2010.bat to create Microsoft Visual Studio projects.
|
||||
* On Mac OSX and Linux you can open a terminal and generate Makefile, codeblocks or Xcode4 projects:
|
||||
* cd Bullet/build
|
||||
* ./premake4_osx gmake or ./premake4_linux gmake or ./premake4_linux64 gmake or (for Mac) ./premake4_osx xcode4
|
||||
* cd Bullet/build/gmake
|
||||
* make
|
||||
*
|
||||
* An alternative to premake is cmake. You can download cmake from http://www.cmake.org
|
||||
* cmake can autogenerate projectfiles for Microsoft Visual Studio, Apple Xcode, KDevelop and Unix Makefiles.
|
||||
* The easiest is to run the CMake cmake-gui graphical user interface and choose the options and generate projectfiles.
|
||||
* You can also use cmake in the command-line. Here are some examples for various platforms:
|
||||
@@ -65,7 +72,6 @@ subject to the following restrictions:
|
||||
#ifndef BT_COLLISION_WORLD_H
|
||||
#define BT_COLLISION_WORLD_H
|
||||
|
||||
class btStackAlloc;
|
||||
class btCollisionShape;
|
||||
class btConvexShape;
|
||||
class btBroadphaseInterface;
|
||||
@@ -91,8 +97,6 @@ protected:
|
||||
|
||||
btDispatcherInfo m_dispatchInfo;
|
||||
|
||||
btStackAlloc* m_stackAlloc;
|
||||
|
||||
btBroadphaseInterface* m_broadphasePairCache;
|
||||
|
||||
btIDebugDraw* m_debugDrawer;
|
||||
|
@@ -11,6 +11,7 @@ subject to the following restrictions:
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
*/
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
|
||||
@@ -22,6 +23,8 @@ subject to the following restrictions:
|
||||
#include "btManifoldResult.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
|
||||
|
||||
btShapePairCallback gCompoundChildShapePairCallback = 0;
|
||||
|
||||
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped)
|
||||
:btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
|
||||
m_isSwapped(isSwapped),
|
||||
@@ -129,6 +132,12 @@ public:
|
||||
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
|
||||
m_otherObjWrap->getCollisionShape()->getAabb(m_otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1);
|
||||
|
||||
if (gCompoundChildShapePairCallback)
|
||||
{
|
||||
if (!gCompoundChildShapePairCallback(m_otherObjWrap->getCollisionShape(), childShape))
|
||||
return;
|
||||
}
|
||||
|
||||
if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
|
||||
{
|
||||
|
||||
|
@@ -11,6 +11,7 @@ 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_COMPOUND_COLLISION_ALGORITHM_H
|
||||
@@ -28,6 +29,10 @@ class btDispatcher;
|
||||
class btDispatcher;
|
||||
class btCollisionObject;
|
||||
|
||||
class btCollisionShape;
|
||||
typedef bool (*btShapePairCallback)(const btCollisionShape* pShape0, const btCollisionShape* pShape1);
|
||||
extern btShapePairCallback gCompoundChildShapePairCallback;
|
||||
|
||||
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
|
||||
class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
@@ -37,6 +42,7 @@ class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
class btPersistentManifold* m_sharedManifold;
|
||||
bool m_ownsManifold;
|
||||
|
||||
|
||||
int m_compoundShapeRevision;//to keep track of changes, so that childAlgorithm array can be updated
|
||||
|
||||
void removeChildAlgorithms();
|
||||
@@ -49,6 +55,12 @@ public:
|
||||
|
||||
virtual ~btCompoundCollisionAlgorithm();
|
||||
|
||||
btCollisionAlgorithm* getChildAlgorithm (int n) const
|
||||
{
|
||||
return m_childCollisionAlgorithms[n];
|
||||
}
|
||||
|
||||
|
||||
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
@@ -63,6 +75,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
|
421
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp
vendored
Normal file
421
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp
vendored
Normal file
@@ -0,0 +1,421 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2013 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.
|
||||
|
||||
*/
|
||||
|
||||
#include "btCompoundCompoundCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "LinearMath/btAabbUtil2.h"
|
||||
#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
m_ownsManifold = false;
|
||||
|
||||
void* ptr = btAlignedAlloc(sizeof(btHashedSimplePairCache),16);
|
||||
m_childCollisionAlgorithmCache= new(ptr) btHashedSimplePairCache();
|
||||
|
||||
const btCollisionObjectWrapper* col0ObjWrap = body0Wrap;
|
||||
btAssert (col0ObjWrap->getCollisionShape()->isCompound());
|
||||
|
||||
const btCollisionObjectWrapper* col1ObjWrap = body1Wrap;
|
||||
btAssert (col1ObjWrap->getCollisionShape()->isCompound());
|
||||
|
||||
const btCompoundShape* compoundShape0 = static_cast<const btCompoundShape*>(col0ObjWrap->getCollisionShape());
|
||||
m_compoundShapeRevision0 = compoundShape0->getUpdateRevision();
|
||||
|
||||
const btCompoundShape* compoundShape1 = static_cast<const btCompoundShape*>(col1ObjWrap->getCollisionShape());
|
||||
m_compoundShapeRevision1 = compoundShape1->getUpdateRevision();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
btCompoundCompoundCollisionAlgorithm::~btCompoundCompoundCollisionAlgorithm()
|
||||
{
|
||||
removeChildAlgorithms();
|
||||
m_childCollisionAlgorithmCache->~btHashedSimplePairCache();
|
||||
btAlignedFree(m_childCollisionAlgorithmCache);
|
||||
}
|
||||
|
||||
void btCompoundCompoundCollisionAlgorithm::getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
{
|
||||
int i;
|
||||
btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray();
|
||||
for (i=0;i<pairs.size();i++)
|
||||
{
|
||||
if (pairs[i].m_userPointer)
|
||||
{
|
||||
|
||||
((btCollisionAlgorithm*)pairs[i].m_userPointer)->getAllContactManifolds(manifoldArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btCompoundCompoundCollisionAlgorithm::removeChildAlgorithms()
|
||||
{
|
||||
btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray();
|
||||
|
||||
int numChildren = pairs.size();
|
||||
int i;
|
||||
for (i=0;i<numChildren;i++)
|
||||
{
|
||||
if (pairs[i].m_userPointer)
|
||||
{
|
||||
btCollisionAlgorithm* algo = (btCollisionAlgorithm*) pairs[i].m_userPointer;
|
||||
algo->~btCollisionAlgorithm();
|
||||
m_dispatcher->freeCollisionAlgorithm(algo);
|
||||
}
|
||||
}
|
||||
m_childCollisionAlgorithmCache->removeAllPairs();
|
||||
}
|
||||
|
||||
struct btCompoundCompoundLeafCallback : btDbvt::ICollide
|
||||
{
|
||||
int m_numOverlapPairs;
|
||||
|
||||
|
||||
const btCollisionObjectWrapper* m_compound0ColObjWrap;
|
||||
const btCollisionObjectWrapper* m_compound1ColObjWrap;
|
||||
btDispatcher* m_dispatcher;
|
||||
const btDispatcherInfo& m_dispatchInfo;
|
||||
btManifoldResult* m_resultOut;
|
||||
|
||||
|
||||
class btHashedSimplePairCache* m_childCollisionAlgorithmCache;
|
||||
|
||||
btPersistentManifold* m_sharedManifold;
|
||||
|
||||
btCompoundCompoundLeafCallback (const btCollisionObjectWrapper* compound1ObjWrap,
|
||||
const btCollisionObjectWrapper* compound0ObjWrap,
|
||||
btDispatcher* dispatcher,
|
||||
const btDispatcherInfo& dispatchInfo,
|
||||
btManifoldResult* resultOut,
|
||||
btHashedSimplePairCache* childAlgorithmsCache,
|
||||
btPersistentManifold* sharedManifold)
|
||||
:m_compound0ColObjWrap(compound1ObjWrap),m_compound1ColObjWrap(compound0ObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
|
||||
m_childCollisionAlgorithmCache(childAlgorithmsCache),
|
||||
m_sharedManifold(sharedManifold),
|
||||
m_numOverlapPairs(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Process(const btDbvtNode* leaf0,const btDbvtNode* leaf1)
|
||||
{
|
||||
m_numOverlapPairs++;
|
||||
|
||||
|
||||
int childIndex0 = leaf0->dataAsInt;
|
||||
int childIndex1 = leaf1->dataAsInt;
|
||||
|
||||
|
||||
btAssert(childIndex0>=0);
|
||||
btAssert(childIndex1>=0);
|
||||
|
||||
|
||||
const btCompoundShape* compoundShape0 = static_cast<const btCompoundShape*>(m_compound0ColObjWrap->getCollisionShape());
|
||||
btAssert(childIndex0<compoundShape0->getNumChildShapes());
|
||||
|
||||
const btCompoundShape* compoundShape1 = static_cast<const btCompoundShape*>(m_compound1ColObjWrap->getCollisionShape());
|
||||
btAssert(childIndex1<compoundShape1->getNumChildShapes());
|
||||
|
||||
const btCollisionShape* childShape0 = compoundShape0->getChildShape(childIndex0);
|
||||
const btCollisionShape* childShape1 = compoundShape1->getChildShape(childIndex1);
|
||||
|
||||
//backup
|
||||
btTransform orgTrans0 = m_compound0ColObjWrap->getWorldTransform();
|
||||
const btTransform& childTrans0 = compoundShape0->getChildTransform(childIndex0);
|
||||
btTransform newChildWorldTrans0 = orgTrans0*childTrans0 ;
|
||||
|
||||
btTransform orgTrans1 = m_compound1ColObjWrap->getWorldTransform();
|
||||
const btTransform& childTrans1 = compoundShape1->getChildTransform(childIndex1);
|
||||
btTransform newChildWorldTrans1 = orgTrans1*childTrans1 ;
|
||||
|
||||
|
||||
//perform an AABB check first
|
||||
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
|
||||
childShape0->getAabb(newChildWorldTrans0,aabbMin0,aabbMax0);
|
||||
childShape1->getAabb(newChildWorldTrans1,aabbMin1,aabbMax1);
|
||||
|
||||
if (gCompoundCompoundChildShapePairCallback)
|
||||
{
|
||||
if (!gCompoundCompoundChildShapePairCallback(childShape0,childShape1))
|
||||
return;
|
||||
}
|
||||
|
||||
if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
|
||||
{
|
||||
btCollisionObjectWrapper compoundWrap0(this->m_compound0ColObjWrap,childShape0, m_compound0ColObjWrap->getCollisionObject(),newChildWorldTrans0,-1,childIndex0);
|
||||
btCollisionObjectWrapper compoundWrap1(this->m_compound1ColObjWrap,childShape1,m_compound1ColObjWrap->getCollisionObject(),newChildWorldTrans1,-1,childIndex1);
|
||||
|
||||
|
||||
btSimplePair* pair = m_childCollisionAlgorithmCache->findPair(childIndex0,childIndex1);
|
||||
|
||||
btCollisionAlgorithm* colAlgo = 0;
|
||||
|
||||
if (pair)
|
||||
{
|
||||
colAlgo = (btCollisionAlgorithm*)pair->m_userPointer;
|
||||
|
||||
} else
|
||||
{
|
||||
colAlgo = m_dispatcher->findAlgorithm(&compoundWrap0,&compoundWrap1,m_sharedManifold);
|
||||
pair = m_childCollisionAlgorithmCache->addOverlappingPair(childIndex0,childIndex1);
|
||||
btAssert(pair);
|
||||
pair->m_userPointer = colAlgo;
|
||||
}
|
||||
|
||||
btAssert(colAlgo);
|
||||
|
||||
const btCollisionObjectWrapper* tmpWrap0 = 0;
|
||||
const btCollisionObjectWrapper* tmpWrap1 = 0;
|
||||
|
||||
tmpWrap0 = m_resultOut->getBody0Wrap();
|
||||
tmpWrap1 = m_resultOut->getBody1Wrap();
|
||||
|
||||
m_resultOut->setBody0Wrap(&compoundWrap0);
|
||||
m_resultOut->setBody1Wrap(&compoundWrap1);
|
||||
|
||||
m_resultOut->setShapeIdentifiersA(-1,childIndex0);
|
||||
m_resultOut->setShapeIdentifiersB(-1,childIndex1);
|
||||
|
||||
|
||||
colAlgo->processCollision(&compoundWrap0,&compoundWrap1,m_dispatchInfo,m_resultOut);
|
||||
|
||||
m_resultOut->setBody0Wrap(tmpWrap0);
|
||||
m_resultOut->setBody1Wrap(tmpWrap1);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static DBVT_INLINE bool MyIntersect( const btDbvtAabbMm& a,
|
||||
const btDbvtAabbMm& b, const btTransform& xform)
|
||||
{
|
||||
btVector3 newmin,newmax;
|
||||
btTransformAabb(b.Mins(),b.Maxs(),0.f,xform,newmin,newmax);
|
||||
btDbvtAabbMm newb = btDbvtAabbMm::FromMM(newmin,newmax);
|
||||
return Intersect(a,newb);
|
||||
}
|
||||
|
||||
|
||||
static inline void MycollideTT( const btDbvtNode* root0,
|
||||
const btDbvtNode* root1,
|
||||
const btTransform& xform,
|
||||
btCompoundCompoundLeafCallback* callback)
|
||||
{
|
||||
|
||||
if(root0&&root1)
|
||||
{
|
||||
int depth=1;
|
||||
int treshold=btDbvt::DOUBLE_STACKSIZE-4;
|
||||
btAlignedObjectArray<btDbvt::sStkNN> stkStack;
|
||||
stkStack.resize(btDbvt::DOUBLE_STACKSIZE);
|
||||
stkStack[0]=btDbvt::sStkNN(root0,root1);
|
||||
do {
|
||||
btDbvt::sStkNN p=stkStack[--depth];
|
||||
if(MyIntersect(p.a->volume,p.b->volume,xform))
|
||||
{
|
||||
if(depth>treshold)
|
||||
{
|
||||
stkStack.resize(stkStack.size()*2);
|
||||
treshold=stkStack.size()-4;
|
||||
}
|
||||
if(p.a->isinternal())
|
||||
{
|
||||
if(p.b->isinternal())
|
||||
{
|
||||
stkStack[depth++]=btDbvt::sStkNN(p.a->childs[0],p.b->childs[0]);
|
||||
stkStack[depth++]=btDbvt::sStkNN(p.a->childs[1],p.b->childs[0]);
|
||||
stkStack[depth++]=btDbvt::sStkNN(p.a->childs[0],p.b->childs[1]);
|
||||
stkStack[depth++]=btDbvt::sStkNN(p.a->childs[1],p.b->childs[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
stkStack[depth++]=btDbvt::sStkNN(p.a->childs[0],p.b);
|
||||
stkStack[depth++]=btDbvt::sStkNN(p.a->childs[1],p.b);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(p.b->isinternal())
|
||||
{
|
||||
stkStack[depth++]=btDbvt::sStkNN(p.a,p.b->childs[0]);
|
||||
stkStack[depth++]=btDbvt::sStkNN(p.a,p.b->childs[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback->Process(p.a,p.b);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(depth);
|
||||
}
|
||||
}
|
||||
|
||||
void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
|
||||
const btCollisionObjectWrapper* col0ObjWrap = body0Wrap;
|
||||
const btCollisionObjectWrapper* col1ObjWrap= body1Wrap;
|
||||
|
||||
btAssert (col0ObjWrap->getCollisionShape()->isCompound());
|
||||
btAssert (col1ObjWrap->getCollisionShape()->isCompound());
|
||||
const btCompoundShape* compoundShape0 = static_cast<const btCompoundShape*>(col0ObjWrap->getCollisionShape());
|
||||
const btCompoundShape* compoundShape1 = static_cast<const btCompoundShape*>(col1ObjWrap->getCollisionShape());
|
||||
|
||||
///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();
|
||||
}
|
||||
|
||||
|
||||
///we need to refresh all contact manifolds
|
||||
///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep
|
||||
///so we should add a 'refreshManifolds' in the btCollisionAlgorithm
|
||||
{
|
||||
int i;
|
||||
btManifoldArray manifoldArray;
|
||||
btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray();
|
||||
for (i=0;i<pairs.size();i++)
|
||||
{
|
||||
if (pairs[i].m_userPointer)
|
||||
{
|
||||
btCollisionAlgorithm* algo = (btCollisionAlgorithm*) pairs[i].m_userPointer;
|
||||
algo->getAllContactManifolds(manifoldArray);
|
||||
for (int m=0;m<manifoldArray.size();m++)
|
||||
{
|
||||
if (manifoldArray[m]->getNumContacts())
|
||||
{
|
||||
resultOut->setPersistentManifold(manifoldArray[m]);
|
||||
resultOut->refreshContactPoints();
|
||||
resultOut->setPersistentManifold(0);
|
||||
}
|
||||
}
|
||||
manifoldArray.resize(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
//printf("#compound-compound child/leaf overlap =%d \r",callback.m_numOverlapPairs);
|
||||
|
||||
//remove non-overlapping child pairs
|
||||
|
||||
{
|
||||
btAssert(m_removePairs.size()==0);
|
||||
|
||||
//iterate over all children, perform an AABB check inside ProcessChildShape
|
||||
btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray();
|
||||
|
||||
int i;
|
||||
btManifoldArray manifoldArray;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
|
||||
|
||||
for (i=0;i<pairs.size();i++)
|
||||
{
|
||||
if (pairs[i].m_userPointer)
|
||||
{
|
||||
btCollisionAlgorithm* algo = (btCollisionAlgorithm*)pairs[i].m_userPointer;
|
||||
|
||||
{
|
||||
btTransform orgTrans0;
|
||||
const btCollisionShape* childShape0 = 0;
|
||||
|
||||
btTransform newChildWorldTrans0;
|
||||
btTransform orgInterpolationTrans0;
|
||||
childShape0 = compoundShape0->getChildShape(pairs[i].m_indexA);
|
||||
orgTrans0 = col0ObjWrap->getWorldTransform();
|
||||
orgInterpolationTrans0 = col0ObjWrap->getWorldTransform();
|
||||
const btTransform& childTrans0 = compoundShape0->getChildTransform(pairs[i].m_indexA);
|
||||
newChildWorldTrans0 = orgTrans0*childTrans0 ;
|
||||
childShape0->getAabb(newChildWorldTrans0,aabbMin0,aabbMax0);
|
||||
}
|
||||
|
||||
{
|
||||
btTransform orgInterpolationTrans1;
|
||||
const btCollisionShape* childShape1 = 0;
|
||||
btTransform orgTrans1;
|
||||
btTransform newChildWorldTrans1;
|
||||
|
||||
childShape1 = compoundShape1->getChildShape(pairs[i].m_indexB);
|
||||
orgTrans1 = col1ObjWrap->getWorldTransform();
|
||||
orgInterpolationTrans1 = col1ObjWrap->getWorldTransform();
|
||||
const btTransform& childTrans1 = compoundShape1->getChildTransform(pairs[i].m_indexB);
|
||||
newChildWorldTrans1 = orgTrans1*childTrans1 ;
|
||||
childShape1->getAabb(newChildWorldTrans1,aabbMin1,aabbMax1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
|
||||
{
|
||||
algo->~btCollisionAlgorithm();
|
||||
m_dispatcher->freeCollisionAlgorithm(algo);
|
||||
m_removePairs.push_back(btSimplePair(pairs[i].m_indexA,pairs[i].m_indexB));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=0;i<m_removePairs.size();i++)
|
||||
{
|
||||
m_childCollisionAlgorithmCache->removeOverlappingPair(m_removePairs[i].m_indexA,m_removePairs[i].m_indexB);
|
||||
}
|
||||
m_removePairs.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
btScalar btCompoundCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||
{
|
||||
btAssert(0);
|
||||
return 0.f;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
90
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h
vendored
Normal file
90
extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2013 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_COMPOUND_COMPOUND_COLLISION_ALGORITHM_H
|
||||
#define BT_COMPOUND_COMPOUND_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
|
||||
class btDispatcher;
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "BulletCollision/CollisionDispatch/btHashedSimplePairCache.h"
|
||||
class btDispatcher;
|
||||
class btCollisionObject;
|
||||
|
||||
class btCollisionShape;
|
||||
typedef bool (*btShapePairCallback)(const btCollisionShape* pShape0, const btCollisionShape* pShape1);
|
||||
extern btShapePairCallback gCompoundCompoundChildShapePairCallback;
|
||||
|
||||
/// btCompoundCompoundCollisionAlgorithm supports collision between two btCompoundCollisionShape shapes
|
||||
class btCompoundCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
|
||||
{
|
||||
|
||||
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;
|
||||
|
||||
void removeChildAlgorithms();
|
||||
|
||||
// void preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
|
||||
|
||||
public:
|
||||
|
||||
btCompoundCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
|
||||
|
||||
virtual ~btCompoundCompoundCollisionAlgorithm();
|
||||
|
||||
|
||||
|
||||
virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray);
|
||||
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCompoundCollisionAlgorithm));
|
||||
return new(mem) btCompoundCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,false);
|
||||
}
|
||||
};
|
||||
|
||||
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCompoundCollisionAlgorithm));
|
||||
return new(mem) btCompoundCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,true);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_COMPOUND_COMPOUND_COLLISION_ALGORITHM_H
|
@@ -132,7 +132,6 @@ void btConvex2dConvex2dAlgorithm ::processCollision (const btCollisionObjectWrap
|
||||
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
|
||||
}
|
||||
|
||||
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
|
||||
input.m_transformA = body0Wrap->getWorldTransform();
|
||||
input.m_transformB = body1Wrap->getWorldTransform();
|
||||
|
||||
|
@@ -76,21 +76,27 @@ void btConvexTriangleCallback::clearCache()
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
|
||||
void btConvexTriangleCallback::processTriangle(btVector3* triangle,int
|
||||
partId, int triangleIndex)
|
||||
{
|
||||
|
||||
//just for debugging purposes
|
||||
//printf("triangle %d",m_triangleCount++);
|
||||
|
||||
if (!TestTriangleAgainstAabb2(triangle, m_aabbMin, m_aabbMax))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//aabb filter is already applied!
|
||||
//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
|
||||
|
@@ -373,7 +373,6 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper*
|
||||
input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
|
||||
}
|
||||
|
||||
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
|
||||
input.m_transformA = body0Wrap->getWorldTransform();
|
||||
input.m_transformB = body1Wrap->getWorldTransform();
|
||||
|
||||
|
@@ -19,6 +19,8 @@ subject to the following restrictions:
|
||||
#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h"
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h"
|
||||
#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
|
||||
@@ -32,7 +34,6 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
|
||||
#include "LinearMath/btStackAlloc.h"
|
||||
#include "LinearMath/btPoolAllocator.h"
|
||||
|
||||
|
||||
@@ -65,6 +66,10 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
|
||||
m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
|
||||
mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16);
|
||||
m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btCompoundCompoundCollisionAlgorithm::CreateFunc),16);
|
||||
m_compoundCompoundCreateFunc = new (mem)btCompoundCompoundCollisionAlgorithm::CreateFunc;
|
||||
|
||||
mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16);
|
||||
m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc;
|
||||
mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16);
|
||||
@@ -106,16 +111,6 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
|
||||
|
||||
if (constructionInfo.m_stackAlloc)
|
||||
{
|
||||
m_ownsStackAllocator = false;
|
||||
this->m_stackAlloc = constructionInfo.m_stackAlloc;
|
||||
} else
|
||||
{
|
||||
m_ownsStackAllocator = true;
|
||||
void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
|
||||
m_stackAlloc = new(mem)btStackAlloc(constructionInfo.m_defaultStackAllocatorSize);
|
||||
}
|
||||
|
||||
if (constructionInfo.m_persistentManifoldPool)
|
||||
{
|
||||
@@ -144,12 +139,6 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
|
||||
|
||||
btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
|
||||
{
|
||||
if (m_ownsStackAllocator)
|
||||
{
|
||||
m_stackAlloc->destroy();
|
||||
m_stackAlloc->~btStackAlloc();
|
||||
btAlignedFree(m_stackAlloc);
|
||||
}
|
||||
if (m_ownsCollisionAlgorithmPool)
|
||||
{
|
||||
m_collisionAlgorithmPool->~btPoolAllocator();
|
||||
@@ -172,6 +161,9 @@ btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
|
||||
m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_compoundCreateFunc);
|
||||
|
||||
m_compoundCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree(m_compoundCompoundCreateFunc);
|
||||
|
||||
m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
|
||||
btAlignedFree( m_swappedCompoundCreateFunc);
|
||||
|
||||
@@ -275,6 +267,12 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlg
|
||||
return m_swappedConvexConcaveCreateFunc;
|
||||
}
|
||||
|
||||
|
||||
if (btBroadphaseProxy::isCompound(proxyType0) && btBroadphaseProxy::isCompound(proxyType1))
|
||||
{
|
||||
return m_compoundCompoundCreateFunc;
|
||||
}
|
||||
|
||||
if (btBroadphaseProxy::isCompound(proxyType0))
|
||||
{
|
||||
return m_compoundCreateFunc;
|
||||
|
@@ -22,23 +22,19 @@ class btConvexPenetrationDepthSolver;
|
||||
|
||||
struct btDefaultCollisionConstructionInfo
|
||||
{
|
||||
btStackAlloc* m_stackAlloc;
|
||||
btPoolAllocator* m_persistentManifoldPool;
|
||||
btPoolAllocator* m_collisionAlgorithmPool;
|
||||
int m_defaultMaxPersistentManifoldPoolSize;
|
||||
int m_defaultMaxCollisionAlgorithmPoolSize;
|
||||
int m_customCollisionAlgorithmMaxElementSize;
|
||||
int m_defaultStackAllocatorSize;
|
||||
int m_useEpaPenetrationAlgorithm;
|
||||
|
||||
btDefaultCollisionConstructionInfo()
|
||||
:m_stackAlloc(0),
|
||||
m_persistentManifoldPool(0),
|
||||
:m_persistentManifoldPool(0),
|
||||
m_collisionAlgorithmPool(0),
|
||||
m_defaultMaxPersistentManifoldPoolSize(4096),
|
||||
m_defaultMaxCollisionAlgorithmPoolSize(4096),
|
||||
m_customCollisionAlgorithmMaxElementSize(0),
|
||||
m_defaultStackAllocatorSize(0),
|
||||
m_useEpaPenetrationAlgorithm(true)
|
||||
{
|
||||
}
|
||||
@@ -56,8 +52,6 @@ protected:
|
||||
|
||||
int m_persistentManifoldPoolSize;
|
||||
|
||||
btStackAlloc* m_stackAlloc;
|
||||
bool m_ownsStackAllocator;
|
||||
|
||||
btPoolAllocator* m_persistentManifoldPool;
|
||||
bool m_ownsPersistentManifoldPool;
|
||||
@@ -75,6 +69,8 @@ protected:
|
||||
btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_compoundCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_compoundCompoundCreateFunc;
|
||||
|
||||
btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
|
||||
btCollisionAlgorithmCreateFunc* m_sphereSphereCF;
|
||||
@@ -105,10 +101,6 @@ public:
|
||||
return m_collisionAlgorithmPool;
|
||||
}
|
||||
|
||||
virtual btStackAlloc* getStackAllocator()
|
||||
{
|
||||
return m_stackAlloc;
|
||||
}
|
||||
|
||||
virtual btVoronoiSimplexSolver* getSimplexSolver()
|
||||
{
|
||||
|
278
extern/bullet2/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp
vendored
Normal file
278
extern/bullet2/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "btHashedSimplePairCache.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int gOverlappingSimplePairs = 0;
|
||||
int gRemoveSimplePairs =0;
|
||||
int gAddedSimplePairs =0;
|
||||
int gFindSimplePairs =0;
|
||||
|
||||
|
||||
|
||||
|
||||
btHashedSimplePairCache::btHashedSimplePairCache():
|
||||
m_blockedForChanges(false)
|
||||
{
|
||||
int initialAllocatedSize= 2;
|
||||
m_overlappingPairArray.reserve(initialAllocatedSize);
|
||||
growTables();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
btHashedSimplePairCache::~btHashedSimplePairCache()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void btHashedSimplePairCache::removeAllPairs()
|
||||
{
|
||||
m_overlappingPairArray.clear();
|
||||
m_hashTable.clear();
|
||||
m_next.clear();
|
||||
|
||||
int initialAllocatedSize= 2;
|
||||
m_overlappingPairArray.reserve(initialAllocatedSize);
|
||||
growTables();
|
||||
}
|
||||
|
||||
|
||||
|
||||
btSimplePair* btHashedSimplePairCache::findPair(int indexA, int indexB)
|
||||
{
|
||||
gFindSimplePairs++;
|
||||
|
||||
|
||||
/*if (indexA > indexB)
|
||||
btSwap(indexA, indexB);*/
|
||||
|
||||
int hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA), static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
|
||||
|
||||
if (hash >= m_hashTable.size())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int index = m_hashTable[hash];
|
||||
while (index != BT_SIMPLE_NULL_PAIR && equalsPair(m_overlappingPairArray[index], indexA, indexB) == false)
|
||||
{
|
||||
index = m_next[index];
|
||||
}
|
||||
|
||||
if (index == BT_SIMPLE_NULL_PAIR)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
btAssert(index < m_overlappingPairArray.size());
|
||||
|
||||
return &m_overlappingPairArray[index];
|
||||
}
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
void btHashedSimplePairCache::growTables()
|
||||
{
|
||||
|
||||
int newCapacity = m_overlappingPairArray.capacity();
|
||||
|
||||
if (m_hashTable.size() < newCapacity)
|
||||
{
|
||||
//grow hashtable and next table
|
||||
int curHashtableSize = m_hashTable.size();
|
||||
|
||||
m_hashTable.resize(newCapacity);
|
||||
m_next.resize(newCapacity);
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
for (i= 0; i < newCapacity; ++i)
|
||||
{
|
||||
m_hashTable[i] = BT_SIMPLE_NULL_PAIR;
|
||||
}
|
||||
for (i = 0; i < newCapacity; ++i)
|
||||
{
|
||||
m_next[i] = BT_SIMPLE_NULL_PAIR;
|
||||
}
|
||||
|
||||
for(i=0;i<curHashtableSize;i++)
|
||||
{
|
||||
|
||||
const btSimplePair& pair = m_overlappingPairArray[i];
|
||||
int indexA = pair.m_indexA;
|
||||
int indexB = pair.m_indexB;
|
||||
|
||||
int hashValue = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask
|
||||
m_next[i] = m_hashTable[hashValue];
|
||||
m_hashTable[hashValue] = i;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
btSimplePair* btHashedSimplePairCache::internalAddPair(int indexA, int indexB)
|
||||
{
|
||||
|
||||
int hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask
|
||||
|
||||
|
||||
btSimplePair* pair = internalFindPair(indexA, indexB, hash);
|
||||
if (pair != NULL)
|
||||
{
|
||||
return pair;
|
||||
}
|
||||
|
||||
int count = m_overlappingPairArray.size();
|
||||
int oldCapacity = m_overlappingPairArray.capacity();
|
||||
void* mem = &m_overlappingPairArray.expandNonInitializing();
|
||||
|
||||
int newCapacity = m_overlappingPairArray.capacity();
|
||||
|
||||
if (oldCapacity < newCapacity)
|
||||
{
|
||||
growTables();
|
||||
//hash with new capacity
|
||||
hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
|
||||
}
|
||||
|
||||
pair = new (mem) btSimplePair(indexA,indexB);
|
||||
|
||||
pair->m_userPointer = 0;
|
||||
|
||||
m_next[count] = m_hashTable[hash];
|
||||
m_hashTable[hash] = count;
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void* btHashedSimplePairCache::removeOverlappingPair(int indexA, int indexB)
|
||||
{
|
||||
gRemoveSimplePairs++;
|
||||
|
||||
|
||||
/*if (indexA > indexB)
|
||||
btSwap(indexA, indexB);*/
|
||||
|
||||
int hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
|
||||
|
||||
btSimplePair* pair = internalFindPair(indexA, indexB, hash);
|
||||
if (pair == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void* userData = pair->m_userPointer;
|
||||
|
||||
|
||||
int pairIndex = int(pair - &m_overlappingPairArray[0]);
|
||||
btAssert(pairIndex < m_overlappingPairArray.size());
|
||||
|
||||
// Remove the pair from the hash table.
|
||||
int index = m_hashTable[hash];
|
||||
btAssert(index != BT_SIMPLE_NULL_PAIR);
|
||||
|
||||
int previous = BT_SIMPLE_NULL_PAIR;
|
||||
while (index != pairIndex)
|
||||
{
|
||||
previous = index;
|
||||
index = m_next[index];
|
||||
}
|
||||
|
||||
if (previous != BT_SIMPLE_NULL_PAIR)
|
||||
{
|
||||
btAssert(m_next[previous] == pairIndex);
|
||||
m_next[previous] = m_next[pairIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hashTable[hash] = m_next[pairIndex];
|
||||
}
|
||||
|
||||
// We now move the last pair into spot of the
|
||||
// pair being removed. We need to fix the hash
|
||||
// table indices to support the move.
|
||||
|
||||
int lastPairIndex = m_overlappingPairArray.size() - 1;
|
||||
|
||||
// If the removed pair is the last pair, we are done.
|
||||
if (lastPairIndex == pairIndex)
|
||||
{
|
||||
m_overlappingPairArray.pop_back();
|
||||
return userData;
|
||||
}
|
||||
|
||||
// Remove the last pair from the hash table.
|
||||
const btSimplePair* last = &m_overlappingPairArray[lastPairIndex];
|
||||
/* missing swap here too, Nat. */
|
||||
int lastHash = static_cast<int>(getHash(static_cast<unsigned int>(last->m_indexA), static_cast<unsigned int>(last->m_indexB)) & (m_overlappingPairArray.capacity()-1));
|
||||
|
||||
index = m_hashTable[lastHash];
|
||||
btAssert(index != BT_SIMPLE_NULL_PAIR);
|
||||
|
||||
previous = BT_SIMPLE_NULL_PAIR;
|
||||
while (index != lastPairIndex)
|
||||
{
|
||||
previous = index;
|
||||
index = m_next[index];
|
||||
}
|
||||
|
||||
if (previous != BT_SIMPLE_NULL_PAIR)
|
||||
{
|
||||
btAssert(m_next[previous] == lastPairIndex);
|
||||
m_next[previous] = m_next[lastPairIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hashTable[lastHash] = m_next[lastPairIndex];
|
||||
}
|
||||
|
||||
// Copy the last pair into the remove pair's spot.
|
||||
m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex];
|
||||
|
||||
// Insert the last pair into the hash table
|
||||
m_next[pairIndex] = m_hashTable[lastHash];
|
||||
m_hashTable[lastHash] = pairIndex;
|
||||
|
||||
m_overlappingPairArray.pop_back();
|
||||
|
||||
return userData;
|
||||
}
|
||||
//#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
174
extern/bullet2/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h
vendored
Normal file
174
extern/bullet2/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_HASHED_SIMPLE_PAIR_CACHE_H
|
||||
#define BT_HASHED_SIMPLE_PAIR_CACHE_H
|
||||
|
||||
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
const int BT_SIMPLE_NULL_PAIR=0xffffffff;
|
||||
|
||||
struct btSimplePair
|
||||
{
|
||||
btSimplePair(int indexA,int indexB)
|
||||
:m_indexA(indexA),
|
||||
m_indexB(indexB),
|
||||
m_userPointer(0)
|
||||
{
|
||||
}
|
||||
|
||||
int m_indexA;
|
||||
int m_indexB;
|
||||
union
|
||||
{
|
||||
void* m_userPointer;
|
||||
int m_userValue;
|
||||
};
|
||||
};
|
||||
|
||||
typedef btAlignedObjectArray<btSimplePair> btSimplePairArray;
|
||||
|
||||
|
||||
|
||||
extern int gOverlappingSimplePairs;
|
||||
extern int gRemoveSimplePairs;
|
||||
extern int gAddedSimplePairs;
|
||||
extern int gFindSimplePairs;
|
||||
|
||||
|
||||
|
||||
|
||||
class btHashedSimplePairCache
|
||||
{
|
||||
btSimplePairArray m_overlappingPairArray;
|
||||
|
||||
bool m_blockedForChanges;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
btAlignedObjectArray<int> m_hashTable;
|
||||
btAlignedObjectArray<int> m_next;
|
||||
|
||||
|
||||
public:
|
||||
btHashedSimplePairCache();
|
||||
virtual ~btHashedSimplePairCache();
|
||||
|
||||
void removeAllPairs();
|
||||
|
||||
virtual void* removeOverlappingPair(int indexA,int indexB);
|
||||
|
||||
// Add a pair and return the new pair. If the pair already exists,
|
||||
// no new pair is created and the old one is returned.
|
||||
virtual btSimplePair* addOverlappingPair(int indexA,int indexB)
|
||||
{
|
||||
gAddedSimplePairs++;
|
||||
|
||||
return internalAddPair(indexA,indexB);
|
||||
}
|
||||
|
||||
|
||||
virtual btSimplePair* getOverlappingPairArrayPtr()
|
||||
{
|
||||
return &m_overlappingPairArray[0];
|
||||
}
|
||||
|
||||
const btSimplePair* getOverlappingPairArrayPtr() const
|
||||
{
|
||||
return &m_overlappingPairArray[0];
|
||||
}
|
||||
|
||||
btSimplePairArray& getOverlappingPairArray()
|
||||
{
|
||||
return m_overlappingPairArray;
|
||||
}
|
||||
|
||||
const btSimplePairArray& getOverlappingPairArray() const
|
||||
{
|
||||
return m_overlappingPairArray;
|
||||
}
|
||||
|
||||
|
||||
btSimplePair* findPair(int indexA,int indexB);
|
||||
|
||||
int GetCount() const { return m_overlappingPairArray.size(); }
|
||||
|
||||
int getNumOverlappingPairs() const
|
||||
{
|
||||
return m_overlappingPairArray.size();
|
||||
}
|
||||
private:
|
||||
|
||||
btSimplePair* internalAddPair(int indexA, int indexB);
|
||||
|
||||
void growTables();
|
||||
|
||||
SIMD_FORCE_INLINE bool equalsPair(const btSimplePair& pair, int indexA, int indexB)
|
||||
{
|
||||
return pair.m_indexA == indexA && pair.m_indexB == indexB;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE unsigned int getHash(unsigned int indexA, unsigned int indexB)
|
||||
{
|
||||
int key = static_cast<int>(((unsigned int)indexA) | (((unsigned int)indexB) <<16));
|
||||
// Thomas Wang's hash
|
||||
|
||||
key += ~(key << 15);
|
||||
key ^= (key >> 10);
|
||||
key += (key << 3);
|
||||
key ^= (key >> 6);
|
||||
key += ~(key << 11);
|
||||
key ^= (key >> 16);
|
||||
return static_cast<unsigned int>(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE btSimplePair* internalFindPair(int proxyIdA , int proxyIdB, int hash)
|
||||
{
|
||||
|
||||
int index = m_hashTable[hash];
|
||||
|
||||
while( index != BT_SIMPLE_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyIdA, proxyIdB) == false)
|
||||
{
|
||||
index = m_next[index];
|
||||
}
|
||||
|
||||
if ( index == BT_SIMPLE_NULL_PAIR )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
btAssert(index < m_overlappingPairArray.size());
|
||||
|
||||
return &m_overlappingPairArray[index];
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //BT_HASHED_SIMPLE_PAIR_CACHE_H
|
||||
|
||||
|
@@ -273,6 +273,8 @@ void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransf
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void btCompoundShape::setLocalScaling(const btVector3& scaling)
|
||||
{
|
||||
|
||||
@@ -283,7 +285,7 @@ void btCompoundShape::setLocalScaling(const btVector3& scaling)
|
||||
// childScale = childScale * (childTrans.getBasis() * scaling);
|
||||
childScale = childScale * scaling / m_localScaling;
|
||||
m_children[i].m_childShape->setLocalScaling(childScale);
|
||||
childTrans.setOrigin((childTrans.getOrigin())*scaling);
|
||||
childTrans.setOrigin((childTrans.getOrigin()) * scaling / m_localScaling);
|
||||
updateChildTransform(i, childTrans,false);
|
||||
}
|
||||
|
||||
|
@@ -62,6 +62,10 @@ void btConeShape::setConeUpIndex(int upIndex)
|
||||
default:
|
||||
btAssert(0);
|
||||
};
|
||||
|
||||
m_implicitShapeDimensions[m_coneIndices[0]] = m_radius;
|
||||
m_implicitShapeDimensions[m_coneIndices[1]] = m_height;
|
||||
m_implicitShapeDimensions[m_coneIndices[2]] = m_radius;
|
||||
}
|
||||
|
||||
btVector3 btConeShape::coneLocalSupport(const btVector3& v) const
|
||||
|
@@ -90,6 +90,13 @@ public:
|
||||
}
|
||||
|
||||
virtual void setLocalScaling(const btVector3& scaling);
|
||||
|
||||
|
||||
virtual int calculateSerializeBufferSize() const;
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -104,19 +111,61 @@ class btConeShapeX : public btConeShape
|
||||
return btVector3 (1,0,0);
|
||||
}
|
||||
|
||||
//debugging
|
||||
virtual const char* getName()const
|
||||
{
|
||||
return "ConeX";
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
///btConeShapeZ implements a Cone shape, around the Z axis
|
||||
class btConeShapeZ : public btConeShape
|
||||
{
|
||||
public:
|
||||
btConeShapeZ(btScalar radius,btScalar height);
|
||||
public:
|
||||
btConeShapeZ(btScalar radius,btScalar height);
|
||||
|
||||
virtual btVector3 getAnisotropicRollingFrictionDirection() const
|
||||
{
|
||||
return btVector3 (0,0,1);
|
||||
}
|
||||
|
||||
//debugging
|
||||
virtual const char* getName()const
|
||||
{
|
||||
return "ConeZ";
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
struct btConeShapeData
|
||||
{
|
||||
btConvexInternalShapeData m_convexInternalShapeData;
|
||||
|
||||
int m_upIndex;
|
||||
|
||||
char m_padding[4];
|
||||
};
|
||||
|
||||
SIMD_FORCE_INLINE int btConeShape::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btConeShapeData);
|
||||
}
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
SIMD_FORCE_INLINE const char* btConeShape::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
btConeShapeData* shapeData = (btConeShapeData*) dataBuffer;
|
||||
|
||||
btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer);
|
||||
|
||||
shapeData->m_upIndex = m_coneIndices[1];
|
||||
|
||||
return "btConeShapeData";
|
||||
}
|
||||
|
||||
#endif //BT_CONE_MINKOWSKI_H
|
||||
|
||||
|
@@ -21,6 +21,7 @@ subject to the following restrictions:
|
||||
#include "btTriangleShape.h"
|
||||
#include "btSphereShape.h"
|
||||
#include "btCylinderShape.h"
|
||||
#include "btConeShape.h"
|
||||
#include "btCapsuleShape.h"
|
||||
#include "btConvexHullShape.h"
|
||||
#include "btConvexPointCloudShape.h"
|
||||
@@ -336,6 +337,11 @@ btScalar btConvexShape::getMarginNonVirtual () const
|
||||
btCylinderShape* cylShape = (btCylinderShape*)this;
|
||||
return cylShape->getMarginNV();
|
||||
}
|
||||
case CONE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btConeShape* conShape = (btConeShape*)this;
|
||||
return conShape->getMarginNV();
|
||||
}
|
||||
case CAPSULE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
|
||||
|
@@ -369,7 +369,7 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
|
||||
getVertex(x+1,j+1,vertices[2]);
|
||||
callback->processTriangle(vertices,x,j);
|
||||
//second triangle
|
||||
getVertex(x,j,vertices[0]);
|
||||
// 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);
|
||||
@@ -382,7 +382,7 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
|
||||
callback->processTriangle(vertices,x,j);
|
||||
//second triangle
|
||||
getVertex(x+1,j,vertices[0]);
|
||||
getVertex(x,j+1,vertices[1]);
|
||||
//getVertex(x,j+1,vertices[1]);
|
||||
getVertex(x+1,j+1,vertices[2]);
|
||||
callback->processTriangle(vertices,x,j);
|
||||
}
|
||||
|
@@ -111,10 +111,10 @@ int btTriangleMesh::findOrAddVertex(const btVector3& vertex, bool removeDuplicat
|
||||
return i/3;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_3componentVertices.push_back((float)vertex.getX());
|
||||
m_3componentVertices.push_back((float)vertex.getY());
|
||||
m_3componentVertices.push_back((float)vertex.getZ());
|
||||
}
|
||||
m_3componentVertices.push_back(vertex.getX());
|
||||
m_3componentVertices.push_back(vertex.getY());
|
||||
m_3componentVertices.push_back(vertex.getZ());
|
||||
m_indexedMeshes[0].m_numVertices++;
|
||||
m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_3componentVertices[0];
|
||||
return (m_3componentVertices.size()/3)-1;
|
||||
|
@@ -27,7 +27,7 @@ subject to the following restrictions:
|
||||
class btTriangleMesh : public btTriangleIndexVertexArray
|
||||
{
|
||||
btAlignedObjectArray<btVector3> m_4componentVertices;
|
||||
btAlignedObjectArray<float> m_3componentVertices;
|
||||
btAlignedObjectArray<btScalar> m_3componentVertices;
|
||||
|
||||
btAlignedObjectArray<unsigned int> m_32bitIndices;
|
||||
btAlignedObjectArray<unsigned short int> m_16bitIndices;
|
||||
|
@@ -17,7 +17,6 @@ subject to the following restrictions:
|
||||
#ifndef BT_CONVEX_PENETRATION_DEPTH_H
|
||||
#define BT_CONVEX_PENETRATION_DEPTH_H
|
||||
|
||||
class btStackAlloc;
|
||||
class btVector3;
|
||||
#include "btSimplexSolverInterface.h"
|
||||
class btConvexShape;
|
||||
@@ -33,8 +32,7 @@ public:
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
) = 0;
|
||||
class btIDebugDraw* debugDraw) = 0;
|
||||
|
||||
|
||||
};
|
||||
|
@@ -19,7 +19,6 @@ subject to the following restrictions:
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
class btStackAlloc;
|
||||
|
||||
/// This interface is made to be used by an iterative approach to do TimeOfImpact calculations
|
||||
/// This interface allows to query for closest points and penetration depth between two (convex) objects
|
||||
@@ -43,15 +42,13 @@ struct btDiscreteCollisionDetectorInterface
|
||||
struct ClosestPointInput
|
||||
{
|
||||
ClosestPointInput()
|
||||
:m_maximumDistanceSquared(btScalar(BT_LARGE_FLOAT)),
|
||||
m_stackAlloc(0)
|
||||
:m_maximumDistanceSquared(btScalar(BT_LARGE_FLOAT))
|
||||
{
|
||||
}
|
||||
|
||||
btTransform m_transformA;
|
||||
btTransform m_transformB;
|
||||
btScalar m_maximumDistanceSquared;
|
||||
btStackAlloc* m_stackAlloc;
|
||||
};
|
||||
|
||||
virtual ~btDiscreteCollisionDetectorInterface() {};
|
||||
|
@@ -25,7 +25,7 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& sim
|
||||
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
|
||||
const btTransform& transformA, const btTransform& transformB,
|
||||
btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
|
||||
class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc )
|
||||
class btIDebugDraw* debugDraw)
|
||||
{
|
||||
|
||||
(void)debugDraw;
|
||||
@@ -34,7 +34,7 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& sim
|
||||
|
||||
// const btScalar radialmargin(btScalar(0.));
|
||||
|
||||
btVector3 guessVector(transformA.getOrigin()-transformB.getOrigin());
|
||||
btVector3 guessVector(transformB.getOrigin()-transformA.getOrigin());
|
||||
btGjkEpaSolver2::sResults results;
|
||||
|
||||
|
||||
|
@@ -33,7 +33,7 @@ class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver
|
||||
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
|
||||
const btTransform& transformA, const btTransform& transformB,
|
||||
btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc );
|
||||
class btIDebugDraw* debugDraw);
|
||||
|
||||
private :
|
||||
|
||||
|
@@ -50,7 +50,8 @@ m_marginA(objectA->getMargin()),
|
||||
m_marginB(objectB->getMargin()),
|
||||
m_ignoreMargin(false),
|
||||
m_lastUsedMethod(-1),
|
||||
m_catchDegeneracies(1)
|
||||
m_catchDegeneracies(1),
|
||||
m_fixContactNormalDirection(1)
|
||||
{
|
||||
}
|
||||
btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver)
|
||||
@@ -65,7 +66,8 @@ m_marginA(marginA),
|
||||
m_marginB(marginB),
|
||||
m_ignoreMargin(false),
|
||||
m_lastUsedMethod(-1),
|
||||
m_catchDegeneracies(1)
|
||||
m_catchDegeneracies(1),
|
||||
m_fixContactNormalDirection(1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -353,7 +355,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
|
||||
m_minkowskiA,m_minkowskiB,
|
||||
localTransA,localTransB,
|
||||
m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB,
|
||||
debugDraw,input.m_stackAlloc
|
||||
debugDraw
|
||||
);
|
||||
|
||||
|
||||
@@ -438,6 +440,27 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu
|
||||
}
|
||||
#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;
|
||||
|
||||
|
@@ -52,7 +52,7 @@ public:
|
||||
int m_curIter;
|
||||
int m_degenerateSimplex;
|
||||
int m_catchDegeneracies;
|
||||
|
||||
int m_fixContactNormalDirection;
|
||||
|
||||
btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver);
|
||||
btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver);
|
||||
|
@@ -26,11 +26,10 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
class btIDebugDraw* debugDraw
|
||||
)
|
||||
{
|
||||
|
||||
(void)stackAlloc;
|
||||
(void)v;
|
||||
|
||||
bool check2d= convexA->isConvex2d() && convexB->isConvex2d();
|
||||
|
@@ -32,7 +32,7 @@ public:
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
class btIDebugDraw* debugDraw
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -35,7 +35,7 @@ public:
|
||||
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
|
||||
kF_Terminator = 0xFFFFFFFF
|
||||
};
|
||||
unsigned int m_flags;
|
||||
|
@@ -31,7 +31,7 @@ public:
|
||||
|
||||
virtual void setWalkDirection(const btVector3& walkDirection) = 0;
|
||||
virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0;
|
||||
virtual void reset () = 0;
|
||||
virtual void reset ( btCollisionWorld* collisionWorld ) = 0;
|
||||
virtual void warp (const btVector3& origin) = 0;
|
||||
|
||||
virtual void preStep ( btCollisionWorld* collisionWorld) = 0;
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
virtual void jump () = 0;
|
||||
|
||||
virtual bool onGround () const = 0;
|
||||
virtual void setUpInterpolate (bool value) = 0;
|
||||
};
|
||||
|
||||
#endif //BT_CHARACTER_CONTROLLER_INTERFACE_H
|
||||
|
@@ -14,6 +14,7 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "LinearMath/btIDebugDraw.h"
|
||||
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
|
||||
#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
|
||||
@@ -79,7 +80,7 @@ public:
|
||||
|
||||
if (!convexResult.m_hitCollisionObject->hasContactResponse())
|
||||
return btScalar(1.0);
|
||||
|
||||
|
||||
btVector3 hitNormalWorld;
|
||||
if (normalInWorldSpace)
|
||||
{
|
||||
@@ -149,7 +150,11 @@ btKinematicCharacterController::btKinematicCharacterController (btPairCachingGho
|
||||
m_jumpSpeed = 10.0; // ?
|
||||
m_wasOnGround = false;
|
||||
m_wasJumping = false;
|
||||
m_interpolateUp = true;
|
||||
setMaxSlope(btRadians(45.0));
|
||||
m_currentStepOffset = 0;
|
||||
full_drop = false;
|
||||
bounce_fix = false;
|
||||
}
|
||||
|
||||
btKinematicCharacterController::~btKinematicCharacterController ()
|
||||
@@ -190,9 +195,10 @@ bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld*
|
||||
m_manifoldArray.resize(0);
|
||||
|
||||
btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
|
||||
|
||||
btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
|
||||
btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
|
||||
|
||||
btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
|
||||
|
||||
if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
|
||||
continue;
|
||||
|
||||
@@ -268,7 +274,10 @@ void btKinematicCharacterController::stepUp ( btCollisionWorld* world)
|
||||
{
|
||||
// we moved up only a fraction of the step height
|
||||
m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
|
||||
m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
|
||||
if (m_interpolateUp == true)
|
||||
m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
|
||||
else
|
||||
m_currentPosition = m_targetPosition;
|
||||
}
|
||||
m_verticalVelocity = 0.0;
|
||||
m_verticalOffset = 0.0;
|
||||
@@ -333,7 +342,8 @@ void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* co
|
||||
{
|
||||
if (m_normalizedDirection.dot(m_touchingNormal) > btScalar(0.0))
|
||||
{
|
||||
updateTargetPositionBasedOnCollision (m_touchingNormal);
|
||||
//interferes with step movement
|
||||
//updateTargetPositionBasedOnCollision (m_touchingNormal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +415,8 @@ void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* co
|
||||
|
||||
void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt)
|
||||
{
|
||||
btTransform start, end;
|
||||
btTransform start, end, end_double;
|
||||
bool runonce = false;
|
||||
|
||||
// phase 3: down
|
||||
/*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
|
||||
@@ -414,44 +425,124 @@ void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld
|
||||
btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity;
|
||||
m_targetPosition -= (step_drop + gravity_drop);*/
|
||||
|
||||
btVector3 orig_position = m_targetPosition;
|
||||
|
||||
btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
|
||||
if(downVelocity > 0.0 && downVelocity < m_stepHeight
|
||||
|
||||
if(downVelocity > 0.0 && downVelocity > m_fallSpeed
|
||||
&& (m_wasOnGround || !m_wasJumping))
|
||||
{
|
||||
downVelocity = m_stepHeight;
|
||||
}
|
||||
downVelocity = m_fallSpeed;
|
||||
|
||||
btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
|
||||
m_targetPosition -= step_drop;
|
||||
|
||||
start.setIdentity ();
|
||||
end.setIdentity ();
|
||||
|
||||
start.setOrigin (m_currentPosition);
|
||||
end.setOrigin (m_targetPosition);
|
||||
|
||||
btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
|
||||
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
|
||||
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
|
||||
callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
|
||||
callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
|
||||
|
||||
btKinematicClosestNotMeConvexResultCallback callback2 (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
|
||||
callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
|
||||
callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
|
||||
|
||||
while (1)
|
||||
{
|
||||
start.setIdentity ();
|
||||
end.setIdentity ();
|
||||
|
||||
end_double.setIdentity ();
|
||||
|
||||
start.setOrigin (m_currentPosition);
|
||||
end.setOrigin (m_targetPosition);
|
||||
|
||||
//set double test for 2x the step drop, to check for a large drop vs small drop
|
||||
end_double.setOrigin (m_targetPosition - step_drop);
|
||||
|
||||
if (m_useGhostObjectSweepTest)
|
||||
{
|
||||
m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
|
||||
|
||||
if (!callback.hasHit())
|
||||
{
|
||||
//test a double fall height, to see if the character should interpolate it's fall (full) or not (partial)
|
||||
m_ghostObject->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
|
||||
}
|
||||
} else
|
||||
{
|
||||
collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
|
||||
|
||||
if (!callback.hasHit())
|
||||
{
|
||||
//test a double fall height, to see if the character should interpolate it's fall (large) or not (small)
|
||||
collisionWorld->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_useGhostObjectSweepTest)
|
||||
{
|
||||
m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
|
||||
} else
|
||||
{
|
||||
collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
|
||||
btScalar downVelocity2 = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
|
||||
bool has_hit = false;
|
||||
if (bounce_fix == true)
|
||||
has_hit = callback.hasHit() || callback2.hasHit();
|
||||
else
|
||||
has_hit = callback2.hasHit();
|
||||
|
||||
if(downVelocity2 > 0.0 && downVelocity2 < m_stepHeight && has_hit == true && runonce == false
|
||||
&& (m_wasOnGround || !m_wasJumping))
|
||||
{
|
||||
//redo the velocity calculation when falling a small amount, for fast stairs motion
|
||||
//for larger falls, use the smoother/slower interpolated movement by not touching the target position
|
||||
|
||||
m_targetPosition = orig_position;
|
||||
downVelocity = m_stepHeight;
|
||||
|
||||
btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
|
||||
m_targetPosition -= step_drop;
|
||||
runonce = true;
|
||||
continue; //re-run previous tests
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (callback.hasHit())
|
||||
if (callback.hasHit() || runonce == true)
|
||||
{
|
||||
// we dropped a fraction of the height -> hit floor
|
||||
m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
|
||||
|
||||
btScalar fraction = (m_currentPosition.getY() - callback.m_hitPointWorld.getY()) / 2;
|
||||
|
||||
//printf("hitpoint: %g - pos %g\n", callback.m_hitPointWorld.getY(), m_currentPosition.getY());
|
||||
|
||||
if (bounce_fix == true)
|
||||
{
|
||||
if (full_drop == true)
|
||||
m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
|
||||
else
|
||||
//due to errors in the closestHitFraction variable when used with large polygons, calculate the hit fraction manually
|
||||
m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, fraction);
|
||||
}
|
||||
else
|
||||
m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
|
||||
|
||||
full_drop = false;
|
||||
|
||||
m_verticalVelocity = 0.0;
|
||||
m_verticalOffset = 0.0;
|
||||
m_wasJumping = false;
|
||||
} else {
|
||||
// we dropped the full height
|
||||
|
||||
full_drop = true;
|
||||
|
||||
if (bounce_fix == true)
|
||||
{
|
||||
downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
|
||||
if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping))
|
||||
{
|
||||
m_targetPosition += step_drop; //undo previous target change
|
||||
downVelocity = m_fallSpeed;
|
||||
step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
|
||||
m_targetPosition -= step_drop;
|
||||
}
|
||||
}
|
||||
//printf("full drop - %g, %g\n", m_currentPosition.getY(), m_targetPosition.getY());
|
||||
|
||||
m_currentPosition = m_targetPosition;
|
||||
}
|
||||
}
|
||||
@@ -484,13 +575,24 @@ btScalar timeInterval
|
||||
m_useWalkDirection = false;
|
||||
m_walkDirection = velocity;
|
||||
m_normalizedDirection = getNormalizedVector(m_walkDirection);
|
||||
m_velocityTimeInterval = timeInterval;
|
||||
m_velocityTimeInterval += timeInterval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btKinematicCharacterController::reset ()
|
||||
void btKinematicCharacterController::reset ( btCollisionWorld* collisionWorld )
|
||||
{
|
||||
m_verticalVelocity = 0.0;
|
||||
m_verticalOffset = 0.0;
|
||||
m_wasOnGround = false;
|
||||
m_wasJumping = false;
|
||||
m_walkDirection.setValue(0,0,0);
|
||||
m_velocityTimeInterval = 0.0;
|
||||
|
||||
//clear pair cache
|
||||
btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache();
|
||||
while (cache->getOverlappingPairArray().size() > 0)
|
||||
{
|
||||
cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher());
|
||||
}
|
||||
}
|
||||
|
||||
void btKinematicCharacterController::warp (const btVector3& origin)
|
||||
@@ -661,3 +763,8 @@ btVector3* btKinematicCharacterController::getUpAxisDirections()
|
||||
void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
|
||||
{
|
||||
}
|
||||
|
||||
void btKinematicCharacterController::setUpInterpolate(bool value)
|
||||
{
|
||||
m_interpolateUp = value;
|
||||
}
|
||||
|
@@ -81,6 +81,9 @@ protected:
|
||||
int m_upAxis;
|
||||
|
||||
static btVector3* getUpAxisDirections();
|
||||
bool m_interpolateUp;
|
||||
bool full_drop;
|
||||
bool bounce_fix;
|
||||
|
||||
btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
|
||||
btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
|
||||
@@ -133,7 +136,7 @@ public:
|
||||
virtual void setVelocityForTimeInterval(const btVector3& velocity,
|
||||
btScalar timeInterval);
|
||||
|
||||
void reset ();
|
||||
void reset ( btCollisionWorld* collisionWorld );
|
||||
void warp (const btVector3& origin);
|
||||
|
||||
void preStep ( btCollisionWorld* collisionWorld);
|
||||
@@ -161,6 +164,7 @@ public:
|
||||
}
|
||||
|
||||
bool onGround () const;
|
||||
void setUpInterpolate (bool value);
|
||||
};
|
||||
|
||||
#endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H
|
||||
|
@@ -40,6 +40,15 @@ and swing 1 and 2 are along the z and y axes respectively.
|
||||
#include "btJacobianEntry.h"
|
||||
#include "btTypedConstraint.h"
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btConeTwistConstraintData2 btConeTwistConstraintDoubleData
|
||||
#define btConeTwistConstraintDataName "btConeTwistConstraintDoubleData"
|
||||
#else
|
||||
#define btConeTwistConstraintData2 btConeTwistConstraintData
|
||||
#define btConeTwistConstraintDataName "btConeTwistConstraintData"
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
|
||||
class btRigidBody;
|
||||
|
||||
enum btConeTwistFlags
|
||||
@@ -295,7 +304,30 @@ public:
|
||||
|
||||
};
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
|
||||
|
||||
struct btConeTwistConstraintDoubleData
|
||||
{
|
||||
btTypedConstraintDoubleData m_typeConstraintData;
|
||||
btTransformDoubleData m_rbAFrame;
|
||||
btTransformDoubleData m_rbBFrame;
|
||||
|
||||
//limits
|
||||
double m_swingSpan1;
|
||||
double m_swingSpan2;
|
||||
double m_twistSpan;
|
||||
double m_limitSoftness;
|
||||
double m_biasFactor;
|
||||
double m_relaxationFactor;
|
||||
|
||||
double m_damping;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
|
||||
///this structure is not used, except for loading pre-2.82 .bullet files
|
||||
struct btConeTwistConstraintData
|
||||
{
|
||||
btTypedConstraintData m_typeConstraintData;
|
||||
@@ -315,12 +347,12 @@ struct btConeTwistConstraintData
|
||||
char m_pad[4];
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
|
||||
//
|
||||
|
||||
SIMD_FORCE_INLINE int btConeTwistConstraint::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btConeTwistConstraintData);
|
||||
return sizeof(btConeTwistConstraintData2);
|
||||
|
||||
}
|
||||
|
||||
@@ -328,21 +360,21 @@ SIMD_FORCE_INLINE int btConeTwistConstraint::calculateSerializeBufferSize() cons
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
SIMD_FORCE_INLINE const char* btConeTwistConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
btConeTwistConstraintData* cone = (btConeTwistConstraintData*) dataBuffer;
|
||||
btConeTwistConstraintData2* cone = (btConeTwistConstraintData2*) dataBuffer;
|
||||
btTypedConstraint::serialize(&cone->m_typeConstraintData,serializer);
|
||||
|
||||
m_rbAFrame.serializeFloat(cone->m_rbAFrame);
|
||||
m_rbBFrame.serializeFloat(cone->m_rbBFrame);
|
||||
m_rbAFrame.serialize(cone->m_rbAFrame);
|
||||
m_rbBFrame.serialize(cone->m_rbBFrame);
|
||||
|
||||
cone->m_swingSpan1 = float(m_swingSpan1);
|
||||
cone->m_swingSpan2 = float(m_swingSpan2);
|
||||
cone->m_twistSpan = float(m_twistSpan);
|
||||
cone->m_limitSoftness = float(m_limitSoftness);
|
||||
cone->m_biasFactor = float(m_biasFactor);
|
||||
cone->m_relaxationFactor = float(m_relaxationFactor);
|
||||
cone->m_damping = float(m_damping);
|
||||
cone->m_swingSpan1 = m_swingSpan1;
|
||||
cone->m_swingSpan2 = m_swingSpan2;
|
||||
cone->m_twistSpan = m_twistSpan;
|
||||
cone->m_limitSoftness = m_limitSoftness;
|
||||
cone->m_biasFactor = m_biasFactor;
|
||||
cone->m_relaxationFactor = m_relaxationFactor;
|
||||
cone->m_damping = m_damping;
|
||||
|
||||
return "btConeTwistConstraintData";
|
||||
return btConeTwistConstraintDataName;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -28,6 +28,14 @@ class btIDebugDraw;
|
||||
class btStackAlloc;
|
||||
class btDispatcher;
|
||||
/// btConstraintSolver provides solver interface
|
||||
|
||||
|
||||
enum btConstraintSolverType
|
||||
{
|
||||
BT_SEQUENTIAL_IMPULSE_SOLVER=1,
|
||||
BT_MLCP_SOLVER=2
|
||||
};
|
||||
|
||||
class btConstraintSolver
|
||||
{
|
||||
|
||||
@@ -38,12 +46,16 @@ public:
|
||||
virtual void prepareSolve (int /* numBodies */, int /* numManifolds */) {;}
|
||||
|
||||
///solve a group of constraints
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) = 0;
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer,btDispatcher* dispatcher) = 0;
|
||||
|
||||
virtual void allSolved (const btContactSolverInfo& /* info */,class btIDebugDraw* /* debugDrawer */, btStackAlloc* /* stackAlloc */) {;}
|
||||
virtual void allSolved (const btContactSolverInfo& /* info */,class btIDebugDraw* /* debugDrawer */) {;}
|
||||
|
||||
///clear internal cached data and reset random seed
|
||||
virtual void reset() = 0;
|
||||
|
||||
virtual btConstraintSolverType getSolverType() const=0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
129
extern/bullet2/src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp
vendored
Normal file
129
extern/bullet2/src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "btFixedConstraint.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
#include "LinearMath/btTransformUtil.h"
|
||||
#include <new>
|
||||
|
||||
|
||||
btFixedConstraint::btFixedConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& frameInA,const btTransform& frameInB)
|
||||
:btTypedConstraint(FIXED_CONSTRAINT_TYPE,rbA,rbB)
|
||||
{
|
||||
m_pivotInA = frameInA.getOrigin();
|
||||
m_pivotInB = frameInB.getOrigin();
|
||||
m_relTargetAB = frameInA.getRotation()*frameInB.getRotation().inverse();
|
||||
|
||||
}
|
||||
|
||||
btFixedConstraint::~btFixedConstraint ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void btFixedConstraint::getInfo1 (btConstraintInfo1* info)
|
||||
{
|
||||
info->m_numConstraintRows = 6;
|
||||
info->nub = 6;
|
||||
}
|
||||
|
||||
void btFixedConstraint::getInfo2 (btConstraintInfo2* info)
|
||||
{
|
||||
//fix the 3 linear degrees of freedom
|
||||
|
||||
|
||||
const btVector3& worldPosA = m_rbA.getCenterOfMassTransform().getOrigin();
|
||||
const btMatrix3x3& worldOrnA = m_rbA.getCenterOfMassTransform().getBasis();
|
||||
const btVector3& worldPosB= m_rbB.getCenterOfMassTransform().getOrigin();
|
||||
const btMatrix3x3& worldOrnB = m_rbB.getCenterOfMassTransform().getBasis();
|
||||
|
||||
|
||||
info->m_J1linearAxis[0] = 1;
|
||||
info->m_J1linearAxis[info->rowskip+1] = 1;
|
||||
info->m_J1linearAxis[2*info->rowskip+2] = 1;
|
||||
|
||||
btVector3 a1 = worldOrnA*m_pivotInA;
|
||||
{
|
||||
btVector3* angular0 = (btVector3*)(info->m_J1angularAxis);
|
||||
btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip);
|
||||
btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip);
|
||||
btVector3 a1neg = -a1;
|
||||
a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
|
||||
}
|
||||
|
||||
if (info->m_J2linearAxis)
|
||||
{
|
||||
info->m_J2linearAxis[0] = -1;
|
||||
info->m_J2linearAxis[info->rowskip+1] = -1;
|
||||
info->m_J2linearAxis[2*info->rowskip+2] = -1;
|
||||
}
|
||||
|
||||
btVector3 a2 = worldOrnB*m_pivotInB;
|
||||
|
||||
{
|
||||
// btVector3 a2n = -a2;
|
||||
btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
|
||||
btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip);
|
||||
btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip);
|
||||
a2.getSkewSymmetricMatrix(angular0,angular1,angular2);
|
||||
}
|
||||
|
||||
// set right hand side for the linear dofs
|
||||
btScalar k = info->fps * info->erp;
|
||||
|
||||
btVector3 linearError = k*(a2+worldPosB-a1-worldPosA);
|
||||
int j;
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
|
||||
|
||||
|
||||
info->m_constraintError[j*info->rowskip] = linearError[j];
|
||||
//printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]);
|
||||
}
|
||||
|
||||
//fix the 3 angular degrees of freedom
|
||||
|
||||
int start_row = 3;
|
||||
int s = info->rowskip;
|
||||
int start_index = start_row * s;
|
||||
|
||||
// 3 rows to make body rotations equal
|
||||
info->m_J1angularAxis[start_index] = 1;
|
||||
info->m_J1angularAxis[start_index + s + 1] = 1;
|
||||
info->m_J1angularAxis[start_index + s*2+2] = 1;
|
||||
if ( info->m_J2angularAxis)
|
||||
{
|
||||
info->m_J2angularAxis[start_index] = -1;
|
||||
info->m_J2angularAxis[start_index + s+1] = -1;
|
||||
info->m_J2angularAxis[start_index + s*2+2] = -1;
|
||||
}
|
||||
|
||||
// set right hand side for the angular dofs
|
||||
|
||||
btVector3 diff;
|
||||
btScalar angle;
|
||||
btMatrix3x3 mrelCur = worldOrnA *worldOrnB.inverse();
|
||||
btQuaternion qrelCur;
|
||||
mrelCur.getRotation(qrelCur);
|
||||
btTransformUtil::calculateDiffAxisAngleQuaternion(m_relTargetAB,qrelCur,diff,angle);
|
||||
diff*=-angle;
|
||||
for (j=0; j<3; j++)
|
||||
{
|
||||
info->m_constraintError[(3+j)*info->rowskip] = k * diff[j];
|
||||
}
|
||||
|
||||
}
|
49
extern/bullet2/src/BulletDynamics/ConstraintSolver/btFixedConstraint.h
vendored
Normal file
49
extern/bullet2/src/BulletDynamics/ConstraintSolver/btFixedConstraint.h
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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_FIXED_CONSTRAINT_H
|
||||
#define BT_FIXED_CONSTRAINT_H
|
||||
|
||||
#include "btTypedConstraint.h"
|
||||
|
||||
ATTRIBUTE_ALIGNED16(class) btFixedConstraint : public btTypedConstraint
|
||||
{
|
||||
btVector3 m_pivotInA;
|
||||
btVector3 m_pivotInB;
|
||||
btQuaternion m_relTargetAB;
|
||||
|
||||
public:
|
||||
btFixedConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& frameInA,const btTransform& frameInB);
|
||||
|
||||
virtual ~btFixedConstraint();
|
||||
|
||||
|
||||
virtual void getInfo1 (btConstraintInfo1* info);
|
||||
|
||||
virtual void getInfo2 (btConstraintInfo2* info);
|
||||
|
||||
virtual void setParam(int num, btScalar value, int axis = -1)
|
||||
{
|
||||
btAssert(0);
|
||||
}
|
||||
virtual btScalar getParam(int num, int axis = -1) const
|
||||
{
|
||||
btAssert(0);
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_FIXED_CONSTRAINT_H
|
@@ -19,6 +19,18 @@ subject to the following restrictions:
|
||||
#define BT_GEAR_CONSTRAINT_H
|
||||
|
||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btGearConstraintData btGearConstraintDoubleData
|
||||
#define btGearConstraintDataName "btGearConstraintDoubleData"
|
||||
#else
|
||||
#define btGearConstraintData btGearConstraintFloatData
|
||||
#define btGearConstraintDataName "btGearConstraintFloatData"
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
|
||||
|
||||
///The btGeatConstraint will couple the angular velocity for two bodies around given local axis and ratio.
|
||||
///See Bullet/Demos/ConstraintDemo for an example use.
|
||||
class btGearConstraint : public btTypedConstraint
|
||||
@@ -39,18 +51,102 @@ public:
|
||||
///internal method used by the constraint solver, don't use them directly
|
||||
virtual void getInfo2 (btConstraintInfo2* info);
|
||||
|
||||
void setAxisA(btVector3& axisA)
|
||||
{
|
||||
m_axisInA = axisA;
|
||||
}
|
||||
void setAxisB(btVector3& axisB)
|
||||
{
|
||||
m_axisInB = axisB;
|
||||
}
|
||||
void setRatio(btScalar ratio)
|
||||
{
|
||||
m_ratio = ratio;
|
||||
}
|
||||
const btVector3& getAxisA() const
|
||||
{
|
||||
return m_axisInA;
|
||||
}
|
||||
const btVector3& getAxisB() const
|
||||
{
|
||||
return m_axisInB;
|
||||
}
|
||||
btScalar getRatio() const
|
||||
{
|
||||
return m_ratio;
|
||||
}
|
||||
|
||||
|
||||
virtual void setParam(int num, btScalar value, int axis = -1)
|
||||
{
|
||||
(void) num;
|
||||
(void) value;
|
||||
(void) axis;
|
||||
btAssert(0);
|
||||
};
|
||||
}
|
||||
|
||||
///return the local value of parameter
|
||||
virtual btScalar getParam(int num, int axis = -1) const
|
||||
{
|
||||
(void) num;
|
||||
(void) axis;
|
||||
btAssert(0);
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
virtual int calculateSerializeBufferSize() const;
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
struct btGearConstraintFloatData
|
||||
{
|
||||
btTypedConstraintFloatData m_typeConstraintData;
|
||||
|
||||
btVector3FloatData m_axisInA;
|
||||
btVector3FloatData m_axisInB;
|
||||
|
||||
float m_ratio;
|
||||
char m_padding[4];
|
||||
};
|
||||
|
||||
struct btGearConstraintDoubleData
|
||||
{
|
||||
btTypedConstraintDoubleData m_typeConstraintData;
|
||||
|
||||
btVector3DoubleData m_axisInA;
|
||||
btVector3DoubleData m_axisInB;
|
||||
|
||||
double m_ratio;
|
||||
};
|
||||
|
||||
SIMD_FORCE_INLINE int btGearConstraint::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btGearConstraintData);
|
||||
}
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
SIMD_FORCE_INLINE const char* btGearConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
btGearConstraintData* gear = (btGearConstraintData*)dataBuffer;
|
||||
btTypedConstraint::serialize(&gear->m_typeConstraintData,serializer);
|
||||
|
||||
m_axisInA.serialize( gear->m_axisInA );
|
||||
m_axisInB.serialize( gear->m_axisInB );
|
||||
|
||||
gear->m_ratio = m_ratio;
|
||||
|
||||
return btGearConstraintDataName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //BT_GEAR_CONSTRAINT_H
|
||||
|
@@ -35,6 +35,14 @@ class btRigidBody;
|
||||
|
||||
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btGeneric6DofConstraintData2 btGeneric6DofConstraintDoubleData2
|
||||
#define btGeneric6DofConstraintDataName "btGeneric6DofConstraintDoubleData2"
|
||||
#else
|
||||
#define btGeneric6DofConstraintData2 btGeneric6DofConstraintData
|
||||
#define btGeneric6DofConstraintDataName "btGeneric6DofConstraintData"
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
|
||||
//! Rotation Limit structure for generic joints
|
||||
class btRotationalLimitMotor
|
||||
@@ -561,7 +569,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
|
||||
struct btGeneric6DofConstraintData
|
||||
{
|
||||
btTypedConstraintData m_typeConstraintData;
|
||||
@@ -578,35 +586,51 @@ struct btGeneric6DofConstraintData
|
||||
int m_useOffsetForConstraintFrame;
|
||||
};
|
||||
|
||||
struct btGeneric6DofConstraintDoubleData2
|
||||
{
|
||||
btTypedConstraintDoubleData m_typeConstraintData;
|
||||
btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
|
||||
btTransformDoubleData m_rbBFrame;
|
||||
|
||||
btVector3DoubleData m_linearUpperLimit;
|
||||
btVector3DoubleData m_linearLowerLimit;
|
||||
|
||||
btVector3DoubleData m_angularUpperLimit;
|
||||
btVector3DoubleData m_angularLowerLimit;
|
||||
|
||||
int m_useLinearReferenceFrameA;
|
||||
int m_useOffsetForConstraintFrame;
|
||||
};
|
||||
|
||||
SIMD_FORCE_INLINE int btGeneric6DofConstraint::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btGeneric6DofConstraintData);
|
||||
return sizeof(btGeneric6DofConstraintData2);
|
||||
}
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
SIMD_FORCE_INLINE const char* btGeneric6DofConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
|
||||
btGeneric6DofConstraintData* dof = (btGeneric6DofConstraintData*)dataBuffer;
|
||||
btGeneric6DofConstraintData2* dof = (btGeneric6DofConstraintData2*)dataBuffer;
|
||||
btTypedConstraint::serialize(&dof->m_typeConstraintData,serializer);
|
||||
|
||||
m_frameInA.serializeFloat(dof->m_rbAFrame);
|
||||
m_frameInB.serializeFloat(dof->m_rbBFrame);
|
||||
m_frameInA.serialize(dof->m_rbAFrame);
|
||||
m_frameInB.serialize(dof->m_rbBFrame);
|
||||
|
||||
|
||||
int i;
|
||||
for (i=0;i<3;i++)
|
||||
{
|
||||
dof->m_angularLowerLimit.m_floats[i] = float(m_angularLimits[i].m_loLimit);
|
||||
dof->m_angularUpperLimit.m_floats[i] = float(m_angularLimits[i].m_hiLimit);
|
||||
dof->m_linearLowerLimit.m_floats[i] = float(m_linearLimits.m_lowerLimit[i]);
|
||||
dof->m_linearUpperLimit.m_floats[i] = float(m_linearLimits.m_upperLimit[i]);
|
||||
dof->m_angularLowerLimit.m_floats[i] = m_angularLimits[i].m_loLimit;
|
||||
dof->m_angularUpperLimit.m_floats[i] = m_angularLimits[i].m_hiLimit;
|
||||
dof->m_linearLowerLimit.m_floats[i] = m_linearLimits.m_lowerLimit[i];
|
||||
dof->m_linearUpperLimit.m_floats[i] = m_linearLimits.m_upperLimit[i];
|
||||
}
|
||||
|
||||
dof->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA? 1 : 0;
|
||||
dof->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame ? 1 : 0;
|
||||
|
||||
return "btGeneric6DofConstraintData";
|
||||
return btGeneric6DofConstraintDataName;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -21,6 +21,15 @@ subject to the following restrictions:
|
||||
#include "btTypedConstraint.h"
|
||||
#include "btGeneric6DofConstraint.h"
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btGeneric6DofSpringConstraintData2 btGeneric6DofSpringConstraintDoubleData2
|
||||
#define btGeneric6DofSpringConstraintDataName "btGeneric6DofSpringConstraintDoubleData2"
|
||||
#else
|
||||
#define btGeneric6DofSpringConstraintData2 btGeneric6DofSpringConstraintData
|
||||
#define btGeneric6DofSpringConstraintDataName "btGeneric6DofSpringConstraintData"
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
|
||||
|
||||
/// Generic 6 DOF constraint that allows to set spring motors to any translational and rotational DOF
|
||||
|
||||
@@ -65,7 +74,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
struct btGeneric6DofSpringConstraintData
|
||||
{
|
||||
btGeneric6DofConstraintData m_6dofData;
|
||||
@@ -76,26 +84,37 @@ struct btGeneric6DofSpringConstraintData
|
||||
float m_springDamping[6];
|
||||
};
|
||||
|
||||
struct btGeneric6DofSpringConstraintDoubleData2
|
||||
{
|
||||
btGeneric6DofConstraintDoubleData2 m_6dofData;
|
||||
|
||||
int m_springEnabled[6];
|
||||
double m_equilibriumPoint[6];
|
||||
double m_springStiffness[6];
|
||||
double m_springDamping[6];
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btGeneric6DofSpringConstraint::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btGeneric6DofSpringConstraintData);
|
||||
return sizeof(btGeneric6DofSpringConstraintData2);
|
||||
}
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
SIMD_FORCE_INLINE const char* btGeneric6DofSpringConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
btGeneric6DofSpringConstraintData* dof = (btGeneric6DofSpringConstraintData*)dataBuffer;
|
||||
btGeneric6DofSpringConstraintData2* dof = (btGeneric6DofSpringConstraintData2*)dataBuffer;
|
||||
btGeneric6DofConstraint::serialize(&dof->m_6dofData,serializer);
|
||||
|
||||
int i;
|
||||
for (i=0;i<6;i++)
|
||||
{
|
||||
dof->m_equilibriumPoint[i] = (float)m_equilibriumPoint[i];
|
||||
dof->m_springDamping[i] = (float)m_springDamping[i];
|
||||
dof->m_equilibriumPoint[i] = m_equilibriumPoint[i];
|
||||
dof->m_springDamping[i] = m_springDamping[i];
|
||||
dof->m_springEnabled[i] = m_springEnabled[i]? 1 : 0;
|
||||
dof->m_springStiffness[i] = (float)m_springStiffness[i];
|
||||
dof->m_springStiffness[i] = m_springStiffness[i];
|
||||
}
|
||||
return "btGeneric6DofSpringConstraintData";
|
||||
return btGeneric6DofSpringConstraintDataName;
|
||||
}
|
||||
|
||||
#endif // BT_GENERIC_6DOF_SPRING_CONSTRAINT_H
|
||||
|
@@ -28,8 +28,8 @@ subject to the following restrictions:
|
||||
class btRigidBody;
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btHingeConstraintData btHingeConstraintDoubleData
|
||||
#define btHingeConstraintDataName "btHingeConstraintDoubleData"
|
||||
#define btHingeConstraintData btHingeConstraintDoubleData2 //rename to 2 for backwards compatibility, so we can still load the 'btHingeConstraintDoubleData' version
|
||||
#define btHingeConstraintDataName "btHingeConstraintDoubleData2"
|
||||
#else
|
||||
#define btHingeConstraintData btHingeConstraintFloatData
|
||||
#define btHingeConstraintDataName "btHingeConstraintFloatData"
|
||||
@@ -302,7 +302,10 @@ public:
|
||||
|
||||
};
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
|
||||
//only for backward compatibility
|
||||
#ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
|
||||
///this structure is not used, except for loading pre-2.82 .bullet files
|
||||
struct btHingeConstraintDoubleData
|
||||
{
|
||||
btTypedConstraintData m_typeConstraintData;
|
||||
@@ -321,7 +324,9 @@ struct btHingeConstraintDoubleData
|
||||
float m_relaxationFactor;
|
||||
|
||||
};
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
|
||||
|
||||
|
||||
struct btHingeConstraintFloatData
|
||||
{
|
||||
btTypedConstraintData m_typeConstraintData;
|
||||
@@ -344,6 +349,30 @@ struct btHingeConstraintFloatData
|
||||
|
||||
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
struct btHingeConstraintDoubleData2
|
||||
{
|
||||
btTypedConstraintDoubleData m_typeConstraintData;
|
||||
btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
|
||||
btTransformDoubleData m_rbBFrame;
|
||||
int m_useReferenceFrameA;
|
||||
int m_angularOnly;
|
||||
int m_enableAngularMotor;
|
||||
double m_motorTargetVelocity;
|
||||
double m_maxMotorImpulse;
|
||||
|
||||
double m_lowerLimit;
|
||||
double m_upperLimit;
|
||||
double m_limitSoftness;
|
||||
double m_biasFactor;
|
||||
double m_relaxationFactor;
|
||||
char m_padding1[4];
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btHingeConstraint::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btHingeConstraintData);
|
||||
|
@@ -24,10 +24,10 @@ class btRigidBody;
|
||||
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btPoint2PointConstraintData btPoint2PointConstraintDoubleData
|
||||
#define btPoint2PointConstraintDataName "btPoint2PointConstraintDoubleData"
|
||||
#define btPoint2PointConstraintData2 btPoint2PointConstraintDoubleData2
|
||||
#define btPoint2PointConstraintDataName "btPoint2PointConstraintDoubleData2"
|
||||
#else
|
||||
#define btPoint2PointConstraintData btPoint2PointConstraintFloatData
|
||||
#define btPoint2PointConstraintData2 btPoint2PointConstraintFloatData
|
||||
#define btPoint2PointConstraintDataName "btPoint2PointConstraintFloatData"
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
@@ -133,6 +133,17 @@ struct btPoint2PointConstraintFloatData
|
||||
btVector3FloatData m_pivotInB;
|
||||
};
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
struct btPoint2PointConstraintDoubleData2
|
||||
{
|
||||
btTypedConstraintDoubleData m_typeConstraintData;
|
||||
btVector3DoubleData m_pivotInA;
|
||||
btVector3DoubleData m_pivotInB;
|
||||
};
|
||||
|
||||
#ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
///this structure is not used, except for loading pre-2.82 .bullet files
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
struct btPoint2PointConstraintDoubleData
|
||||
{
|
||||
@@ -140,18 +151,19 @@ struct btPoint2PointConstraintDoubleData
|
||||
btVector3DoubleData m_pivotInA;
|
||||
btVector3DoubleData m_pivotInB;
|
||||
};
|
||||
#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btPoint2PointConstraint::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btPoint2PointConstraintData);
|
||||
return sizeof(btPoint2PointConstraintData2);
|
||||
|
||||
}
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
SIMD_FORCE_INLINE const char* btPoint2PointConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
btPoint2PointConstraintData* p2pData = (btPoint2PointConstraintData*)dataBuffer;
|
||||
btPoint2PointConstraintData2* p2pData = (btPoint2PointConstraintData2*)dataBuffer;
|
||||
|
||||
btTypedConstraint::serialize(&p2pData->m_typeConstraintData,serializer);
|
||||
m_pivotInA.serialize(p2pData->m_pivotInA);
|
||||
|
@@ -152,7 +152,7 @@ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(
|
||||
#endif
|
||||
}
|
||||
|
||||
// Project Gauss Seidel or the equivalent Sequential Impulse
|
||||
// Projected Gauss Seidel or the equivalent Sequential Impulse
|
||||
void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
|
||||
{
|
||||
btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
|
||||
@@ -280,7 +280,7 @@ int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
|
||||
|
||||
|
||||
|
||||
void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject)
|
||||
void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep)
|
||||
{
|
||||
|
||||
btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0;
|
||||
@@ -299,6 +299,9 @@ void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBod
|
||||
solverBody->m_linearFactor = rb->getLinearFactor();
|
||||
solverBody->m_linearVelocity = rb->getLinearVelocity();
|
||||
solverBody->m_angularVelocity = rb->getAngularVelocity();
|
||||
solverBody->m_externalForceImpulse = rb->getTotalForce()*rb->getInvMass()*timeStep;
|
||||
solverBody->m_externalTorqueImpulse = rb->getTotalTorque()*rb->getInvInertiaTensorWorld()*timeStep ;
|
||||
|
||||
} else
|
||||
{
|
||||
solverBody->m_worldTransform.setIdentity();
|
||||
@@ -308,6 +311,8 @@ void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBod
|
||||
solverBody->m_linearFactor.setValue(1,1,1);
|
||||
solverBody->m_linearVelocity.setValue(0,0,0);
|
||||
solverBody->m_angularVelocity.setValue(0,0,0);
|
||||
solverBody->m_externalForceImpulse.setValue(0,0,0);
|
||||
solverBody->m_externalTorqueImpulse.setValue(0,0,0);
|
||||
}
|
||||
|
||||
|
||||
@@ -326,8 +331,7 @@ btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel,
|
||||
|
||||
|
||||
|
||||
static void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode);
|
||||
static void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode)
|
||||
void btSequentialImpulseConstraintSolver::applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode)
|
||||
{
|
||||
|
||||
|
||||
@@ -351,8 +355,6 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr
|
||||
{
|
||||
|
||||
|
||||
solverConstraint.m_contactNormal1 = normalAxis;
|
||||
solverConstraint.m_contactNormal2 = -normalAxis;
|
||||
btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA];
|
||||
btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB];
|
||||
|
||||
@@ -368,15 +370,30 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr
|
||||
solverConstraint.m_appliedImpulse = 0.f;
|
||||
solverConstraint.m_appliedPushImpulse = 0.f;
|
||||
|
||||
if (body0)
|
||||
{
|
||||
solverConstraint.m_contactNormal1 = normalAxis;
|
||||
btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal1);
|
||||
solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
|
||||
solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0);
|
||||
}
|
||||
solverConstraint.m_angularComponentA = body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor();
|
||||
}else
|
||||
{
|
||||
solverConstraint.m_contactNormal1.setZero();
|
||||
solverConstraint.m_relpos1CrossNormal.setZero();
|
||||
solverConstraint.m_angularComponentA .setZero();
|
||||
}
|
||||
|
||||
if (body1)
|
||||
{
|
||||
solverConstraint.m_contactNormal2 = -normalAxis;
|
||||
btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal2);
|
||||
solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
|
||||
solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0);
|
||||
solverConstraint.m_angularComponentB = body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor();
|
||||
} else
|
||||
{
|
||||
solverConstraint.m_contactNormal2.setZero();
|
||||
solverConstraint.m_relpos2CrossNormal.setZero();
|
||||
solverConstraint.m_angularComponentB.setZero();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -401,9 +418,9 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr
|
||||
|
||||
|
||||
btScalar rel_vel;
|
||||
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity:btVector3(0,0,0))
|
||||
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity+solverBodyA.m_externalForceImpulse:btVector3(0,0,0))
|
||||
+ solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0));
|
||||
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(body1?solverBodyB.m_linearVelocity:btVector3(0,0,0))
|
||||
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(body1?solverBodyB.m_linearVelocity+solverBodyB.m_externalForceImpulse:btVector3(0,0,0))
|
||||
+ solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:btVector3(0,0,0));
|
||||
|
||||
rel_vel = vel1Dotn+vel2Dotn;
|
||||
@@ -414,8 +431,8 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr
|
||||
btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);
|
||||
solverConstraint.m_rhs = velocityImpulse;
|
||||
solverConstraint.m_cfm = cfmSlip;
|
||||
solverConstraint.m_lowerLimit = 0;
|
||||
solverConstraint.m_upperLimit = 1e10f;
|
||||
solverConstraint.m_lowerLimit = -solverConstraint.m_friction;
|
||||
solverConstraint.m_upperLimit = solverConstraint.m_friction;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -481,9 +498,9 @@ void btSequentialImpulseConstraintSolver::setupRollingFrictionConstraint( btSolv
|
||||
|
||||
|
||||
btScalar rel_vel;
|
||||
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity:btVector3(0,0,0))
|
||||
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity+solverBodyA.m_externalForceImpulse:btVector3(0,0,0))
|
||||
+ solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0));
|
||||
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(body1?solverBodyB.m_linearVelocity:btVector3(0,0,0))
|
||||
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(body1?solverBodyB.m_linearVelocity+solverBodyB.m_externalForceImpulse:btVector3(0,0,0))
|
||||
+ solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:btVector3(0,0,0));
|
||||
|
||||
rel_vel = vel1Dotn+vel2Dotn;
|
||||
@@ -494,8 +511,8 @@ void btSequentialImpulseConstraintSolver::setupRollingFrictionConstraint( btSolv
|
||||
btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);
|
||||
solverConstraint.m_rhs = velocityImpulse;
|
||||
solverConstraint.m_cfm = cfmSlip;
|
||||
solverConstraint.m_lowerLimit = 0;
|
||||
solverConstraint.m_upperLimit = 1e10f;
|
||||
solverConstraint.m_lowerLimit = -solverConstraint.m_friction;
|
||||
solverConstraint.m_upperLimit = solverConstraint.m_friction;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -517,7 +534,7 @@ btSolverConstraint& btSequentialImpulseConstraintSolver::addRollingFrictionConst
|
||||
}
|
||||
|
||||
|
||||
int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body)
|
||||
int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body,btScalar timeStep)
|
||||
{
|
||||
|
||||
int solverBodyIdA = -1;
|
||||
@@ -535,11 +552,19 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject&
|
||||
{
|
||||
solverBodyIdA = m_tmpSolverBodyPool.size();
|
||||
btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
|
||||
initSolverBody(&solverBody,&body);
|
||||
initSolverBody(&solverBody,&body,timeStep);
|
||||
body.setCompanionId(solverBodyIdA);
|
||||
} else
|
||||
{
|
||||
return 0;//assume first one is a fixed solver body
|
||||
|
||||
if (m_fixedBodyId<0)
|
||||
{
|
||||
m_fixedBodyId = m_tmpSolverBodyPool.size();
|
||||
btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
|
||||
initSolverBody(&fixedBody,0,timeStep);
|
||||
}
|
||||
return m_fixedBodyId;
|
||||
// return 0;//assume first one is a fixed solver body
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,8 +577,8 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject&
|
||||
void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstraint& solverConstraint,
|
||||
int solverBodyIdA, int solverBodyIdB,
|
||||
btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
|
||||
btVector3& vel, btScalar& rel_vel, btScalar& relaxation,
|
||||
btVector3& rel_pos1, btVector3& rel_pos2)
|
||||
btScalar& relaxation,
|
||||
const btVector3& rel_pos1, const btVector3& rel_pos2)
|
||||
{
|
||||
|
||||
const btVector3& pos1 = cp.getPositionWorldOnA();
|
||||
@@ -567,8 +592,8 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
|
||||
|
||||
// btVector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin();
|
||||
// btVector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
|
||||
rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin();
|
||||
rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin();
|
||||
//rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin();
|
||||
//rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin();
|
||||
|
||||
relaxation = 1.f;
|
||||
|
||||
@@ -601,10 +626,24 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
|
||||
solverConstraint.m_jacDiagABInv = denom;
|
||||
}
|
||||
|
||||
solverConstraint.m_contactNormal1 = cp.m_normalWorldOnB;
|
||||
solverConstraint.m_contactNormal2 = -cp.m_normalWorldOnB;
|
||||
solverConstraint.m_relpos1CrossNormal = torqueAxis0;
|
||||
solverConstraint.m_relpos2CrossNormal = -torqueAxis1;
|
||||
if (rb0)
|
||||
{
|
||||
solverConstraint.m_contactNormal1 = cp.m_normalWorldOnB;
|
||||
solverConstraint.m_relpos1CrossNormal = torqueAxis0;
|
||||
} else
|
||||
{
|
||||
solverConstraint.m_contactNormal1.setZero();
|
||||
solverConstraint.m_relpos1CrossNormal.setZero();
|
||||
}
|
||||
if (rb1)
|
||||
{
|
||||
solverConstraint.m_contactNormal2 = -cp.m_normalWorldOnB;
|
||||
solverConstraint.m_relpos2CrossNormal = -torqueAxis1;
|
||||
}else
|
||||
{
|
||||
solverConstraint.m_contactNormal2.setZero();
|
||||
solverConstraint.m_relpos2CrossNormal.setZero();
|
||||
}
|
||||
|
||||
btScalar restitution = 0.f;
|
||||
btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop;
|
||||
@@ -616,8 +655,8 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
|
||||
vel2 = rb1? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
|
||||
|
||||
// btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
|
||||
vel = vel1 - vel2;
|
||||
rel_vel = cp.m_normalWorldOnB.dot(vel);
|
||||
btVector3 vel = vel1 - vel2;
|
||||
btScalar rel_vel = cp.m_normalWorldOnB.dot(vel);
|
||||
|
||||
|
||||
|
||||
@@ -648,10 +687,17 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
|
||||
solverConstraint.m_appliedPushImpulse = 0.f;
|
||||
|
||||
{
|
||||
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rb0?bodyA->m_linearVelocity:btVector3(0,0,0))
|
||||
+ solverConstraint.m_relpos1CrossNormal.dot(rb0?bodyA->m_angularVelocity:btVector3(0,0,0));
|
||||
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rb1?bodyB->m_linearVelocity:btVector3(0,0,0))
|
||||
+ solverConstraint.m_relpos2CrossNormal.dot(rb1?bodyB->m_angularVelocity:btVector3(0,0,0));
|
||||
|
||||
btVector3 externalForceImpulseA = bodyA->m_originalBody ? bodyA->m_externalForceImpulse: btVector3(0,0,0);
|
||||
btVector3 externalTorqueImpulseA = bodyA->m_originalBody ? bodyA->m_externalTorqueImpulse: btVector3(0,0,0);
|
||||
btVector3 externalForceImpulseB = bodyB->m_originalBody ? bodyB->m_externalForceImpulse: btVector3(0,0,0);
|
||||
btVector3 externalTorqueImpulseB = bodyB->m_originalBody ?bodyB->m_externalTorqueImpulse : btVector3(0,0,0);
|
||||
|
||||
|
||||
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(bodyA->m_linearVelocity+externalForceImpulseA)
|
||||
+ solverConstraint.m_relpos1CrossNormal.dot(bodyA->m_angularVelocity+externalTorqueImpulseA);
|
||||
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(bodyB->m_linearVelocity+externalForceImpulseB)
|
||||
+ solverConstraint.m_relpos2CrossNormal.dot(bodyB->m_angularVelocity+externalTorqueImpulseB);
|
||||
btScalar rel_vel = vel1Dotn+vel2Dotn;
|
||||
|
||||
btScalar positionalError = 0.f;
|
||||
@@ -680,7 +726,7 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
|
||||
if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
|
||||
{
|
||||
//combine position and velocity into rhs
|
||||
solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
|
||||
solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;//-solverConstraint.m_contactNormal1.dot(bodyA->m_externalForce*bodyA->m_invMass-bodyB->m_externalForce/bodyB->m_invMass)*solverConstraint.m_jacDiagABInv;
|
||||
solverConstraint.m_rhsPenetration = 0.f;
|
||||
|
||||
} else
|
||||
@@ -754,8 +800,8 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
||||
colObj0 = (btCollisionObject*)manifold->getBody0();
|
||||
colObj1 = (btCollisionObject*)manifold->getBody1();
|
||||
|
||||
int solverBodyIdA = getOrInitSolverBody(*colObj0);
|
||||
int solverBodyIdB = getOrInitSolverBody(*colObj1);
|
||||
int solverBodyIdA = getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep);
|
||||
int solverBodyIdB = getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep);
|
||||
|
||||
// btRigidBody* bodyA = btRigidBody::upcast(colObj0);
|
||||
// btRigidBody* bodyB = btRigidBody::upcast(colObj1);
|
||||
@@ -780,19 +826,35 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
||||
btVector3 rel_pos1;
|
||||
btVector3 rel_pos2;
|
||||
btScalar relaxation;
|
||||
btScalar rel_vel;
|
||||
btVector3 vel;
|
||||
|
||||
|
||||
int frictionIndex = m_tmpSolverContactConstraintPool.size();
|
||||
btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expandNonInitializing();
|
||||
// btRigidBody* rb0 = btRigidBody::upcast(colObj0);
|
||||
// btRigidBody* rb1 = btRigidBody::upcast(colObj1);
|
||||
btRigidBody* rb0 = btRigidBody::upcast(colObj0);
|
||||
btRigidBody* rb1 = btRigidBody::upcast(colObj1);
|
||||
solverConstraint.m_solverBodyIdA = solverBodyIdA;
|
||||
solverConstraint.m_solverBodyIdB = solverBodyIdB;
|
||||
|
||||
solverConstraint.m_originalContactPoint = &cp;
|
||||
|
||||
setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, vel, rel_vel, relaxation, rel_pos1, rel_pos2);
|
||||
const btVector3& pos1 = cp.getPositionWorldOnA();
|
||||
const btVector3& pos2 = cp.getPositionWorldOnB();
|
||||
|
||||
rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin();
|
||||
rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
|
||||
|
||||
btVector3 vel1;// = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
|
||||
btVector3 vel2;// = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
|
||||
|
||||
solverBodyA->getVelocityInLocalPointNoDelta(rel_pos1,vel1);
|
||||
solverBodyB->getVelocityInLocalPointNoDelta(rel_pos2,vel2 );
|
||||
|
||||
btVector3 vel = vel1 - vel2;
|
||||
btScalar rel_vel = cp.m_normalWorldOnB.dot(vel);
|
||||
|
||||
setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2);
|
||||
|
||||
|
||||
|
||||
// const btVector3& pos1 = cp.getPositionWorldOnA();
|
||||
// const btVector3& pos2 = cp.getPositionWorldOnB();
|
||||
@@ -801,9 +863,11 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
||||
|
||||
solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size();
|
||||
|
||||
btVector3 angVelA,angVelB;
|
||||
solverBodyA->getAngularVelocity(angVelA);
|
||||
solverBodyB->getAngularVelocity(angVelB);
|
||||
btVector3 angVelA(0,0,0),angVelB(0,0,0);
|
||||
if (rb0)
|
||||
angVelA = rb0->getAngularVelocity();
|
||||
if (rb1)
|
||||
angVelB = rb1->getAngularVelocity();
|
||||
btVector3 relAngVel = angVelB-angVelA;
|
||||
|
||||
if ((cp.m_combinedRollingFriction>0.f) && (rollingFriction>0))
|
||||
@@ -857,6 +921,10 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
||||
if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON)
|
||||
{
|
||||
cp.m_lateralFrictionDir1 *= 1.f/btSqrt(lat_rel_vel);
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
|
||||
{
|
||||
cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
|
||||
@@ -864,17 +932,16 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
}
|
||||
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
} else
|
||||
{
|
||||
btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
|
||||
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
|
||||
{
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
@@ -882,9 +949,6 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
}
|
||||
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION))
|
||||
{
|
||||
@@ -899,8 +963,8 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
||||
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
|
||||
addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2);
|
||||
|
||||
setFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
|
||||
}
|
||||
setFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
|
||||
|
||||
|
||||
|
||||
@@ -909,10 +973,24 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
|
||||
}
|
||||
}
|
||||
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
|
||||
void btSequentialImpulseConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr,int numManifolds, const btContactSolverInfo& infoGlobal)
|
||||
{
|
||||
int i;
|
||||
btPersistentManifold* manifold = 0;
|
||||
// btCollisionObject* colObj0=0,*colObj1=0;
|
||||
|
||||
|
||||
for (i=0;i<numManifolds;i++)
|
||||
{
|
||||
manifold = manifoldPtr[i];
|
||||
convertContact(manifold,infoGlobal);
|
||||
}
|
||||
}
|
||||
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
|
||||
{
|
||||
m_fixedBodyId = -1;
|
||||
BT_PROFILE("solveGroupCacheFriendlySetup");
|
||||
(void)stackAlloc;
|
||||
(void)debugDrawer;
|
||||
|
||||
m_maxOverrideNumSolverIterations = 0;
|
||||
@@ -996,14 +1074,15 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
m_tmpSolverBodyPool.reserve(numBodies+1);
|
||||
m_tmpSolverBodyPool.resize(0);
|
||||
|
||||
btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
|
||||
initSolverBody(&fixedBody,0);
|
||||
//btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
|
||||
//initSolverBody(&fixedBody,0);
|
||||
|
||||
//convert all bodies
|
||||
|
||||
for (int i=0;i<numBodies;i++)
|
||||
{
|
||||
int bodyId = getOrInitSolverBody(*bodies[i]);
|
||||
int bodyId = getOrInitSolverBody(*bodies[i],infoGlobal.m_timeStep);
|
||||
|
||||
btRigidBody* body = btRigidBody::upcast(bodies[i]);
|
||||
if (body && body->getInvMass())
|
||||
{
|
||||
@@ -1012,9 +1091,8 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
if (body->getFlags()&BT_ENABLE_GYROPSCOPIC_FORCE)
|
||||
{
|
||||
gyroForce = body->computeGyroscopicForce(infoGlobal.m_maxGyroscopicForce);
|
||||
solverBody.m_externalTorqueImpulse -= gyroForce*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep;
|
||||
}
|
||||
solverBody.m_linearVelocity += body->getTotalForce()*body->getInvMass()*infoGlobal.m_timeStep;
|
||||
solverBody.m_angularVelocity += (body->getTotalTorque()-gyroForce)*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,8 +1162,8 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
btRigidBody& rbA = constraint->getRigidBodyA();
|
||||
btRigidBody& rbB = constraint->getRigidBodyB();
|
||||
|
||||
int solverBodyIdA = getOrInitSolverBody(rbA);
|
||||
int solverBodyIdB = getOrInitSolverBody(rbB);
|
||||
int solverBodyIdA = getOrInitSolverBody(rbA,infoGlobal.m_timeStep);
|
||||
int solverBodyIdB = getOrInitSolverBody(rbB,infoGlobal.m_timeStep);
|
||||
|
||||
btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA];
|
||||
btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB];
|
||||
@@ -1182,15 +1260,22 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
}
|
||||
|
||||
|
||||
///fix rhs
|
||||
///todo: add force/torque accelerators
|
||||
|
||||
{
|
||||
btScalar rel_vel;
|
||||
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity());
|
||||
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity());
|
||||
btVector3 externalForceImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalForceImpulse : btVector3(0,0,0);
|
||||
btVector3 externalTorqueImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalTorqueImpulse : btVector3(0,0,0);
|
||||
|
||||
btVector3 externalForceImpulseB = bodyBPtr->m_originalBody ? bodyBPtr->m_externalForceImpulse : btVector3(0,0,0);
|
||||
btVector3 externalTorqueImpulseB = bodyBPtr->m_originalBody ?bodyBPtr->m_externalTorqueImpulse : btVector3(0,0,0);
|
||||
|
||||
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rbA.getLinearVelocity()+externalForceImpulseA)
|
||||
+ solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()+externalTorqueImpulseA);
|
||||
|
||||
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rbB.getLinearVelocity()+externalForceImpulseB)
|
||||
+ solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()+externalTorqueImpulseB);
|
||||
|
||||
rel_vel = vel1Dotn+vel2Dotn;
|
||||
|
||||
btScalar restitution = 0.f;
|
||||
btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2
|
||||
btScalar velocityError = restitution - rel_vel * info2.m_damping;
|
||||
@@ -1199,6 +1284,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
|
||||
solverConstraint.m_appliedImpulse = 0.f;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1206,18 +1292,8 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
btPersistentManifold* manifold = 0;
|
||||
// btCollisionObject* colObj0=0,*colObj1=0;
|
||||
convertContacts(manifoldPtr,numManifolds,infoGlobal);
|
||||
|
||||
|
||||
for (i=0;i<numManifolds;i++)
|
||||
{
|
||||
manifold = manifoldPtr[i];
|
||||
convertContact(manifold,infoGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// btContactSolverInfo info = infoGlobal;
|
||||
@@ -1256,7 +1332,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
|
||||
}
|
||||
|
||||
|
||||
btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
|
||||
btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/)
|
||||
{
|
||||
|
||||
int numNonContactPool = m_tmpSolverNonContactConstraintPool.size();
|
||||
@@ -1309,14 +1385,14 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
|
||||
{
|
||||
for (int j=0;j<numConstraints;j++)
|
||||
{
|
||||
if (constraints[j]->isEnabled())
|
||||
{
|
||||
int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA());
|
||||
int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB());
|
||||
btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
|
||||
btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
|
||||
constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
|
||||
}
|
||||
if (constraints[j]->isEnabled())
|
||||
{
|
||||
int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(),infoGlobal.m_timeStep);
|
||||
int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
|
||||
btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
|
||||
btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
|
||||
constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
|
||||
}
|
||||
}
|
||||
|
||||
///solve all contact constraints using SIMD, if available
|
||||
@@ -1376,7 +1452,8 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
|
||||
for (j=0;j<numPoolConstraints;j++)
|
||||
{
|
||||
const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
|
||||
resolveSingleConstraintRowLowerLimitSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
|
||||
//resolveSingleConstraintRowLowerLimitSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
|
||||
resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
|
||||
|
||||
}
|
||||
|
||||
@@ -1395,7 +1472,8 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
|
||||
solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
|
||||
solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
|
||||
|
||||
resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
|
||||
//resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
|
||||
resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1437,14 +1515,14 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
|
||||
{
|
||||
for (int j=0;j<numConstraints;j++)
|
||||
{
|
||||
if (constraints[j]->isEnabled())
|
||||
{
|
||||
int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA());
|
||||
int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB());
|
||||
btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
|
||||
btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
|
||||
constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
|
||||
}
|
||||
if (constraints[j]->isEnabled())
|
||||
{
|
||||
int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(),infoGlobal.m_timeStep);
|
||||
int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
|
||||
btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
|
||||
btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
|
||||
constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
|
||||
}
|
||||
}
|
||||
///solve all contact constraints
|
||||
int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
|
||||
@@ -1492,7 +1570,7 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
|
||||
}
|
||||
|
||||
|
||||
void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
|
||||
void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
|
||||
{
|
||||
int iteration;
|
||||
if (infoGlobal.m_splitImpulse)
|
||||
@@ -1532,20 +1610,20 @@ void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIte
|
||||
}
|
||||
}
|
||||
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
|
||||
{
|
||||
BT_PROFILE("solveGroupCacheFriendlyIterations");
|
||||
|
||||
{
|
||||
///this is a special step to resolve penetrations (just for contacts)
|
||||
solveGroupCacheFriendlySplitImpulseIterations(bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
|
||||
solveGroupCacheFriendlySplitImpulseIterations(bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
|
||||
|
||||
int maxIterations = m_maxOverrideNumSolverIterations > infoGlobal.m_numIterations? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations;
|
||||
|
||||
for ( int iteration = 0 ; iteration< maxIterations ; iteration++)
|
||||
//for ( int iteration = maxIterations-1 ; iteration >= 0;iteration--)
|
||||
{
|
||||
solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
|
||||
solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1610,9 +1688,15 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCo
|
||||
m_tmpSolverBodyPool[i].writebackVelocityAndTransform(infoGlobal.m_timeStep, infoGlobal.m_splitImpulseTurnErp);
|
||||
else
|
||||
m_tmpSolverBodyPool[i].writebackVelocity();
|
||||
|
||||
m_tmpSolverBodyPool[i].m_originalBody->setLinearVelocity(
|
||||
m_tmpSolverBodyPool[i].m_linearVelocity+
|
||||
m_tmpSolverBodyPool[i].m_externalForceImpulse);
|
||||
|
||||
m_tmpSolverBodyPool[i].m_originalBody->setAngularVelocity(
|
||||
m_tmpSolverBodyPool[i].m_angularVelocity+
|
||||
m_tmpSolverBodyPool[i].m_externalTorqueImpulse);
|
||||
|
||||
m_tmpSolverBodyPool[i].m_originalBody->setLinearVelocity(m_tmpSolverBodyPool[i].m_linearVelocity);
|
||||
m_tmpSolverBodyPool[i].m_originalBody->setAngularVelocity(m_tmpSolverBodyPool[i].m_angularVelocity);
|
||||
if (infoGlobal.m_splitImpulse)
|
||||
m_tmpSolverBodyPool[i].m_originalBody->setWorldTransform(m_tmpSolverBodyPool[i].m_worldTransform);
|
||||
|
||||
@@ -1632,15 +1716,15 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCo
|
||||
|
||||
|
||||
/// btSequentialImpulseConstraintSolver Sequentially applies impulses
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/)
|
||||
btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btDispatcher* /*dispatcher*/)
|
||||
{
|
||||
|
||||
BT_PROFILE("solveGroup");
|
||||
//you need to provide at least some bodies
|
||||
|
||||
solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
|
||||
solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer);
|
||||
|
||||
solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
|
||||
solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer);
|
||||
|
||||
solveGroupCacheFriendlyFinish(bodies, numBodies, infoGlobal);
|
||||
|
||||
|
@@ -18,7 +18,6 @@ subject to the following restrictions:
|
||||
|
||||
class btIDebugDraw;
|
||||
class btPersistentManifold;
|
||||
class btStackAlloc;
|
||||
class btDispatcher;
|
||||
class btCollisionObject;
|
||||
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
|
||||
@@ -43,7 +42,7 @@ protected:
|
||||
btAlignedObjectArray<int> m_orderFrictionConstraintPool;
|
||||
btAlignedObjectArray<btTypedConstraint::btConstraintInfo1> m_tmpConstraintSizesPool;
|
||||
int m_maxOverrideNumSolverIterations;
|
||||
|
||||
int m_fixedBodyId;
|
||||
void setupFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,
|
||||
btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
|
||||
btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation,
|
||||
@@ -57,10 +56,11 @@ protected:
|
||||
btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0., btScalar cfmSlip=0.);
|
||||
btSolverConstraint& addRollingFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0, btScalar cfmSlip=0.f);
|
||||
|
||||
|
||||
|
||||
void setupContactConstraint(btSolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp,
|
||||
const btContactSolverInfo& infoGlobal, btVector3& vel, btScalar& rel_vel, btScalar& relaxation,
|
||||
btVector3& rel_pos1, btVector3& rel_pos2);
|
||||
const btContactSolverInfo& infoGlobal,btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2);
|
||||
|
||||
static void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode);
|
||||
|
||||
void setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, int solverBodyIdA,int solverBodyIdB,
|
||||
btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
|
||||
@@ -71,6 +71,8 @@ protected:
|
||||
|
||||
btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);
|
||||
|
||||
virtual void convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal);
|
||||
|
||||
void convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal);
|
||||
|
||||
|
||||
@@ -83,8 +85,8 @@ protected:
|
||||
const btSolverConstraint& contactConstraint);
|
||||
|
||||
//internal method
|
||||
int getOrInitSolverBody(btCollisionObject& body);
|
||||
void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);
|
||||
int getOrInitSolverBody(btCollisionObject& body,btScalar timeStep);
|
||||
void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep);
|
||||
|
||||
void resolveSingleConstraintRowGeneric(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
|
||||
|
||||
@@ -97,12 +99,12 @@ protected:
|
||||
protected:
|
||||
|
||||
|
||||
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
|
||||
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
|
||||
virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal);
|
||||
btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
|
||||
virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
|
||||
|
||||
virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
|
||||
virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
|
||||
virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
|
||||
virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
|
||||
|
||||
|
||||
public:
|
||||
@@ -112,7 +114,7 @@ public:
|
||||
btSequentialImpulseConstraintSolver();
|
||||
virtual ~btSequentialImpulseConstraintSolver();
|
||||
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher);
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher);
|
||||
|
||||
|
||||
|
||||
@@ -132,6 +134,11 @@ public:
|
||||
return m_btSeed2;
|
||||
}
|
||||
|
||||
|
||||
virtual btConstraintSolverType getSolverType() const
|
||||
{
|
||||
return BT_SEQUENTIAL_IMPULSE_SOLVER;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@@ -25,7 +25,13 @@ TODO:
|
||||
#ifndef BT_SLIDER_CONSTRAINT_H
|
||||
#define BT_SLIDER_CONSTRAINT_H
|
||||
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btSliderConstraintData2 btSliderConstraintDoubleData
|
||||
#define btSliderConstraintDataName "btSliderConstraintDoubleData"
|
||||
#else
|
||||
#define btSliderConstraintData2 btSliderConstraintData
|
||||
#define btSliderConstraintDataName "btSliderConstraintData"
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "btJacobianEntry.h"
|
||||
@@ -283,7 +289,10 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
|
||||
|
||||
struct btSliderConstraintData
|
||||
{
|
||||
btTypedConstraintData m_typeConstraintData;
|
||||
@@ -302,31 +311,48 @@ struct btSliderConstraintData
|
||||
};
|
||||
|
||||
|
||||
struct btSliderConstraintDoubleData
|
||||
{
|
||||
btTypedConstraintDoubleData m_typeConstraintData;
|
||||
btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
|
||||
btTransformDoubleData m_rbBFrame;
|
||||
|
||||
double m_linearUpperLimit;
|
||||
double m_linearLowerLimit;
|
||||
|
||||
double m_angularUpperLimit;
|
||||
double m_angularLowerLimit;
|
||||
|
||||
int m_useLinearReferenceFrameA;
|
||||
int m_useOffsetForConstraintFrame;
|
||||
|
||||
};
|
||||
|
||||
SIMD_FORCE_INLINE int btSliderConstraint::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btSliderConstraintData);
|
||||
return sizeof(btSliderConstraintData2);
|
||||
}
|
||||
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
SIMD_FORCE_INLINE const char* btSliderConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
|
||||
btSliderConstraintData* sliderData = (btSliderConstraintData*) dataBuffer;
|
||||
btSliderConstraintData2* sliderData = (btSliderConstraintData2*) dataBuffer;
|
||||
btTypedConstraint::serialize(&sliderData->m_typeConstraintData,serializer);
|
||||
|
||||
m_frameInA.serializeFloat(sliderData->m_rbAFrame);
|
||||
m_frameInB.serializeFloat(sliderData->m_rbBFrame);
|
||||
m_frameInA.serialize(sliderData->m_rbAFrame);
|
||||
m_frameInB.serialize(sliderData->m_rbBFrame);
|
||||
|
||||
sliderData->m_linearUpperLimit = float(m_upperLinLimit);
|
||||
sliderData->m_linearLowerLimit = float(m_lowerLinLimit);
|
||||
sliderData->m_linearUpperLimit = m_upperLinLimit;
|
||||
sliderData->m_linearLowerLimit = m_lowerLinLimit;
|
||||
|
||||
sliderData->m_angularUpperLimit = float(m_upperAngLimit);
|
||||
sliderData->m_angularLowerLimit = float(m_lowerAngLimit);
|
||||
sliderData->m_angularUpperLimit = m_upperAngLimit;
|
||||
sliderData->m_angularLowerLimit = m_lowerAngLimit;
|
||||
|
||||
sliderData->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA;
|
||||
sliderData->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame;
|
||||
|
||||
return "btSliderConstraintData";
|
||||
return btSliderConstraintDataName;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -118,6 +118,8 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody
|
||||
btVector3 m_turnVelocity;
|
||||
btVector3 m_linearVelocity;
|
||||
btVector3 m_angularVelocity;
|
||||
btVector3 m_externalForceImpulse;
|
||||
btVector3 m_externalTorqueImpulse;
|
||||
|
||||
btRigidBody* m_originalBody;
|
||||
void setWorldTransform(const btTransform& worldTransform)
|
||||
@@ -130,6 +132,17 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody
|
||||
return m_worldTransform;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void getVelocityInLocalPointNoDelta(const btVector3& rel_pos, btVector3& velocity ) const
|
||||
{
|
||||
if (m_originalBody)
|
||||
velocity = m_linearVelocity + m_externalForceImpulse + (m_angularVelocity+m_externalTorqueImpulse).cross(rel_pos);
|
||||
else
|
||||
velocity.setValue(0,0,0);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE void getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
|
||||
{
|
||||
if (m_originalBody)
|
||||
|
@@ -55,6 +55,7 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint
|
||||
{
|
||||
void* m_originalContactPoint;
|
||||
btScalar m_unusedPadding4;
|
||||
int m_numRowsForNonContactConstraint;
|
||||
};
|
||||
|
||||
int m_overrideNumSolverIterations;
|
||||
|
@@ -109,7 +109,7 @@ btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScal
|
||||
///fills the dataBuffer and returns the struct name (and 0 on failure)
|
||||
const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
|
||||
{
|
||||
btTypedConstraintData* tcd = (btTypedConstraintData*) dataBuffer;
|
||||
btTypedConstraintData2* tcd = (btTypedConstraintData2*) dataBuffer;
|
||||
|
||||
tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA);
|
||||
tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB);
|
||||
@@ -123,14 +123,14 @@ const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* seriali
|
||||
tcd->m_objectType = m_objectType;
|
||||
tcd->m_needsFeedback = m_needsFeedback;
|
||||
tcd->m_overrideNumSolverIterations = m_overrideNumSolverIterations;
|
||||
tcd->m_breakingImpulseThreshold = float(m_breakingImpulseThreshold);
|
||||
tcd->m_breakingImpulseThreshold = m_breakingImpulseThreshold;
|
||||
tcd->m_isEnabled = m_isEnabled? 1: 0;
|
||||
|
||||
tcd->m_userConstraintId =m_userConstraintId;
|
||||
tcd->m_userConstraintType =m_userConstraintType;
|
||||
|
||||
tcd->m_appliedImpulse = float(m_appliedImpulse);
|
||||
tcd->m_dbgDrawSize = float(m_dbgDrawSize );
|
||||
tcd->m_appliedImpulse = m_appliedImpulse;
|
||||
tcd->m_dbgDrawSize = m_dbgDrawSize;
|
||||
|
||||
tcd->m_disableCollisionsBetweenLinkedBodies = false;
|
||||
|
||||
@@ -142,7 +142,7 @@ const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* seriali
|
||||
if (m_rbB.getConstraintRef(i) == this)
|
||||
tcd->m_disableCollisionsBetweenLinkedBodies = true;
|
||||
|
||||
return "btTypedConstraintData";
|
||||
return btTypedConstraintDataName;
|
||||
}
|
||||
|
||||
btRigidBody& btTypedConstraint::getFixedBody()
|
||||
|
@@ -21,6 +21,15 @@ subject to the following restrictions:
|
||||
#include "btSolverConstraint.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
|
||||
#ifdef BT_USE_DOUBLE_PRECISION
|
||||
#define btTypedConstraintData2 btTypedConstraintDoubleData
|
||||
#define btTypedConstraintDataName "btTypedConstraintDoubleData"
|
||||
#else
|
||||
#define btTypedConstraintData2 btTypedConstraintFloatData
|
||||
#define btTypedConstraintDataName "btTypedConstraintFloatData"
|
||||
#endif //BT_USE_DOUBLE_PRECISION
|
||||
|
||||
|
||||
class btSerializer;
|
||||
|
||||
//Don't change any of the existing enum values, so add enum types at the end for serialization compatibility
|
||||
@@ -34,6 +43,7 @@ enum btTypedConstraintType
|
||||
CONTACT_CONSTRAINT_TYPE,
|
||||
D6_SPRING_CONSTRAINT_TYPE,
|
||||
GEAR_CONSTRAINT_TYPE,
|
||||
FIXED_CONSTRAINT_TYPE,
|
||||
MAX_CONSTRAINT_TYPE
|
||||
};
|
||||
|
||||
@@ -356,6 +366,33 @@ SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScal
|
||||
}
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
struct btTypedConstraintFloatData
|
||||
{
|
||||
btRigidBodyFloatData *m_rbA;
|
||||
btRigidBodyFloatData *m_rbB;
|
||||
char *m_name;
|
||||
|
||||
int m_objectType;
|
||||
int m_userConstraintType;
|
||||
int m_userConstraintId;
|
||||
int m_needsFeedback;
|
||||
|
||||
float m_appliedImpulse;
|
||||
float m_dbgDrawSize;
|
||||
|
||||
int m_disableCollisionsBetweenLinkedBodies;
|
||||
int m_overrideNumSolverIterations;
|
||||
|
||||
float m_breakingImpulseThreshold;
|
||||
int m_isEnabled;
|
||||
|
||||
};
|
||||
|
||||
///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
|
||||
|
||||
#define BT_BACKWARDS_COMPATIBLE_SERIALIZATION
|
||||
#ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION
|
||||
///this structure is not used, except for loading pre-2.82 .bullet files
|
||||
struct btTypedConstraintData
|
||||
{
|
||||
btRigidBodyData *m_rbA;
|
||||
@@ -377,10 +414,35 @@ struct btTypedConstraintData
|
||||
int m_isEnabled;
|
||||
|
||||
};
|
||||
#endif //BACKWARDS_COMPATIBLE
|
||||
|
||||
struct btTypedConstraintDoubleData
|
||||
{
|
||||
btRigidBodyDoubleData *m_rbA;
|
||||
btRigidBodyDoubleData *m_rbB;
|
||||
char *m_name;
|
||||
|
||||
int m_objectType;
|
||||
int m_userConstraintType;
|
||||
int m_userConstraintId;
|
||||
int m_needsFeedback;
|
||||
|
||||
double m_appliedImpulse;
|
||||
double m_dbgDrawSize;
|
||||
|
||||
int m_disableCollisionsBetweenLinkedBodies;
|
||||
int m_overrideNumSolverIterations;
|
||||
|
||||
double m_breakingImpulseThreshold;
|
||||
int m_isEnabled;
|
||||
char padding[4];
|
||||
|
||||
};
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btTypedConstraint::calculateSerializeBufferSize() const
|
||||
{
|
||||
return sizeof(btTypedConstraintData);
|
||||
return sizeof(btTypedConstraintData2);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -87,7 +87,6 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
|
||||
btTypedConstraint** m_sortedConstraints;
|
||||
int m_numConstraints;
|
||||
btIDebugDraw* m_debugDrawer;
|
||||
btStackAlloc* m_stackAlloc;
|
||||
btDispatcher* m_dispatcher;
|
||||
|
||||
btAlignedObjectArray<btCollisionObject*> m_bodies;
|
||||
@@ -104,7 +103,6 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
|
||||
m_sortedConstraints(NULL),
|
||||
m_numConstraints(0),
|
||||
m_debugDrawer(NULL),
|
||||
m_stackAlloc(stackAlloc),
|
||||
m_dispatcher(dispatcher)
|
||||
{
|
||||
|
||||
@@ -135,7 +133,7 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
|
||||
if (islandId<0)
|
||||
{
|
||||
///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
|
||||
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
|
||||
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
|
||||
} else
|
||||
{
|
||||
//also add all non-contact constraints/joints for this island
|
||||
@@ -163,7 +161,7 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
|
||||
|
||||
if (m_solverInfo->m_minimumSolverBatchSize<=1)
|
||||
{
|
||||
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
|
||||
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
|
||||
} else
|
||||
{
|
||||
|
||||
@@ -190,7 +188,7 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
|
||||
btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0;
|
||||
btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0;
|
||||
|
||||
m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
|
||||
m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_dispatcher);
|
||||
m_bodies.resize(0);
|
||||
m_manifolds.resize(0);
|
||||
m_constraints.resize(0);
|
||||
@@ -210,7 +208,9 @@ m_gravity(0,-10,0),
|
||||
m_localTime(0),
|
||||
m_synchronizeAllMotionStates(false),
|
||||
m_applySpeculativeContactRestitution(false),
|
||||
m_profileTimings(0)
|
||||
m_profileTimings(0),
|
||||
m_fixedTimeStep(0),
|
||||
m_latencyMotionStateInterpolation(true)
|
||||
|
||||
{
|
||||
if (!m_constraintSolver)
|
||||
@@ -232,7 +232,7 @@ m_profileTimings(0)
|
||||
|
||||
{
|
||||
void* mem = btAlignedAlloc(sizeof(InplaceSolverIslandCallback),16);
|
||||
m_solverIslandCallback = new (mem) InplaceSolverIslandCallback (m_constraintSolver, m_stackAlloc, dispatcher);
|
||||
m_solverIslandCallback = new (mem) InplaceSolverIslandCallback (m_constraintSolver, 0, dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,7 +359,9 @@ void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body)
|
||||
{
|
||||
btTransform interpolatedTransform;
|
||||
btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
|
||||
body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
|
||||
body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),
|
||||
(m_latencyMotionStateInterpolation && m_fixedTimeStep) ? m_localTime - m_fixedTimeStep : m_localTime*body->getHitFraction(),
|
||||
interpolatedTransform);
|
||||
body->getMotionState()->setWorldTransform(interpolatedTransform);
|
||||
}
|
||||
}
|
||||
@@ -403,6 +405,7 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
|
||||
if (maxSubSteps)
|
||||
{
|
||||
//fixed timestep with interpolation
|
||||
m_fixedTimeStep = fixedTimeStep;
|
||||
m_localTime += timeStep;
|
||||
if (m_localTime >= fixedTimeStep)
|
||||
{
|
||||
@@ -413,7 +416,8 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
|
||||
{
|
||||
//variable timestep
|
||||
fixedTimeStep = timeStep;
|
||||
m_localTime = timeStep;
|
||||
m_localTime = m_latencyMotionStateInterpolation ? 0 : timeStep;
|
||||
m_fixedTimeStep = 0;
|
||||
if (btFuzzyZero(timeStep))
|
||||
{
|
||||
numSimulationSubSteps = 0;
|
||||
@@ -724,7 +728,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
|
||||
|
||||
m_solverIslandCallback->processConstraints();
|
||||
|
||||
m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
|
||||
m_constraintSolver->allSolved(solverInfo, m_debugDrawer);
|
||||
}
|
||||
|
||||
|
||||
@@ -746,12 +750,7 @@ void btDiscreteDynamicsWorld::calculateSimulationIslands()
|
||||
if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
|
||||
((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
|
||||
{
|
||||
if (colObj0->isActive() || colObj1->isActive())
|
||||
{
|
||||
|
||||
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),
|
||||
(colObj1)->getIslandTag());
|
||||
}
|
||||
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -770,12 +769,7 @@ void btDiscreteDynamicsWorld::calculateSimulationIslands()
|
||||
if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
|
||||
((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
|
||||
{
|
||||
if (colObj0->isActive() || colObj1->isActive())
|
||||
{
|
||||
|
||||
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),
|
||||
(colObj1)->getIslandTag());
|
||||
}
|
||||
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1131,7 +1125,6 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
|
||||
{
|
||||
//don't integrate/update velocities here, it happens in the constraint solver
|
||||
|
||||
//damping
|
||||
body->applyDamping(timeStep);
|
||||
|
||||
body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
|
||||
|
@@ -53,6 +53,7 @@ protected:
|
||||
|
||||
//for variable timesteps
|
||||
btScalar m_localTime;
|
||||
btScalar m_fixedTimeStep;
|
||||
//for variable timesteps
|
||||
|
||||
bool m_ownsIslandManager;
|
||||
@@ -64,6 +65,8 @@ protected:
|
||||
|
||||
int m_profileTimings;
|
||||
|
||||
bool m_latencyMotionStateInterpolation;
|
||||
|
||||
btAlignedObjectArray<btPersistentManifold*> m_predictiveManifolds;
|
||||
|
||||
virtual void predictUnconstraintMotion(btScalar timeStep);
|
||||
@@ -74,7 +77,7 @@ protected:
|
||||
|
||||
virtual void solveConstraints(btContactSolverInfo& solverInfo);
|
||||
|
||||
void updateActivationState(btScalar timeStep);
|
||||
virtual void updateActivationState(btScalar timeStep);
|
||||
|
||||
void updateActions(btScalar timeStep);
|
||||
|
||||
@@ -216,6 +219,16 @@ public:
|
||||
///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo)
|
||||
virtual void serialize(btSerializer* serializer);
|
||||
|
||||
///Interpolate motion state between previous and current transform, instead of current and next transform.
|
||||
///This can relieve discontinuities in the rendering, due to penetrations
|
||||
void setLatencyMotionStateInterpolation(bool latencyInterpolation )
|
||||
{
|
||||
m_latencyMotionStateInterpolation = latencyInterpolation;
|
||||
}
|
||||
bool getLatencyMotionStateInterpolation() const
|
||||
{
|
||||
return m_latencyMotionStateInterpolation;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //BT_DISCRETE_DYNAMICS_WORLD_H
|
||||
|
@@ -33,7 +33,8 @@ enum btDynamicsWorldType
|
||||
BT_SIMPLE_DYNAMICS_WORLD=1,
|
||||
BT_DISCRETE_DYNAMICS_WORLD=2,
|
||||
BT_CONTINUOUS_DYNAMICS_WORLD=3,
|
||||
BT_SOFT_RIGID_DYNAMICS_WORLD=4
|
||||
BT_SOFT_RIGID_DYNAMICS_WORLD=4,
|
||||
BT_GPU_DYNAMICS_WORLD=5
|
||||
};
|
||||
|
||||
///The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc.
|
||||
|
@@ -363,11 +363,13 @@ public:
|
||||
|
||||
inline void setLinearVelocity(const btVector3& lin_vel)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_linearVelocity = lin_vel;
|
||||
}
|
||||
|
||||
inline void setAngularVelocity(const btVector3& ang_vel)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_angularVelocity = ang_vel;
|
||||
}
|
||||
|
||||
@@ -484,11 +486,13 @@ public:
|
||||
|
||||
void setAngularFactor(const btVector3& angFac)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_angularFactor = angFac;
|
||||
}
|
||||
|
||||
void setAngularFactor(btScalar angFac)
|
||||
{
|
||||
m_updateRevision++;
|
||||
m_angularFactor.setValue(angFac,angFac,angFac);
|
||||
}
|
||||
const btVector3& getAngularFactor() const
|
||||
|
@@ -78,8 +78,8 @@ int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, b
|
||||
btContactSolverInfo infoGlobal;
|
||||
infoGlobal.m_timeStep = timeStep;
|
||||
m_constraintSolver->prepareSolve(0,numManifolds);
|
||||
m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc,m_dispatcher1);
|
||||
m_constraintSolver->allSolved(infoGlobal,m_debugDrawer, m_stackAlloc);
|
||||
m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_dispatcher1);
|
||||
m_constraintSolver->allSolved(infoGlobal,m_debugDrawer);
|
||||
}
|
||||
|
||||
///integrate transforms
|
||||
|
1009
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.cpp
vendored
Normal file
1009
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
466
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.h
vendored
Normal file
466
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBody.h
vendored
Normal file
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* PURPOSE:
|
||||
* Class representing an articulated rigid body. Stores the body's
|
||||
* current state, allows forces and torques to be set, handles
|
||||
* timestepping and implements Featherstone's algorithm.
|
||||
*
|
||||
* COPYRIGHT:
|
||||
* Copyright (C) Stephen Thompson, <stephen@solarflare.org.uk>, 2011-2013
|
||||
* Portions written By Erwin Coumans: replacing Eigen math library by Bullet LinearMath and a dedicated 6x6 matrix inverse (solveImatrix)
|
||||
|
||||
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_MULTIBODY_H
|
||||
#define BT_MULTIBODY_H
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
#include "LinearMath/btMatrix3x3.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
|
||||
#include "btMultiBodyLink.h"
|
||||
class btMultiBodyLinkCollider;
|
||||
|
||||
class btMultiBody
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
//
|
||||
// initialization
|
||||
//
|
||||
|
||||
btMultiBody(int n_links, // NOT including the base
|
||||
btScalar mass, // mass of base
|
||||
const btVector3 &inertia, // inertia of base, in base frame; assumed diagonal
|
||||
bool fixed_base_, // whether the base is fixed (true) or can move (false)
|
||||
bool can_sleep_);
|
||||
|
||||
~btMultiBody();
|
||||
|
||||
void setupPrismatic(int i, // 0 to num_links-1
|
||||
btScalar mass,
|
||||
const btVector3 &inertia, // in my frame; assumed diagonal
|
||||
int parent,
|
||||
const btQuaternion &rot_parent_to_this, // rotate points in parent frame to my frame.
|
||||
const btVector3 &joint_axis, // in my frame
|
||||
const btVector3 &r_vector_when_q_zero, // vector from parent COM to my COM, in my frame, when q = 0.
|
||||
bool disableParentCollision=false
|
||||
);
|
||||
|
||||
void setupRevolute(int i, // 0 to num_links-1
|
||||
btScalar mass,
|
||||
const btVector3 &inertia,
|
||||
int parent,
|
||||
const btQuaternion &zero_rot_parent_to_this, // rotate points in parent frame to this frame, when q = 0
|
||||
const btVector3 &joint_axis, // in my frame
|
||||
const btVector3 &parent_axis_position, // vector from parent COM to joint axis, in PARENT frame
|
||||
const btVector3 &my_axis_position, // vector from joint axis to my COM, in MY frame
|
||||
bool disableParentCollision=false);
|
||||
|
||||
const btMultibodyLink& getLink(int index) const
|
||||
{
|
||||
return links[index];
|
||||
}
|
||||
|
||||
btMultibodyLink& getLink(int index)
|
||||
{
|
||||
return links[index];
|
||||
}
|
||||
|
||||
|
||||
void setBaseCollider(btMultiBodyLinkCollider* collider)//collider can be NULL to disable collision for the base
|
||||
{
|
||||
m_baseCollider = collider;
|
||||
}
|
||||
const btMultiBodyLinkCollider* getBaseCollider() const
|
||||
{
|
||||
return m_baseCollider;
|
||||
}
|
||||
btMultiBodyLinkCollider* getBaseCollider()
|
||||
{
|
||||
return m_baseCollider;
|
||||
}
|
||||
|
||||
//
|
||||
// get parent
|
||||
// input: link num from 0 to num_links-1
|
||||
// output: link num from 0 to num_links-1, OR -1 to mean the base.
|
||||
//
|
||||
int getParent(int link_num) const;
|
||||
|
||||
|
||||
//
|
||||
// get number of links, masses, moments of inertia
|
||||
//
|
||||
|
||||
int getNumLinks() const { return links.size(); }
|
||||
btScalar getBaseMass() const { return base_mass; }
|
||||
const btVector3 & getBaseInertia() const { return base_inertia; }
|
||||
btScalar getLinkMass(int i) const;
|
||||
const btVector3 & getLinkInertia(int i) const;
|
||||
|
||||
|
||||
//
|
||||
// change mass (incomplete: can only change base mass and inertia at present)
|
||||
//
|
||||
|
||||
void setBaseMass(btScalar mass) { base_mass = mass; }
|
||||
void setBaseInertia(const btVector3 &inertia) { base_inertia = inertia; }
|
||||
|
||||
|
||||
//
|
||||
// get/set pos/vel/rot/omega for the base link
|
||||
//
|
||||
|
||||
const btVector3 & getBasePos() const { return base_pos; } // in world frame
|
||||
const btVector3 getBaseVel() const
|
||||
{
|
||||
return btVector3(m_real_buf[3],m_real_buf[4],m_real_buf[5]);
|
||||
} // in world frame
|
||||
const btQuaternion & getWorldToBaseRot() const
|
||||
{
|
||||
return base_quat;
|
||||
} // rotates world vectors into base frame
|
||||
btVector3 getBaseOmega() const { return btVector3(m_real_buf[0],m_real_buf[1],m_real_buf[2]); } // in world frame
|
||||
|
||||
void setBasePos(const btVector3 &pos)
|
||||
{
|
||||
base_pos = pos;
|
||||
}
|
||||
void setBaseVel(const btVector3 &vel)
|
||||
{
|
||||
|
||||
m_real_buf[3]=vel[0]; m_real_buf[4]=vel[1]; m_real_buf[5]=vel[2];
|
||||
}
|
||||
void setWorldToBaseRot(const btQuaternion &rot)
|
||||
{
|
||||
base_quat = rot;
|
||||
}
|
||||
void setBaseOmega(const btVector3 &omega)
|
||||
{
|
||||
m_real_buf[0]=omega[0];
|
||||
m_real_buf[1]=omega[1];
|
||||
m_real_buf[2]=omega[2];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// get/set pos/vel for child links (i = 0 to num_links-1)
|
||||
//
|
||||
|
||||
btScalar getJointPos(int i) const;
|
||||
btScalar getJointVel(int i) const;
|
||||
|
||||
void setJointPos(int i, btScalar q);
|
||||
void setJointVel(int i, btScalar qdot);
|
||||
|
||||
//
|
||||
// direct access to velocities as a vector of 6 + num_links elements.
|
||||
// (omega first, then v, then joint velocities.)
|
||||
//
|
||||
const btScalar * getVelocityVector() const
|
||||
{
|
||||
return &m_real_buf[0];
|
||||
}
|
||||
/* btScalar * getVelocityVector()
|
||||
{
|
||||
return &real_buf[0];
|
||||
}
|
||||
*/
|
||||
|
||||
//
|
||||
// get the frames of reference (positions and orientations) of the child links
|
||||
// (i = 0 to num_links-1)
|
||||
//
|
||||
|
||||
const btVector3 & getRVector(int i) const; // vector from COM(parent(i)) to COM(i), in frame i's coords
|
||||
const btQuaternion & getParentToLocalRot(int i) const; // rotates vectors in frame parent(i) to vectors in frame i.
|
||||
|
||||
|
||||
//
|
||||
// transform vectors in local frame of link i to world frame (or vice versa)
|
||||
//
|
||||
btVector3 localPosToWorld(int i, const btVector3 &vec) const;
|
||||
btVector3 localDirToWorld(int i, const btVector3 &vec) const;
|
||||
btVector3 worldPosToLocal(int i, const btVector3 &vec) const;
|
||||
btVector3 worldDirToLocal(int i, const btVector3 &vec) const;
|
||||
|
||||
|
||||
//
|
||||
// calculate kinetic energy and angular momentum
|
||||
// useful for debugging.
|
||||
//
|
||||
|
||||
btScalar getKineticEnergy() const;
|
||||
btVector3 getAngularMomentum() const;
|
||||
|
||||
|
||||
//
|
||||
// set external forces and torques. Note all external forces/torques are given in the WORLD frame.
|
||||
//
|
||||
|
||||
void clearForcesAndTorques();
|
||||
void clearVelocities();
|
||||
|
||||
void addBaseForce(const btVector3 &f)
|
||||
{
|
||||
base_force += f;
|
||||
}
|
||||
void addBaseTorque(const btVector3 &t) { base_torque += t; }
|
||||
void addLinkForce(int i, const btVector3 &f);
|
||||
void addLinkTorque(int i, const btVector3 &t);
|
||||
void addJointTorque(int i, btScalar Q);
|
||||
|
||||
const btVector3 & getBaseForce() const { return base_force; }
|
||||
const btVector3 & getBaseTorque() const { return base_torque; }
|
||||
const btVector3 & getLinkForce(int i) const;
|
||||
const btVector3 & getLinkTorque(int i) const;
|
||||
btScalar getJointTorque(int i) const;
|
||||
|
||||
|
||||
//
|
||||
// dynamics routines.
|
||||
//
|
||||
|
||||
// timestep the velocities (given the external forces/torques set using addBaseForce etc).
|
||||
// also sets up caches for calcAccelerationDeltas.
|
||||
//
|
||||
// Note: the caller must provide three vectors which are used as
|
||||
// temporary scratch space. The idea here is to reduce dynamic
|
||||
// memory allocation: the same scratch vectors can be re-used
|
||||
// again and again for different Multibodies, instead of each
|
||||
// btMultiBody allocating (and then deallocating) their own
|
||||
// individual scratch buffers. This gives a considerable speed
|
||||
// improvement, at least on Windows (where dynamic memory
|
||||
// allocation appears to be fairly slow).
|
||||
//
|
||||
void stepVelocities(btScalar dt,
|
||||
btAlignedObjectArray<btScalar> &scratch_r,
|
||||
btAlignedObjectArray<btVector3> &scratch_v,
|
||||
btAlignedObjectArray<btMatrix3x3> &scratch_m);
|
||||
|
||||
// calcAccelerationDeltas
|
||||
// input: force vector (in same format as jacobian, i.e.:
|
||||
// 3 torque values, 3 force values, num_links joint torque values)
|
||||
// output: 3 omegadot values, 3 vdot values, num_links q_double_dot values
|
||||
// (existing contents of output array are replaced)
|
||||
// stepVelocities must have been called first.
|
||||
void calcAccelerationDeltas(const btScalar *force, btScalar *output,
|
||||
btAlignedObjectArray<btScalar> &scratch_r,
|
||||
btAlignedObjectArray<btVector3> &scratch_v) const;
|
||||
|
||||
// apply a delta-vee directly. used in sequential impulses code.
|
||||
void applyDeltaVee(const btScalar * delta_vee)
|
||||
{
|
||||
|
||||
for (int i = 0; i < 6 + getNumLinks(); ++i)
|
||||
{
|
||||
m_real_buf[i] += delta_vee[i];
|
||||
}
|
||||
|
||||
}
|
||||
void applyDeltaVee(const btScalar * delta_vee, btScalar multiplier)
|
||||
{
|
||||
btScalar sum = 0;
|
||||
for (int i = 0; i < 6 + getNumLinks(); ++i)
|
||||
{
|
||||
sum += delta_vee[i]*multiplier*delta_vee[i]*multiplier;
|
||||
}
|
||||
btScalar l = btSqrt(sum);
|
||||
/*
|
||||
static btScalar maxl = -1e30f;
|
||||
if (l>maxl)
|
||||
{
|
||||
maxl=l;
|
||||
// printf("maxl=%f\n",maxl);
|
||||
}
|
||||
*/
|
||||
if (l>m_maxAppliedImpulse)
|
||||
{
|
||||
// printf("exceeds 100: l=%f\n",maxl);
|
||||
multiplier *= m_maxAppliedImpulse/l;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6 + getNumLinks(); ++i)
|
||||
{
|
||||
sum += delta_vee[i]*multiplier*delta_vee[i]*multiplier;
|
||||
m_real_buf[i] += delta_vee[i] * multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
// timestep the positions (given current velocities).
|
||||
void stepPositions(btScalar dt);
|
||||
|
||||
|
||||
//
|
||||
// contacts
|
||||
//
|
||||
|
||||
// This routine fills out a contact constraint jacobian for this body.
|
||||
// the 'normal' supplied must be -n for body1 or +n for body2 of the contact.
|
||||
// 'normal' & 'contact_point' are both given in world coordinates.
|
||||
void fillContactJacobian(int link,
|
||||
const btVector3 &contact_point,
|
||||
const btVector3 &normal,
|
||||
btScalar *jac,
|
||||
btAlignedObjectArray<btScalar> &scratch_r,
|
||||
btAlignedObjectArray<btVector3> &scratch_v,
|
||||
btAlignedObjectArray<btMatrix3x3> &scratch_m) const;
|
||||
|
||||
|
||||
//
|
||||
// sleeping
|
||||
//
|
||||
void setCanSleep(bool canSleep)
|
||||
{
|
||||
can_sleep = canSleep;
|
||||
}
|
||||
|
||||
bool isAwake() const { return awake; }
|
||||
void wakeUp();
|
||||
void goToSleep();
|
||||
void checkMotionAndSleepIfRequired(btScalar timestep);
|
||||
|
||||
bool hasFixedBase() const
|
||||
{
|
||||
return fixed_base;
|
||||
}
|
||||
|
||||
int getCompanionId() const
|
||||
{
|
||||
return m_companionId;
|
||||
}
|
||||
void setCompanionId(int id)
|
||||
{
|
||||
//printf("for %p setCompanionId(%d)\n",this, id);
|
||||
m_companionId = id;
|
||||
}
|
||||
|
||||
void setNumLinks(int numLinks)//careful: when changing the number of links, make sure to re-initialize or update existing links
|
||||
{
|
||||
links.resize(numLinks);
|
||||
}
|
||||
|
||||
btScalar getLinearDamping() const
|
||||
{
|
||||
return m_linearDamping;
|
||||
}
|
||||
void setLinearDamping( btScalar damp)
|
||||
{
|
||||
m_linearDamping = damp;
|
||||
}
|
||||
btScalar getAngularDamping() const
|
||||
{
|
||||
return m_angularDamping;
|
||||
}
|
||||
|
||||
bool getUseGyroTerm() const
|
||||
{
|
||||
return m_useGyroTerm;
|
||||
}
|
||||
void setUseGyroTerm(bool useGyro)
|
||||
{
|
||||
m_useGyroTerm = useGyro;
|
||||
}
|
||||
btScalar getMaxAppliedImpulse() const
|
||||
{
|
||||
return m_maxAppliedImpulse;
|
||||
}
|
||||
void setMaxAppliedImpulse(btScalar maxImp)
|
||||
{
|
||||
m_maxAppliedImpulse = maxImp;
|
||||
}
|
||||
|
||||
void setHasSelfCollision(bool hasSelfCollision)
|
||||
{
|
||||
m_hasSelfCollision = hasSelfCollision;
|
||||
}
|
||||
bool hasSelfCollision() const
|
||||
{
|
||||
return m_hasSelfCollision;
|
||||
}
|
||||
|
||||
private:
|
||||
btMultiBody(const btMultiBody &); // not implemented
|
||||
void operator=(const btMultiBody &); // not implemented
|
||||
|
||||
void compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const;
|
||||
|
||||
void solveImatrix(const btVector3& rhs_top, const btVector3& rhs_bot, float result[6]) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
btMultiBodyLinkCollider* m_baseCollider;//can be NULL
|
||||
|
||||
btVector3 base_pos; // position of COM of base (world frame)
|
||||
btQuaternion base_quat; // rotates world points into base frame
|
||||
|
||||
btScalar base_mass; // mass of the base
|
||||
btVector3 base_inertia; // inertia of the base (in local frame; diagonal)
|
||||
|
||||
btVector3 base_force; // external force applied to base. World frame.
|
||||
btVector3 base_torque; // external torque applied to base. World frame.
|
||||
|
||||
btAlignedObjectArray<btMultibodyLink> links; // array of links, excluding the base. index from 0 to num_links-1.
|
||||
btAlignedObjectArray<btMultiBodyLinkCollider*> m_colliders;
|
||||
|
||||
//
|
||||
// real_buf:
|
||||
// offset size array
|
||||
// 0 6 + num_links v (base_omega; base_vel; joint_vels)
|
||||
// 6+num_links num_links D
|
||||
//
|
||||
// vector_buf:
|
||||
// offset size array
|
||||
// 0 num_links h_top
|
||||
// num_links num_links h_bottom
|
||||
//
|
||||
// matrix_buf:
|
||||
// offset size array
|
||||
// 0 num_links+1 rot_from_parent
|
||||
//
|
||||
|
||||
btAlignedObjectArray<btScalar> m_real_buf;
|
||||
btAlignedObjectArray<btVector3> vector_buf;
|
||||
btAlignedObjectArray<btMatrix3x3> matrix_buf;
|
||||
|
||||
//std::auto_ptr<Eigen::LU<Eigen::Matrix<btScalar, 6, 6> > > cached_imatrix_lu;
|
||||
|
||||
btMatrix3x3 cached_inertia_top_left;
|
||||
btMatrix3x3 cached_inertia_top_right;
|
||||
btMatrix3x3 cached_inertia_lower_left;
|
||||
btMatrix3x3 cached_inertia_lower_right;
|
||||
|
||||
bool fixed_base;
|
||||
|
||||
// Sleep parameters.
|
||||
bool awake;
|
||||
bool can_sleep;
|
||||
btScalar sleep_timer;
|
||||
|
||||
int m_companionId;
|
||||
btScalar m_linearDamping;
|
||||
btScalar m_angularDamping;
|
||||
bool m_useGyroTerm;
|
||||
btScalar m_maxAppliedImpulse;
|
||||
bool m_hasSelfCollision;
|
||||
};
|
||||
|
||||
#endif
|
527
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp
vendored
Normal file
527
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp
vendored
Normal file
@@ -0,0 +1,527 @@
|
||||
#include "btMultiBodyConstraint.h"
|
||||
#include "BulletDynamics/Dynamics/btRigidBody.h"
|
||||
|
||||
btMultiBodyConstraint::btMultiBodyConstraint(btMultiBody* bodyA,btMultiBody* bodyB,int linkA, int linkB, int numRows, bool isUnilateral)
|
||||
:m_bodyA(bodyA),
|
||||
m_bodyB(bodyB),
|
||||
m_linkA(linkA),
|
||||
m_linkB(linkB),
|
||||
m_num_rows(numRows),
|
||||
m_isUnilateral(isUnilateral),
|
||||
m_maxAppliedImpulse(100)
|
||||
{
|
||||
m_jac_size_A = (6 + bodyA->getNumLinks());
|
||||
m_jac_size_both = (m_jac_size_A + (bodyB ? 6 + bodyB->getNumLinks() : 0));
|
||||
m_pos_offset = ((1 + m_jac_size_both)*m_num_rows);
|
||||
m_data.resize((2 + m_jac_size_both) * m_num_rows);
|
||||
}
|
||||
|
||||
btMultiBodyConstraint::~btMultiBodyConstraint()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
btScalar btMultiBodyConstraint::fillConstraintRowMultiBodyMultiBody(btMultiBodySolverConstraint& constraintRow,
|
||||
btMultiBodyJacobianData& data,
|
||||
btScalar* jacOrgA,btScalar* jacOrgB,
|
||||
const btContactSolverInfo& infoGlobal,
|
||||
btScalar desiredVelocity,
|
||||
btScalar lowerLimit,
|
||||
btScalar upperLimit)
|
||||
{
|
||||
|
||||
|
||||
|
||||
constraintRow.m_multiBodyA = m_bodyA;
|
||||
constraintRow.m_multiBodyB = m_bodyB;
|
||||
|
||||
btMultiBody* multiBodyA = constraintRow.m_multiBodyA;
|
||||
btMultiBody* multiBodyB = constraintRow.m_multiBodyB;
|
||||
|
||||
if (multiBodyA)
|
||||
{
|
||||
|
||||
const int ndofA = multiBodyA->getNumLinks() + 6;
|
||||
|
||||
constraintRow.m_deltaVelAindex = multiBodyA->getCompanionId();
|
||||
|
||||
if (constraintRow.m_deltaVelAindex <0)
|
||||
{
|
||||
constraintRow.m_deltaVelAindex = data.m_deltaVelocities.size();
|
||||
multiBodyA->setCompanionId(constraintRow.m_deltaVelAindex);
|
||||
data.m_deltaVelocities.resize(data.m_deltaVelocities.size()+ndofA);
|
||||
} else
|
||||
{
|
||||
btAssert(data.m_deltaVelocities.size() >= constraintRow.m_deltaVelAindex+ndofA);
|
||||
}
|
||||
|
||||
constraintRow.m_jacAindex = data.m_jacobians.size();
|
||||
data.m_jacobians.resize(data.m_jacobians.size()+ndofA);
|
||||
data.m_deltaVelocitiesUnitImpulse.resize(data.m_deltaVelocitiesUnitImpulse.size()+ndofA);
|
||||
btAssert(data.m_jacobians.size() == data.m_deltaVelocitiesUnitImpulse.size());
|
||||
for (int i=0;i<ndofA;i++)
|
||||
data.m_jacobians[constraintRow.m_jacAindex+i] = jacOrgA[i];
|
||||
|
||||
btScalar* delta = &data.m_deltaVelocitiesUnitImpulse[constraintRow.m_jacAindex];
|
||||
multiBodyA->calcAccelerationDeltas(&data.m_jacobians[constraintRow.m_jacAindex],delta,data.scratch_r, data.scratch_v);
|
||||
}
|
||||
|
||||
if (multiBodyB)
|
||||
{
|
||||
const int ndofB = multiBodyB->getNumLinks() + 6;
|
||||
|
||||
constraintRow.m_deltaVelBindex = multiBodyB->getCompanionId();
|
||||
if (constraintRow.m_deltaVelBindex <0)
|
||||
{
|
||||
constraintRow.m_deltaVelBindex = data.m_deltaVelocities.size();
|
||||
multiBodyB->setCompanionId(constraintRow.m_deltaVelBindex);
|
||||
data.m_deltaVelocities.resize(data.m_deltaVelocities.size()+ndofB);
|
||||
}
|
||||
|
||||
constraintRow.m_jacBindex = data.m_jacobians.size();
|
||||
data.m_jacobians.resize(data.m_jacobians.size()+ndofB);
|
||||
|
||||
for (int i=0;i<ndofB;i++)
|
||||
data.m_jacobians[constraintRow.m_jacBindex+i] = jacOrgB[i];
|
||||
|
||||
data.m_deltaVelocitiesUnitImpulse.resize(data.m_deltaVelocitiesUnitImpulse.size()+ndofB);
|
||||
btAssert(data.m_jacobians.size() == data.m_deltaVelocitiesUnitImpulse.size());
|
||||
multiBodyB->calcAccelerationDeltas(&data.m_jacobians[constraintRow.m_jacBindex],&data.m_deltaVelocitiesUnitImpulse[constraintRow.m_jacBindex],data.scratch_r, data.scratch_v);
|
||||
}
|
||||
{
|
||||
|
||||
btVector3 vec;
|
||||
btScalar denom0 = 0.f;
|
||||
btScalar denom1 = 0.f;
|
||||
btScalar* jacB = 0;
|
||||
btScalar* jacA = 0;
|
||||
btScalar* lambdaA =0;
|
||||
btScalar* lambdaB =0;
|
||||
int ndofA = 0;
|
||||
if (multiBodyA)
|
||||
{
|
||||
ndofA = multiBodyA->getNumLinks() + 6;
|
||||
jacA = &data.m_jacobians[constraintRow.m_jacAindex];
|
||||
lambdaA = &data.m_deltaVelocitiesUnitImpulse[constraintRow.m_jacAindex];
|
||||
for (int i = 0; i < ndofA; ++i)
|
||||
{
|
||||
btScalar j = jacA[i] ;
|
||||
btScalar l =lambdaA[i];
|
||||
denom0 += j*l;
|
||||
}
|
||||
}
|
||||
if (multiBodyB)
|
||||
{
|
||||
const int ndofB = multiBodyB->getNumLinks() + 6;
|
||||
jacB = &data.m_jacobians[constraintRow.m_jacBindex];
|
||||
lambdaB = &data.m_deltaVelocitiesUnitImpulse[constraintRow.m_jacBindex];
|
||||
for (int i = 0; i < ndofB; ++i)
|
||||
{
|
||||
btScalar j = jacB[i] ;
|
||||
btScalar l =lambdaB[i];
|
||||
denom1 += j*l;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (multiBodyA && (multiBodyA==multiBodyB))
|
||||
{
|
||||
// ndof1 == ndof2 in this case
|
||||
for (int i = 0; i < ndofA; ++i)
|
||||
{
|
||||
denom1 += jacB[i] * lambdaA[i];
|
||||
denom1 += jacA[i] * lambdaB[i];
|
||||
}
|
||||
}
|
||||
|
||||
btScalar d = denom0+denom1;
|
||||
if (btFabs(d)>SIMD_EPSILON)
|
||||
{
|
||||
|
||||
constraintRow.m_jacDiagABInv = 1.f/(d);
|
||||
} else
|
||||
{
|
||||
constraintRow.m_jacDiagABInv = 1.f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//compute rhs and remaining constraintRow fields
|
||||
|
||||
|
||||
|
||||
|
||||
btScalar rel_vel = 0.f;
|
||||
int ndofA = 0;
|
||||
int ndofB = 0;
|
||||
{
|
||||
|
||||
btVector3 vel1,vel2;
|
||||
if (multiBodyA)
|
||||
{
|
||||
ndofA = multiBodyA->getNumLinks() + 6;
|
||||
btScalar* jacA = &data.m_jacobians[constraintRow.m_jacAindex];
|
||||
for (int i = 0; i < ndofA ; ++i)
|
||||
rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i];
|
||||
}
|
||||
if (multiBodyB)
|
||||
{
|
||||
ndofB = multiBodyB->getNumLinks() + 6;
|
||||
btScalar* jacB = &data.m_jacobians[constraintRow.m_jacBindex];
|
||||
for (int i = 0; i < ndofB ; ++i)
|
||||
rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i];
|
||||
|
||||
}
|
||||
|
||||
constraintRow.m_friction = 0.f;
|
||||
|
||||
constraintRow.m_appliedImpulse = 0.f;
|
||||
constraintRow.m_appliedPushImpulse = 0.f;
|
||||
|
||||
btScalar velocityError = desiredVelocity - rel_vel;// * damping;
|
||||
|
||||
btScalar erp = infoGlobal.m_erp2;
|
||||
|
||||
btScalar velocityImpulse = velocityError *constraintRow.m_jacDiagABInv;
|
||||
|
||||
if (!infoGlobal.m_splitImpulse)
|
||||
{
|
||||
//combine position and velocity into rhs
|
||||
constraintRow.m_rhs = velocityImpulse;
|
||||
constraintRow.m_rhsPenetration = 0.f;
|
||||
|
||||
} else
|
||||
{
|
||||
//split position and velocity into rhs and m_rhsPenetration
|
||||
constraintRow.m_rhs = velocityImpulse;
|
||||
constraintRow.m_rhsPenetration = 0.f;
|
||||
}
|
||||
|
||||
|
||||
constraintRow.m_cfm = 0.f;
|
||||
constraintRow.m_lowerLimit = lowerLimit;
|
||||
constraintRow.m_upperLimit = upperLimit;
|
||||
|
||||
}
|
||||
return rel_vel;
|
||||
}
|
||||
|
||||
|
||||
void btMultiBodyConstraint::applyDeltaVee(btMultiBodyJacobianData& data, btScalar* delta_vee, btScalar impulse, int velocityIndex, int ndof)
|
||||
{
|
||||
for (int i = 0; i < ndof; ++i)
|
||||
data.m_deltaVelocities[velocityIndex+i] += delta_vee[i] * impulse;
|
||||
}
|
||||
|
||||
|
||||
void btMultiBodyConstraint::fillMultiBodyConstraintMixed(btMultiBodySolverConstraint& solverConstraint,
|
||||
btMultiBodyJacobianData& data,
|
||||
const btVector3& contactNormalOnB,
|
||||
const btVector3& posAworld, const btVector3& posBworld,
|
||||
btScalar position,
|
||||
const btContactSolverInfo& infoGlobal,
|
||||
btScalar& relaxation,
|
||||
bool isFriction, btScalar desiredVelocity, btScalar cfmSlip)
|
||||
{
|
||||
|
||||
|
||||
btVector3 rel_pos1 = posAworld;
|
||||
btVector3 rel_pos2 = posBworld;
|
||||
|
||||
solverConstraint.m_multiBodyA = m_bodyA;
|
||||
solverConstraint.m_multiBodyB = m_bodyB;
|
||||
solverConstraint.m_linkA = m_linkA;
|
||||
solverConstraint.m_linkB = m_linkB;
|
||||
|
||||
|
||||
btMultiBody* multiBodyA = solverConstraint.m_multiBodyA;
|
||||
btMultiBody* multiBodyB = solverConstraint.m_multiBodyB;
|
||||
|
||||
const btVector3& pos1 = posAworld;
|
||||
const btVector3& pos2 = posBworld;
|
||||
|
||||
btSolverBody* bodyA = multiBodyA ? 0 : &data.m_solverBodyPool->at(solverConstraint.m_solverBodyIdA);
|
||||
btSolverBody* bodyB = multiBodyB ? 0 : &data.m_solverBodyPool->at(solverConstraint.m_solverBodyIdB);
|
||||
|
||||
btRigidBody* rb0 = multiBodyA ? 0 : bodyA->m_originalBody;
|
||||
btRigidBody* rb1 = multiBodyB ? 0 : bodyB->m_originalBody;
|
||||
|
||||
if (bodyA)
|
||||
rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin();
|
||||
if (bodyB)
|
||||
rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin();
|
||||
|
||||
relaxation = 1.f;
|
||||
|
||||
if (multiBodyA)
|
||||
{
|
||||
const int ndofA = multiBodyA->getNumLinks() + 6;
|
||||
|
||||
solverConstraint.m_deltaVelAindex = multiBodyA->getCompanionId();
|
||||
|
||||
if (solverConstraint.m_deltaVelAindex <0)
|
||||
{
|
||||
solverConstraint.m_deltaVelAindex = data.m_deltaVelocities.size();
|
||||
multiBodyA->setCompanionId(solverConstraint.m_deltaVelAindex);
|
||||
data.m_deltaVelocities.resize(data.m_deltaVelocities.size()+ndofA);
|
||||
} else
|
||||
{
|
||||
btAssert(data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex+ndofA);
|
||||
}
|
||||
|
||||
solverConstraint.m_jacAindex = data.m_jacobians.size();
|
||||
data.m_jacobians.resize(data.m_jacobians.size()+ndofA);
|
||||
data.m_deltaVelocitiesUnitImpulse.resize(data.m_deltaVelocitiesUnitImpulse.size()+ndofA);
|
||||
btAssert(data.m_jacobians.size() == data.m_deltaVelocitiesUnitImpulse.size());
|
||||
|
||||
btScalar* jac1=&data.m_jacobians[solverConstraint.m_jacAindex];
|
||||
multiBodyA->fillContactJacobian(solverConstraint.m_linkA, posAworld, contactNormalOnB, jac1, data.scratch_r, data.scratch_v, data.scratch_m);
|
||||
btScalar* delta = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
|
||||
multiBodyA->calcAccelerationDeltas(&data.m_jacobians[solverConstraint.m_jacAindex],delta,data.scratch_r, data.scratch_v);
|
||||
} else
|
||||
{
|
||||
btVector3 torqueAxis0 = rel_pos1.cross(contactNormalOnB);
|
||||
solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0);
|
||||
solverConstraint.m_relpos1CrossNormal = torqueAxis0;
|
||||
solverConstraint.m_contactNormal1 = contactNormalOnB;
|
||||
}
|
||||
|
||||
if (multiBodyB)
|
||||
{
|
||||
const int ndofB = multiBodyB->getNumLinks() + 6;
|
||||
|
||||
solverConstraint.m_deltaVelBindex = multiBodyB->getCompanionId();
|
||||
if (solverConstraint.m_deltaVelBindex <0)
|
||||
{
|
||||
solverConstraint.m_deltaVelBindex = data.m_deltaVelocities.size();
|
||||
multiBodyB->setCompanionId(solverConstraint.m_deltaVelBindex);
|
||||
data.m_deltaVelocities.resize(data.m_deltaVelocities.size()+ndofB);
|
||||
}
|
||||
|
||||
solverConstraint.m_jacBindex = data.m_jacobians.size();
|
||||
|
||||
data.m_jacobians.resize(data.m_jacobians.size()+ndofB);
|
||||
data.m_deltaVelocitiesUnitImpulse.resize(data.m_deltaVelocitiesUnitImpulse.size()+ndofB);
|
||||
btAssert(data.m_jacobians.size() == data.m_deltaVelocitiesUnitImpulse.size());
|
||||
|
||||
multiBodyB->fillContactJacobian(solverConstraint.m_linkB, posBworld, -contactNormalOnB, &data.m_jacobians[solverConstraint.m_jacBindex], data.scratch_r, data.scratch_v, data.scratch_m);
|
||||
multiBodyB->calcAccelerationDeltas(&data.m_jacobians[solverConstraint.m_jacBindex],&data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex],data.scratch_r, data.scratch_v);
|
||||
} else
|
||||
{
|
||||
btVector3 torqueAxis1 = rel_pos2.cross(contactNormalOnB);
|
||||
solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0);
|
||||
solverConstraint.m_relpos2CrossNormal = -torqueAxis1;
|
||||
solverConstraint.m_contactNormal2 = -contactNormalOnB;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
btVector3 vec;
|
||||
btScalar denom0 = 0.f;
|
||||
btScalar denom1 = 0.f;
|
||||
btScalar* jacB = 0;
|
||||
btScalar* jacA = 0;
|
||||
btScalar* lambdaA =0;
|
||||
btScalar* lambdaB =0;
|
||||
int ndofA = 0;
|
||||
if (multiBodyA)
|
||||
{
|
||||
ndofA = multiBodyA->getNumLinks() + 6;
|
||||
jacA = &data.m_jacobians[solverConstraint.m_jacAindex];
|
||||
lambdaA = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
|
||||
for (int i = 0; i < ndofA; ++i)
|
||||
{
|
||||
btScalar j = jacA[i] ;
|
||||
btScalar l =lambdaA[i];
|
||||
denom0 += j*l;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (rb0)
|
||||
{
|
||||
vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
|
||||
denom0 = rb0->getInvMass() + contactNormalOnB.dot(vec);
|
||||
}
|
||||
}
|
||||
if (multiBodyB)
|
||||
{
|
||||
const int ndofB = multiBodyB->getNumLinks() + 6;
|
||||
jacB = &data.m_jacobians[solverConstraint.m_jacBindex];
|
||||
lambdaB = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex];
|
||||
for (int i = 0; i < ndofB; ++i)
|
||||
{
|
||||
btScalar j = jacB[i] ;
|
||||
btScalar l =lambdaB[i];
|
||||
denom1 += j*l;
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
if (rb1)
|
||||
{
|
||||
vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
|
||||
denom1 = rb1->getInvMass() + contactNormalOnB.dot(vec);
|
||||
}
|
||||
}
|
||||
|
||||
if (multiBodyA && (multiBodyA==multiBodyB))
|
||||
{
|
||||
// ndof1 == ndof2 in this case
|
||||
for (int i = 0; i < ndofA; ++i)
|
||||
{
|
||||
denom1 += jacB[i] * lambdaA[i];
|
||||
denom1 += jacA[i] * lambdaB[i];
|
||||
}
|
||||
}
|
||||
|
||||
btScalar d = denom0+denom1;
|
||||
if (btFabs(d)>SIMD_EPSILON)
|
||||
{
|
||||
|
||||
solverConstraint.m_jacDiagABInv = relaxation/(d);
|
||||
} else
|
||||
{
|
||||
solverConstraint.m_jacDiagABInv = 1.f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//compute rhs and remaining solverConstraint fields
|
||||
|
||||
|
||||
|
||||
btScalar restitution = 0.f;
|
||||
btScalar penetration = isFriction? 0 : position+infoGlobal.m_linearSlop;
|
||||
|
||||
btScalar rel_vel = 0.f;
|
||||
int ndofA = 0;
|
||||
int ndofB = 0;
|
||||
{
|
||||
|
||||
btVector3 vel1,vel2;
|
||||
if (multiBodyA)
|
||||
{
|
||||
ndofA = multiBodyA->getNumLinks() + 6;
|
||||
btScalar* jacA = &data.m_jacobians[solverConstraint.m_jacAindex];
|
||||
for (int i = 0; i < ndofA ; ++i)
|
||||
rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i];
|
||||
} else
|
||||
{
|
||||
if (rb0)
|
||||
{
|
||||
rel_vel += rb0->getVelocityInLocalPoint(rel_pos1).dot(solverConstraint.m_contactNormal1);
|
||||
}
|
||||
}
|
||||
if (multiBodyB)
|
||||
{
|
||||
ndofB = multiBodyB->getNumLinks() + 6;
|
||||
btScalar* jacB = &data.m_jacobians[solverConstraint.m_jacBindex];
|
||||
for (int i = 0; i < ndofB ; ++i)
|
||||
rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i];
|
||||
|
||||
} else
|
||||
{
|
||||
if (rb1)
|
||||
{
|
||||
rel_vel += rb1->getVelocityInLocalPoint(rel_pos2).dot(solverConstraint.m_contactNormal2);
|
||||
}
|
||||
}
|
||||
|
||||
solverConstraint.m_friction = 0.f;//cp.m_combinedFriction;
|
||||
|
||||
|
||||
restitution = restitution * -rel_vel;//restitutionCurve(rel_vel, cp.m_combinedRestitution);
|
||||
if (restitution <= btScalar(0.))
|
||||
{
|
||||
restitution = 0.f;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///warm starting (or zero if disabled)
|
||||
/*
|
||||
if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
|
||||
{
|
||||
solverConstraint.m_appliedImpulse = isFriction ? 0 : cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
|
||||
|
||||
if (solverConstraint.m_appliedImpulse)
|
||||
{
|
||||
if (multiBodyA)
|
||||
{
|
||||
btScalar impulse = solverConstraint.m_appliedImpulse;
|
||||
btScalar* deltaV = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
|
||||
multiBodyA->applyDeltaVee(deltaV,impulse);
|
||||
applyDeltaVee(data,deltaV,impulse,solverConstraint.m_deltaVelAindex,ndofA);
|
||||
} else
|
||||
{
|
||||
if (rb0)
|
||||
bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1*bodyA->internalGetInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
|
||||
}
|
||||
if (multiBodyB)
|
||||
{
|
||||
btScalar impulse = solverConstraint.m_appliedImpulse;
|
||||
btScalar* deltaV = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex];
|
||||
multiBodyB->applyDeltaVee(deltaV,impulse);
|
||||
applyDeltaVee(data,deltaV,impulse,solverConstraint.m_deltaVelBindex,ndofB);
|
||||
} else
|
||||
{
|
||||
if (rb1)
|
||||
bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2*bodyB->internalGetInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse);
|
||||
}
|
||||
}
|
||||
} else
|
||||
*/
|
||||
{
|
||||
solverConstraint.m_appliedImpulse = 0.f;
|
||||
}
|
||||
|
||||
solverConstraint.m_appliedPushImpulse = 0.f;
|
||||
|
||||
{
|
||||
|
||||
|
||||
btScalar positionalError = 0.f;
|
||||
btScalar velocityError = restitution - rel_vel;// * damping;
|
||||
|
||||
|
||||
btScalar erp = infoGlobal.m_erp2;
|
||||
if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
|
||||
{
|
||||
erp = infoGlobal.m_erp;
|
||||
}
|
||||
|
||||
if (penetration>0)
|
||||
{
|
||||
positionalError = 0;
|
||||
velocityError = -penetration / infoGlobal.m_timeStep;
|
||||
|
||||
} else
|
||||
{
|
||||
positionalError = -penetration * erp/infoGlobal.m_timeStep;
|
||||
}
|
||||
|
||||
btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
|
||||
btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
|
||||
|
||||
if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
|
||||
{
|
||||
//combine position and velocity into rhs
|
||||
solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
|
||||
solverConstraint.m_rhsPenetration = 0.f;
|
||||
|
||||
} else
|
||||
{
|
||||
//split position and velocity into rhs and m_rhsPenetration
|
||||
solverConstraint.m_rhs = velocityImpulse;
|
||||
solverConstraint.m_rhsPenetration = penetrationImpulse;
|
||||
}
|
||||
|
||||
solverConstraint.m_cfm = 0.f;
|
||||
solverConstraint.m_lowerLimit = -m_maxAppliedImpulse;
|
||||
solverConstraint.m_upperLimit = m_maxAppliedImpulse;
|
||||
}
|
||||
|
||||
}
|
166
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraint.h
vendored
Normal file
166
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraint.h
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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_MULTIBODY_CONSTRAINT_H
|
||||
#define BT_MULTIBODY_CONSTRAINT_H
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "btMultiBody.h"
|
||||
|
||||
class btMultiBody;
|
||||
struct btSolverInfo;
|
||||
|
||||
#include "btMultiBodySolverConstraint.h"
|
||||
|
||||
struct btMultiBodyJacobianData
|
||||
{
|
||||
btAlignedObjectArray<btScalar> m_jacobians;
|
||||
btAlignedObjectArray<btScalar> m_deltaVelocitiesUnitImpulse;
|
||||
btAlignedObjectArray<btScalar> m_deltaVelocities;
|
||||
btAlignedObjectArray<btScalar> scratch_r;
|
||||
btAlignedObjectArray<btVector3> scratch_v;
|
||||
btAlignedObjectArray<btMatrix3x3> scratch_m;
|
||||
btAlignedObjectArray<btSolverBody>* m_solverBodyPool;
|
||||
int m_fixedBodyId;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class btMultiBodyConstraint
|
||||
{
|
||||
protected:
|
||||
|
||||
btMultiBody* m_bodyA;
|
||||
btMultiBody* m_bodyB;
|
||||
int m_linkA;
|
||||
int m_linkB;
|
||||
|
||||
int m_num_rows;
|
||||
int m_jac_size_A;
|
||||
int m_jac_size_both;
|
||||
int m_pos_offset;
|
||||
|
||||
bool m_isUnilateral;
|
||||
|
||||
btScalar m_maxAppliedImpulse;
|
||||
|
||||
|
||||
// data block laid out as follows:
|
||||
// cached impulses. (one per row.)
|
||||
// jacobians. (interleaved, row1 body1 then row1 body2 then row2 body 1 etc)
|
||||
// positions. (one per row.)
|
||||
btAlignedObjectArray<btScalar> m_data;
|
||||
|
||||
void applyDeltaVee(btMultiBodyJacobianData& data, btScalar* delta_vee, btScalar impulse, int velocityIndex, int ndof);
|
||||
|
||||
void fillMultiBodyConstraintMixed(btMultiBodySolverConstraint& solverConstraint,
|
||||
btMultiBodyJacobianData& data,
|
||||
const btVector3& contactNormalOnB,
|
||||
const btVector3& posAworld, const btVector3& posBworld,
|
||||
btScalar position,
|
||||
const btContactSolverInfo& infoGlobal,
|
||||
btScalar& relaxation,
|
||||
bool isFriction, btScalar desiredVelocity=0, btScalar cfmSlip=0);
|
||||
|
||||
btScalar fillConstraintRowMultiBodyMultiBody(btMultiBodySolverConstraint& constraintRow,
|
||||
btMultiBodyJacobianData& data,
|
||||
btScalar* jacOrgA,btScalar* jacOrgB,
|
||||
const btContactSolverInfo& infoGlobal,
|
||||
btScalar desiredVelocity,
|
||||
btScalar lowerLimit,
|
||||
btScalar upperLimit);
|
||||
|
||||
public:
|
||||
|
||||
btMultiBodyConstraint(btMultiBody* bodyA,btMultiBody* bodyB,int linkA, int linkB, int numRows, bool isUnilateral);
|
||||
virtual ~btMultiBodyConstraint();
|
||||
|
||||
|
||||
|
||||
virtual int getIslandIdA() const =0;
|
||||
virtual int getIslandIdB() const =0;
|
||||
|
||||
virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows,
|
||||
btMultiBodyJacobianData& data,
|
||||
const btContactSolverInfo& infoGlobal)=0;
|
||||
|
||||
int getNumRows() const
|
||||
{
|
||||
return m_num_rows;
|
||||
}
|
||||
|
||||
btMultiBody* getMultiBodyA()
|
||||
{
|
||||
return m_bodyA;
|
||||
}
|
||||
btMultiBody* getMultiBodyB()
|
||||
{
|
||||
return m_bodyB;
|
||||
}
|
||||
|
||||
// current constraint position
|
||||
// constraint is pos >= 0 for unilateral, or pos = 0 for bilateral
|
||||
// NOTE: ignored position for friction rows.
|
||||
btScalar getPosition(int row) const
|
||||
{
|
||||
return m_data[m_pos_offset + row];
|
||||
}
|
||||
|
||||
void setPosition(int row, btScalar pos)
|
||||
{
|
||||
m_data[m_pos_offset + row] = pos;
|
||||
}
|
||||
|
||||
|
||||
bool isUnilateral() const
|
||||
{
|
||||
return m_isUnilateral;
|
||||
}
|
||||
|
||||
// jacobian blocks.
|
||||
// each of size 6 + num_links. (jacobian2 is null if no body2.)
|
||||
// format: 3 'omega' coefficients, 3 'v' coefficients, then the 'qdot' coefficients.
|
||||
btScalar* jacobianA(int row)
|
||||
{
|
||||
return &m_data[m_num_rows + row * m_jac_size_both];
|
||||
}
|
||||
const btScalar* jacobianA(int row) const
|
||||
{
|
||||
return &m_data[m_num_rows + (row * m_jac_size_both)];
|
||||
}
|
||||
btScalar* jacobianB(int row)
|
||||
{
|
||||
return &m_data[m_num_rows + (row * m_jac_size_both) + m_jac_size_A];
|
||||
}
|
||||
const btScalar* jacobianB(int row) const
|
||||
{
|
||||
return &m_data[m_num_rows + (row * m_jac_size_both) + m_jac_size_A];
|
||||
}
|
||||
|
||||
btScalar getMaxAppliedImpulse() const
|
||||
{
|
||||
return m_maxAppliedImpulse;
|
||||
}
|
||||
void setMaxAppliedImpulse(btScalar maxImp)
|
||||
{
|
||||
m_maxAppliedImpulse = maxImp;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_MULTIBODY_CONSTRAINT_H
|
||||
|
795
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
vendored
Normal file
795
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
vendored
Normal file
@@ -0,0 +1,795 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#include "btMultiBodyConstraintSolver.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
|
||||
#include "btMultiBodyLinkCollider.h"
|
||||
|
||||
#include "BulletDynamics/ConstraintSolver/btSolverBody.h"
|
||||
#include "btMultiBodyConstraint.h"
|
||||
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
|
||||
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
|
||||
btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
|
||||
{
|
||||
btScalar val = btSequentialImpulseConstraintSolver::solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer);
|
||||
|
||||
//solve featherstone non-contact constraints
|
||||
|
||||
//printf("m_multiBodyNonContactConstraints = %d\n",m_multiBodyNonContactConstraints.size());
|
||||
for (int j=0;j<m_multiBodyNonContactConstraints.size();j++)
|
||||
{
|
||||
btMultiBodySolverConstraint& constraint = m_multiBodyNonContactConstraints[j];
|
||||
//if (iteration < constraint.m_overrideNumSolverIterations)
|
||||
//resolveSingleConstraintRowGenericMultiBody(constraint);
|
||||
resolveSingleConstraintRowGeneric(constraint);
|
||||
}
|
||||
|
||||
//solve featherstone normal contact
|
||||
for (int j=0;j<m_multiBodyNormalContactConstraints.size();j++)
|
||||
{
|
||||
btMultiBodySolverConstraint& constraint = m_multiBodyNormalContactConstraints[j];
|
||||
if (iteration < infoGlobal.m_numIterations)
|
||||
resolveSingleConstraintRowGeneric(constraint);
|
||||
}
|
||||
|
||||
//solve featherstone frictional contact
|
||||
|
||||
for (int j=0;j<this->m_multiBodyFrictionContactConstraints.size();j++)
|
||||
{
|
||||
if (iteration < infoGlobal.m_numIterations)
|
||||
{
|
||||
btMultiBodySolverConstraint& frictionConstraint = m_multiBodyFrictionContactConstraints[j];
|
||||
btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse;
|
||||
//adjust friction limits here
|
||||
if (totalImpulse>btScalar(0))
|
||||
{
|
||||
frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction*totalImpulse);
|
||||
frictionConstraint.m_upperLimit = frictionConstraint.m_friction*totalImpulse;
|
||||
resolveSingleConstraintRowGeneric(frictionConstraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
|
||||
{
|
||||
m_multiBodyNonContactConstraints.resize(0);
|
||||
m_multiBodyNormalContactConstraints.resize(0);
|
||||
m_multiBodyFrictionContactConstraints.resize(0);
|
||||
m_data.m_jacobians.resize(0);
|
||||
m_data.m_deltaVelocitiesUnitImpulse.resize(0);
|
||||
m_data.m_deltaVelocities.resize(0);
|
||||
|
||||
for (int i=0;i<numBodies;i++)
|
||||
{
|
||||
const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(bodies[i]);
|
||||
if (fcA)
|
||||
{
|
||||
fcA->m_multiBody->setCompanionId(-1);
|
||||
}
|
||||
}
|
||||
|
||||
btScalar val = btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup( bodies,numBodies,manifoldPtr, numManifolds, constraints,numConstraints,infoGlobal,debugDrawer);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void btMultiBodyConstraintSolver::applyDeltaVee(btScalar* delta_vee, btScalar impulse, int velocityIndex, int ndof)
|
||||
{
|
||||
for (int i = 0; i < ndof; ++i)
|
||||
m_data.m_deltaVelocities[velocityIndex+i] += delta_vee[i] * impulse;
|
||||
}
|
||||
|
||||
void btMultiBodyConstraintSolver::resolveSingleConstraintRowGeneric(const btMultiBodySolverConstraint& c)
|
||||
{
|
||||
|
||||
btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
|
||||
btScalar deltaVelADotn=0;
|
||||
btScalar deltaVelBDotn=0;
|
||||
btSolverBody* bodyA = 0;
|
||||
btSolverBody* bodyB = 0;
|
||||
int ndofA=0;
|
||||
int ndofB=0;
|
||||
|
||||
if (c.m_multiBodyA)
|
||||
{
|
||||
ndofA = c.m_multiBodyA->getNumLinks() + 6;
|
||||
for (int i = 0; i < ndofA; ++i)
|
||||
deltaVelADotn += m_data.m_jacobians[c.m_jacAindex+i] * m_data.m_deltaVelocities[c.m_deltaVelAindex+i];
|
||||
} else
|
||||
{
|
||||
bodyA = &m_tmpSolverBodyPool[c.m_solverBodyIdA];
|
||||
deltaVelADotn += c.m_contactNormal1.dot(bodyA->internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(bodyA->internalGetDeltaAngularVelocity());
|
||||
}
|
||||
|
||||
if (c.m_multiBodyB)
|
||||
{
|
||||
ndofB = c.m_multiBodyB->getNumLinks() + 6;
|
||||
for (int i = 0; i < ndofB; ++i)
|
||||
deltaVelBDotn += m_data.m_jacobians[c.m_jacBindex+i] * m_data.m_deltaVelocities[c.m_deltaVelBindex+i];
|
||||
} else
|
||||
{
|
||||
bodyB = &m_tmpSolverBodyPool[c.m_solverBodyIdB];
|
||||
deltaVelBDotn += c.m_contactNormal2.dot(bodyB->internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(bodyB->internalGetDeltaAngularVelocity());
|
||||
}
|
||||
|
||||
|
||||
deltaImpulse -= deltaVelADotn*c.m_jacDiagABInv;//m_jacDiagABInv = 1./denom
|
||||
deltaImpulse -= deltaVelBDotn*c.m_jacDiagABInv;
|
||||
const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
|
||||
|
||||
if (sum < c.m_lowerLimit)
|
||||
{
|
||||
deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
|
||||
c.m_appliedImpulse = c.m_lowerLimit;
|
||||
}
|
||||
else if (sum > c.m_upperLimit)
|
||||
{
|
||||
deltaImpulse = c.m_upperLimit-c.m_appliedImpulse;
|
||||
c.m_appliedImpulse = c.m_upperLimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
c.m_appliedImpulse = sum;
|
||||
}
|
||||
|
||||
if (c.m_multiBodyA)
|
||||
{
|
||||
applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],deltaImpulse,c.m_deltaVelAindex,ndofA);
|
||||
c.m_multiBodyA->applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],deltaImpulse);
|
||||
} else
|
||||
{
|
||||
bodyA->internalApplyImpulse(c.m_contactNormal1*bodyA->internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
|
||||
|
||||
}
|
||||
if (c.m_multiBodyB)
|
||||
{
|
||||
applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],deltaImpulse,c.m_deltaVelBindex,ndofB);
|
||||
c.m_multiBodyB->applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],deltaImpulse);
|
||||
} else
|
||||
{
|
||||
bodyB->internalApplyImpulse(c.m_contactNormal2*bodyB->internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btMultiBodyConstraintSolver::resolveSingleConstraintRowGenericMultiBody(const btMultiBodySolverConstraint& c)
|
||||
{
|
||||
|
||||
btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
|
||||
btScalar deltaVelADotn=0;
|
||||
btScalar deltaVelBDotn=0;
|
||||
int ndofA=0;
|
||||
int ndofB=0;
|
||||
|
||||
if (c.m_multiBodyA)
|
||||
{
|
||||
ndofA = c.m_multiBodyA->getNumLinks() + 6;
|
||||
for (int i = 0; i < ndofA; ++i)
|
||||
deltaVelADotn += m_data.m_jacobians[c.m_jacAindex+i] * m_data.m_deltaVelocities[c.m_deltaVelAindex+i];
|
||||
}
|
||||
|
||||
if (c.m_multiBodyB)
|
||||
{
|
||||
ndofB = c.m_multiBodyB->getNumLinks() + 6;
|
||||
for (int i = 0; i < ndofB; ++i)
|
||||
deltaVelBDotn += m_data.m_jacobians[c.m_jacBindex+i] * m_data.m_deltaVelocities[c.m_deltaVelBindex+i];
|
||||
}
|
||||
|
||||
|
||||
deltaImpulse -= deltaVelADotn*c.m_jacDiagABInv;//m_jacDiagABInv = 1./denom
|
||||
deltaImpulse -= deltaVelBDotn*c.m_jacDiagABInv;
|
||||
const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
|
||||
|
||||
if (sum < c.m_lowerLimit)
|
||||
{
|
||||
deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
|
||||
c.m_appliedImpulse = c.m_lowerLimit;
|
||||
}
|
||||
else if (sum > c.m_upperLimit)
|
||||
{
|
||||
deltaImpulse = c.m_upperLimit-c.m_appliedImpulse;
|
||||
c.m_appliedImpulse = c.m_upperLimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
c.m_appliedImpulse = sum;
|
||||
}
|
||||
|
||||
if (c.m_multiBodyA)
|
||||
{
|
||||
applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],deltaImpulse,c.m_deltaVelAindex,ndofA);
|
||||
c.m_multiBodyA->applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],deltaImpulse);
|
||||
}
|
||||
if (c.m_multiBodyB)
|
||||
{
|
||||
applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],deltaImpulse,c.m_deltaVelBindex,ndofB);
|
||||
c.m_multiBodyB->applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],deltaImpulse);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySolverConstraint& solverConstraint,
|
||||
const btVector3& contactNormal,
|
||||
btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
|
||||
btScalar& relaxation,
|
||||
bool isFriction, btScalar desiredVelocity, btScalar cfmSlip)
|
||||
{
|
||||
|
||||
BT_PROFILE("setupMultiBodyContactConstraint");
|
||||
btVector3 rel_pos1;
|
||||
btVector3 rel_pos2;
|
||||
|
||||
btMultiBody* multiBodyA = solverConstraint.m_multiBodyA;
|
||||
btMultiBody* multiBodyB = solverConstraint.m_multiBodyB;
|
||||
|
||||
const btVector3& pos1 = cp.getPositionWorldOnA();
|
||||
const btVector3& pos2 = cp.getPositionWorldOnB();
|
||||
|
||||
btSolverBody* bodyA = multiBodyA ? 0 : &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA];
|
||||
btSolverBody* bodyB = multiBodyB ? 0 : &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB];
|
||||
|
||||
btRigidBody* rb0 = multiBodyA ? 0 : bodyA->m_originalBody;
|
||||
btRigidBody* rb1 = multiBodyB ? 0 : bodyB->m_originalBody;
|
||||
|
||||
if (bodyA)
|
||||
rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin();
|
||||
if (bodyB)
|
||||
rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin();
|
||||
|
||||
relaxation = 1.f;
|
||||
|
||||
if (multiBodyA)
|
||||
{
|
||||
const int ndofA = multiBodyA->getNumLinks() + 6;
|
||||
|
||||
solverConstraint.m_deltaVelAindex = multiBodyA->getCompanionId();
|
||||
|
||||
if (solverConstraint.m_deltaVelAindex <0)
|
||||
{
|
||||
solverConstraint.m_deltaVelAindex = m_data.m_deltaVelocities.size();
|
||||
multiBodyA->setCompanionId(solverConstraint.m_deltaVelAindex);
|
||||
m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size()+ndofA);
|
||||
} else
|
||||
{
|
||||
btAssert(m_data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex+ndofA);
|
||||
}
|
||||
|
||||
solverConstraint.m_jacAindex = m_data.m_jacobians.size();
|
||||
m_data.m_jacobians.resize(m_data.m_jacobians.size()+ndofA);
|
||||
m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size()+ndofA);
|
||||
btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size());
|
||||
|
||||
btScalar* jac1=&m_data.m_jacobians[solverConstraint.m_jacAindex];
|
||||
multiBodyA->fillContactJacobian(solverConstraint.m_linkA, cp.getPositionWorldOnA(), contactNormal, jac1, m_data.scratch_r, m_data.scratch_v, m_data.scratch_m);
|
||||
btScalar* delta = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
|
||||
multiBodyA->calcAccelerationDeltas(&m_data.m_jacobians[solverConstraint.m_jacAindex],delta,m_data.scratch_r, m_data.scratch_v);
|
||||
} else
|
||||
{
|
||||
btVector3 torqueAxis0 = rel_pos1.cross(contactNormal);
|
||||
solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0);
|
||||
solverConstraint.m_relpos1CrossNormal = torqueAxis0;
|
||||
solverConstraint.m_contactNormal1 = contactNormal;
|
||||
}
|
||||
|
||||
if (multiBodyB)
|
||||
{
|
||||
const int ndofB = multiBodyB->getNumLinks() + 6;
|
||||
|
||||
solverConstraint.m_deltaVelBindex = multiBodyB->getCompanionId();
|
||||
if (solverConstraint.m_deltaVelBindex <0)
|
||||
{
|
||||
solverConstraint.m_deltaVelBindex = m_data.m_deltaVelocities.size();
|
||||
multiBodyB->setCompanionId(solverConstraint.m_deltaVelBindex);
|
||||
m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size()+ndofB);
|
||||
}
|
||||
|
||||
solverConstraint.m_jacBindex = m_data.m_jacobians.size();
|
||||
|
||||
m_data.m_jacobians.resize(m_data.m_jacobians.size()+ndofB);
|
||||
m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size()+ndofB);
|
||||
btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size());
|
||||
|
||||
multiBodyB->fillContactJacobian(solverConstraint.m_linkB, cp.getPositionWorldOnB(), -contactNormal, &m_data.m_jacobians[solverConstraint.m_jacBindex], m_data.scratch_r, m_data.scratch_v, m_data.scratch_m);
|
||||
multiBodyB->calcAccelerationDeltas(&m_data.m_jacobians[solverConstraint.m_jacBindex],&m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex],m_data.scratch_r, m_data.scratch_v);
|
||||
} else
|
||||
{
|
||||
btVector3 torqueAxis1 = rel_pos2.cross(contactNormal);
|
||||
solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0);
|
||||
solverConstraint.m_relpos2CrossNormal = -torqueAxis1;
|
||||
solverConstraint.m_contactNormal2 = -contactNormal;
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
btVector3 vec;
|
||||
btScalar denom0 = 0.f;
|
||||
btScalar denom1 = 0.f;
|
||||
btScalar* jacB = 0;
|
||||
btScalar* jacA = 0;
|
||||
btScalar* lambdaA =0;
|
||||
btScalar* lambdaB =0;
|
||||
int ndofA = 0;
|
||||
if (multiBodyA)
|
||||
{
|
||||
ndofA = multiBodyA->getNumLinks() + 6;
|
||||
jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex];
|
||||
lambdaA = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
|
||||
for (int i = 0; i < ndofA; ++i)
|
||||
{
|
||||
btScalar j = jacA[i] ;
|
||||
btScalar l =lambdaA[i];
|
||||
denom0 += j*l;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (rb0)
|
||||
{
|
||||
vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
|
||||
denom0 = rb0->getInvMass() + contactNormal.dot(vec);
|
||||
}
|
||||
}
|
||||
if (multiBodyB)
|
||||
{
|
||||
const int ndofB = multiBodyB->getNumLinks() + 6;
|
||||
jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex];
|
||||
lambdaB = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex];
|
||||
for (int i = 0; i < ndofB; ++i)
|
||||
{
|
||||
btScalar j = jacB[i] ;
|
||||
btScalar l =lambdaB[i];
|
||||
denom1 += j*l;
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
if (rb1)
|
||||
{
|
||||
vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
|
||||
denom1 = rb1->getInvMass() + contactNormal.dot(vec);
|
||||
}
|
||||
}
|
||||
|
||||
if (multiBodyA && (multiBodyA==multiBodyB))
|
||||
{
|
||||
// ndof1 == ndof2 in this case
|
||||
for (int i = 0; i < ndofA; ++i)
|
||||
{
|
||||
denom1 += jacB[i] * lambdaA[i];
|
||||
denom1 += jacA[i] * lambdaB[i];
|
||||
}
|
||||
}
|
||||
|
||||
btScalar d = denom0+denom1;
|
||||
if (btFabs(d)>SIMD_EPSILON)
|
||||
{
|
||||
|
||||
solverConstraint.m_jacDiagABInv = relaxation/(d);
|
||||
} else
|
||||
{
|
||||
solverConstraint.m_jacDiagABInv = 1.f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//compute rhs and remaining solverConstraint fields
|
||||
|
||||
|
||||
|
||||
btScalar restitution = 0.f;
|
||||
btScalar penetration = isFriction? 0 : cp.getDistance()+infoGlobal.m_linearSlop;
|
||||
|
||||
btScalar rel_vel = 0.f;
|
||||
int ndofA = 0;
|
||||
int ndofB = 0;
|
||||
{
|
||||
|
||||
btVector3 vel1,vel2;
|
||||
if (multiBodyA)
|
||||
{
|
||||
ndofA = multiBodyA->getNumLinks() + 6;
|
||||
btScalar* jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex];
|
||||
for (int i = 0; i < ndofA ; ++i)
|
||||
rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i];
|
||||
} else
|
||||
{
|
||||
if (rb0)
|
||||
{
|
||||
rel_vel += rb0->getVelocityInLocalPoint(rel_pos1).dot(solverConstraint.m_contactNormal1);
|
||||
}
|
||||
}
|
||||
if (multiBodyB)
|
||||
{
|
||||
ndofB = multiBodyB->getNumLinks() + 6;
|
||||
btScalar* jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex];
|
||||
for (int i = 0; i < ndofB ; ++i)
|
||||
rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i];
|
||||
|
||||
} else
|
||||
{
|
||||
if (rb1)
|
||||
{
|
||||
rel_vel += rb1->getVelocityInLocalPoint(rel_pos2).dot(solverConstraint.m_contactNormal2);
|
||||
}
|
||||
}
|
||||
|
||||
solverConstraint.m_friction = cp.m_combinedFriction;
|
||||
|
||||
|
||||
restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution);
|
||||
if (restitution <= btScalar(0.))
|
||||
{
|
||||
restitution = 0.f;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///warm starting (or zero if disabled)
|
||||
if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
|
||||
{
|
||||
solverConstraint.m_appliedImpulse = isFriction ? 0 : cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
|
||||
|
||||
if (solverConstraint.m_appliedImpulse)
|
||||
{
|
||||
if (multiBodyA)
|
||||
{
|
||||
btScalar impulse = solverConstraint.m_appliedImpulse;
|
||||
btScalar* deltaV = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex];
|
||||
multiBodyA->applyDeltaVee(deltaV,impulse);
|
||||
applyDeltaVee(deltaV,impulse,solverConstraint.m_deltaVelAindex,ndofA);
|
||||
} else
|
||||
{
|
||||
if (rb0)
|
||||
bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1*bodyA->internalGetInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
|
||||
}
|
||||
if (multiBodyB)
|
||||
{
|
||||
btScalar impulse = solverConstraint.m_appliedImpulse;
|
||||
btScalar* deltaV = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex];
|
||||
multiBodyB->applyDeltaVee(deltaV,impulse);
|
||||
applyDeltaVee(deltaV,impulse,solverConstraint.m_deltaVelBindex,ndofB);
|
||||
} else
|
||||
{
|
||||
if (rb1)
|
||||
bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2*bodyB->internalGetInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
solverConstraint.m_appliedImpulse = 0.f;
|
||||
}
|
||||
|
||||
solverConstraint.m_appliedPushImpulse = 0.f;
|
||||
|
||||
{
|
||||
|
||||
|
||||
btScalar positionalError = 0.f;
|
||||
btScalar velocityError = restitution - rel_vel;// * damping;
|
||||
|
||||
|
||||
btScalar erp = infoGlobal.m_erp2;
|
||||
if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
|
||||
{
|
||||
erp = infoGlobal.m_erp;
|
||||
}
|
||||
|
||||
if (penetration>0)
|
||||
{
|
||||
positionalError = 0;
|
||||
velocityError = -penetration / infoGlobal.m_timeStep;
|
||||
|
||||
} else
|
||||
{
|
||||
positionalError = -penetration * erp/infoGlobal.m_timeStep;
|
||||
}
|
||||
|
||||
btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
|
||||
btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
|
||||
|
||||
if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
|
||||
{
|
||||
//combine position and velocity into rhs
|
||||
solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
|
||||
solverConstraint.m_rhsPenetration = 0.f;
|
||||
|
||||
} else
|
||||
{
|
||||
//split position and velocity into rhs and m_rhsPenetration
|
||||
solverConstraint.m_rhs = velocityImpulse;
|
||||
solverConstraint.m_rhsPenetration = penetrationImpulse;
|
||||
}
|
||||
|
||||
solverConstraint.m_cfm = 0.f;
|
||||
solverConstraint.m_lowerLimit = 0;
|
||||
solverConstraint.m_upperLimit = 1e10f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyFrictionConstraint(const btVector3& normalAxis,btPersistentManifold* manifold,int frictionIndex,btManifoldPoint& cp,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
|
||||
{
|
||||
BT_PROFILE("addMultiBodyFrictionConstraint");
|
||||
btMultiBodySolverConstraint& solverConstraint = m_multiBodyFrictionContactConstraints.expandNonInitializing();
|
||||
solverConstraint.m_frictionIndex = frictionIndex;
|
||||
bool isFriction = true;
|
||||
|
||||
const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
|
||||
const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
|
||||
|
||||
btMultiBody* mbA = fcA? fcA->m_multiBody : 0;
|
||||
btMultiBody* mbB = fcB? fcB->m_multiBody : 0;
|
||||
|
||||
int solverBodyIdA = mbA? -1 : getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep);
|
||||
int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep);
|
||||
|
||||
solverConstraint.m_solverBodyIdA = solverBodyIdA;
|
||||
solverConstraint.m_solverBodyIdB = solverBodyIdB;
|
||||
solverConstraint.m_multiBodyA = mbA;
|
||||
if (mbA)
|
||||
solverConstraint.m_linkA = fcA->m_link;
|
||||
|
||||
solverConstraint.m_multiBodyB = mbB;
|
||||
if (mbB)
|
||||
solverConstraint.m_linkB = fcB->m_link;
|
||||
|
||||
solverConstraint.m_originalContactPoint = &cp;
|
||||
|
||||
setupMultiBodyContactConstraint(solverConstraint, normalAxis, cp, infoGlobal,relaxation,isFriction, desiredVelocity, cfmSlip);
|
||||
return solverConstraint;
|
||||
}
|
||||
|
||||
void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal)
|
||||
{
|
||||
const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
|
||||
const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
|
||||
|
||||
btMultiBody* mbA = fcA? fcA->m_multiBody : 0;
|
||||
btMultiBody* mbB = fcB? fcB->m_multiBody : 0;
|
||||
|
||||
btCollisionObject* colObj0=0,*colObj1=0;
|
||||
|
||||
colObj0 = (btCollisionObject*)manifold->getBody0();
|
||||
colObj1 = (btCollisionObject*)manifold->getBody1();
|
||||
|
||||
int solverBodyIdA = mbA? -1 : getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep);
|
||||
int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep);
|
||||
|
||||
btSolverBody* solverBodyA = mbA ? 0 : &m_tmpSolverBodyPool[solverBodyIdA];
|
||||
btSolverBody* solverBodyB = mbB ? 0 : &m_tmpSolverBodyPool[solverBodyIdB];
|
||||
|
||||
|
||||
///avoid collision response between two static objects
|
||||
// if (!solverBodyA || (solverBodyA->m_invMass.isZero() && (!solverBodyB || solverBodyB->m_invMass.isZero())))
|
||||
// return;
|
||||
|
||||
int rollingFriction=1;
|
||||
|
||||
for (int j=0;j<manifold->getNumContacts();j++)
|
||||
{
|
||||
|
||||
btManifoldPoint& cp = manifold->getContactPoint(j);
|
||||
|
||||
if (cp.getDistance() <= manifold->getContactProcessingThreshold())
|
||||
{
|
||||
|
||||
btScalar relaxation;
|
||||
|
||||
int frictionIndex = m_multiBodyNormalContactConstraints.size();
|
||||
|
||||
btMultiBodySolverConstraint& solverConstraint = m_multiBodyNormalContactConstraints.expandNonInitializing();
|
||||
|
||||
btRigidBody* rb0 = btRigidBody::upcast(colObj0);
|
||||
btRigidBody* rb1 = btRigidBody::upcast(colObj1);
|
||||
solverConstraint.m_solverBodyIdA = solverBodyIdA;
|
||||
solverConstraint.m_solverBodyIdB = solverBodyIdB;
|
||||
solverConstraint.m_multiBodyA = mbA;
|
||||
if (mbA)
|
||||
solverConstraint.m_linkA = fcA->m_link;
|
||||
|
||||
solverConstraint.m_multiBodyB = mbB;
|
||||
if (mbB)
|
||||
solverConstraint.m_linkB = fcB->m_link;
|
||||
|
||||
solverConstraint.m_originalContactPoint = &cp;
|
||||
|
||||
bool isFriction = false;
|
||||
setupMultiBodyContactConstraint(solverConstraint, cp.m_normalWorldOnB,cp, infoGlobal, relaxation, isFriction);
|
||||
|
||||
// const btVector3& pos1 = cp.getPositionWorldOnA();
|
||||
// const btVector3& pos2 = cp.getPositionWorldOnB();
|
||||
|
||||
/////setup the friction constraints
|
||||
#define ENABLE_FRICTION
|
||||
#ifdef ENABLE_FRICTION
|
||||
solverConstraint.m_frictionIndex = frictionIndex;
|
||||
#if ROLLING_FRICTION
|
||||
btVector3 angVelA(0,0,0),angVelB(0,0,0);
|
||||
if (rb0)
|
||||
angVelA = rb0->getAngularVelocity();
|
||||
if (rb1)
|
||||
angVelB = rb1->getAngularVelocity();
|
||||
btVector3 relAngVel = angVelB-angVelA;
|
||||
|
||||
if ((cp.m_combinedRollingFriction>0.f) && (rollingFriction>0))
|
||||
{
|
||||
//only a single rollingFriction per manifold
|
||||
rollingFriction--;
|
||||
if (relAngVel.length()>infoGlobal.m_singleAxisRollingFrictionThreshold)
|
||||
{
|
||||
relAngVel.normalize();
|
||||
applyAnisotropicFriction(colObj0,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
|
||||
if (relAngVel.length()>0.001)
|
||||
addRollingFrictionConstraint(relAngVel,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
} else
|
||||
{
|
||||
addRollingFrictionConstraint(cp.m_normalWorldOnB,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
btVector3 axis0,axis1;
|
||||
btPlaneSpace1(cp.m_normalWorldOnB,axis0,axis1);
|
||||
applyAnisotropicFriction(colObj0,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
|
||||
applyAnisotropicFriction(colObj0,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
|
||||
if (axis0.length()>0.001)
|
||||
addRollingFrictionConstraint(axis0,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
if (axis1.length()>0.001)
|
||||
addRollingFrictionConstraint(axis1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
}
|
||||
}
|
||||
#endif //ROLLING_FRICTION
|
||||
|
||||
///Bullet has several options to set the friction directions
|
||||
///By default, each contact has only a single friction direction that is recomputed automatically very frame
|
||||
///based on the relative linear velocity.
|
||||
///If the relative velocity it zero, it will automatically compute a friction direction.
|
||||
|
||||
///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS.
|
||||
///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction.
|
||||
///
|
||||
///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity.
|
||||
///
|
||||
///The user can manually override the friction directions for certain contacts using a contact callback,
|
||||
///and set the cp.m_lateralFrictionInitialized to true
|
||||
///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2)
|
||||
///this will give a conveyor belt effect
|
||||
///
|
||||
if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !cp.m_lateralFrictionInitialized)
|
||||
{/*
|
||||
cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
|
||||
btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
|
||||
if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON)
|
||||
{
|
||||
cp.m_lateralFrictionDir1 *= 1.f/btSqrt(lat_rel_vel);
|
||||
if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
|
||||
{
|
||||
cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
|
||||
cp.m_lateralFrictionDir2.normalize();//??
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
}
|
||||
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
|
||||
|
||||
} else
|
||||
*/
|
||||
{
|
||||
btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
|
||||
|
||||
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
|
||||
{
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal);
|
||||
}
|
||||
|
||||
applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
|
||||
addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal);
|
||||
|
||||
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION))
|
||||
{
|
||||
cp.m_lateralFrictionInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal,cp.m_contactMotion1, cp.m_contactCFM1);
|
||||
|
||||
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
|
||||
addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2,manifold,frictionIndex,cp,colObj0,colObj1, relaxation, infoGlobal,cp.m_contactMotion2, cp.m_contactCFM2);
|
||||
|
||||
//setMultiBodyFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
|
||||
//todo:
|
||||
solverConstraint.m_appliedImpulse = 0.f;
|
||||
solverConstraint.m_appliedPushImpulse = 0.f;
|
||||
}
|
||||
|
||||
|
||||
#endif //ENABLE_FRICTION
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void btMultiBodyConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr,int numManifolds, const btContactSolverInfo& infoGlobal)
|
||||
{
|
||||
btPersistentManifold* manifold = 0;
|
||||
|
||||
for (int i=0;i<numManifolds;i++)
|
||||
{
|
||||
btPersistentManifold* manifold= manifoldPtr[i];
|
||||
const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
|
||||
const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
|
||||
if (!fcA && !fcB)
|
||||
{
|
||||
//the contact doesn't involve any Featherstone btMultiBody, so deal with the regular btRigidBody/btCollisionObject case
|
||||
convertContact(manifold,infoGlobal);
|
||||
} else
|
||||
{
|
||||
convertMultiBodyContact(manifold,infoGlobal);
|
||||
}
|
||||
}
|
||||
|
||||
//also convert the multibody constraints, if any
|
||||
|
||||
|
||||
for (int i=0;i<m_tmpNumMultiBodyConstraints;i++)
|
||||
{
|
||||
btMultiBodyConstraint* c = m_tmpMultiBodyConstraints[i];
|
||||
m_data.m_solverBodyPool = &m_tmpSolverBodyPool;
|
||||
m_data.m_fixedBodyId = m_fixedBodyId;
|
||||
|
||||
c->createConstraintRows(m_multiBodyNonContactConstraints,m_data, infoGlobal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
btScalar btMultiBodyConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher)
|
||||
{
|
||||
return btSequentialImpulseConstraintSolver::solveGroup(bodies,numBodies,manifold,numManifolds,constraints,numConstraints,info,debugDrawer,dispatcher);
|
||||
}
|
||||
|
||||
|
||||
void btMultiBodyConstraintSolver::solveMultiBodyGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher)
|
||||
{
|
||||
//printf("solveMultiBodyGroup start\n");
|
||||
m_tmpMultiBodyConstraints = multiBodyConstraints;
|
||||
m_tmpNumMultiBodyConstraints = numMultiBodyConstraints;
|
||||
|
||||
btSequentialImpulseConstraintSolver::solveGroup(bodies,numBodies,manifold,numManifolds,constraints,numConstraints,info,debugDrawer,dispatcher);
|
||||
|
||||
m_tmpMultiBodyConstraints = 0;
|
||||
m_tmpNumMultiBodyConstraints = 0;
|
||||
|
||||
|
||||
}
|
85
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
vendored
Normal file
85
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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_MULTIBODY_CONSTRAINT_SOLVER_H
|
||||
#define BT_MULTIBODY_CONSTRAINT_SOLVER_H
|
||||
|
||||
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
|
||||
#include "btMultiBodySolverConstraint.h"
|
||||
|
||||
|
||||
class btMultiBody;
|
||||
|
||||
#include "btMultiBodyConstraint.h"
|
||||
|
||||
|
||||
|
||||
ATTRIBUTE_ALIGNED16(class) btMultiBodyConstraintSolver : public btSequentialImpulseConstraintSolver
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
btMultiBodyConstraintArray m_multiBodyNonContactConstraints;
|
||||
|
||||
btMultiBodyConstraintArray m_multiBodyNormalContactConstraints;
|
||||
btMultiBodyConstraintArray m_multiBodyFrictionContactConstraints;
|
||||
|
||||
btMultiBodyJacobianData m_data;
|
||||
|
||||
//temp storage for multi body constraints for a specific island/group called by 'solveGroup'
|
||||
btMultiBodyConstraint** m_tmpMultiBodyConstraints;
|
||||
int m_tmpNumMultiBodyConstraints;
|
||||
|
||||
void resolveSingleConstraintRowGeneric(const btMultiBodySolverConstraint& c);
|
||||
void resolveSingleConstraintRowGenericMultiBody(const btMultiBodySolverConstraint& c);
|
||||
|
||||
void convertContacts(btPersistentManifold** manifoldPtr,int numManifolds, const btContactSolverInfo& infoGlobal);
|
||||
btMultiBodySolverConstraint& addMultiBodyFrictionConstraint(const btVector3& normalAxis,btPersistentManifold* manifold,int frictionIndex,btManifoldPoint& cp,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity=0, btScalar cfmSlip=0);
|
||||
|
||||
|
||||
void setupMultiBodyJointLimitConstraint(btMultiBodySolverConstraint& constraintRow,
|
||||
btScalar* jacA,btScalar* jacB,
|
||||
btScalar penetration,btScalar combinedFrictionCoeff, btScalar combinedRestitutionCoeff,
|
||||
const btContactSolverInfo& infoGlobal);
|
||||
|
||||
void setupMultiBodyContactConstraint(btMultiBodySolverConstraint& solverConstraint,
|
||||
const btVector3& contactNormal,
|
||||
btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
|
||||
btScalar& relaxation,
|
||||
bool isFriction, btScalar desiredVelocity=0, btScalar cfmSlip=0);
|
||||
|
||||
void convertMultiBodyContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal);
|
||||
virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
|
||||
// virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
|
||||
|
||||
virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer);
|
||||
void applyDeltaVee(btScalar* deltaV, btScalar impulse, int velocityIndex, int ndof);
|
||||
|
||||
public:
|
||||
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
///this method should not be called, it was just used during porting/integration of Featherstone btMultiBody, providing backwards compatibility but no support for btMultiBodyConstraint (only contact constraints)
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher);
|
||||
|
||||
virtual void solveMultiBodyGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //BT_MULTIBODY_CONSTRAINT_SOLVER_H
|
||||
|
578
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp
vendored
Normal file
578
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp
vendored
Normal file
@@ -0,0 +1,578 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#include "btMultiBodyDynamicsWorld.h"
|
||||
#include "btMultiBodyConstraintSolver.h"
|
||||
#include "btMultiBody.h"
|
||||
#include "btMultiBodyLinkCollider.h"
|
||||
#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
|
||||
#include "LinearMath/btQuickprof.h"
|
||||
#include "btMultiBodyConstraint.h"
|
||||
|
||||
|
||||
|
||||
|
||||
void btMultiBodyDynamicsWorld::addMultiBody(btMultiBody* body, short group, short mask)
|
||||
{
|
||||
m_multiBodies.push_back(body);
|
||||
|
||||
}
|
||||
|
||||
void btMultiBodyDynamicsWorld::removeMultiBody(btMultiBody* body)
|
||||
{
|
||||
m_multiBodies.remove(body);
|
||||
}
|
||||
|
||||
void btMultiBodyDynamicsWorld::calculateSimulationIslands()
|
||||
{
|
||||
BT_PROFILE("calculateSimulationIslands");
|
||||
|
||||
getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher());
|
||||
|
||||
{
|
||||
//merge islands based on speculative contact manifolds too
|
||||
for (int i=0;i<this->m_predictiveManifolds.size();i++)
|
||||
{
|
||||
btPersistentManifold* manifold = m_predictiveManifolds[i];
|
||||
|
||||
const btCollisionObject* colObj0 = manifold->getBody0();
|
||||
const btCollisionObject* colObj1 = manifold->getBody1();
|
||||
|
||||
if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
|
||||
((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
|
||||
{
|
||||
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
int numConstraints = int(m_constraints.size());
|
||||
for (i=0;i< numConstraints ; i++ )
|
||||
{
|
||||
btTypedConstraint* constraint = m_constraints[i];
|
||||
if (constraint->isEnabled())
|
||||
{
|
||||
const btRigidBody* colObj0 = &constraint->getRigidBodyA();
|
||||
const btRigidBody* colObj1 = &constraint->getRigidBodyB();
|
||||
|
||||
if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
|
||||
((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
|
||||
{
|
||||
getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//merge islands linked by Featherstone link colliders
|
||||
for (int i=0;i<m_multiBodies.size();i++)
|
||||
{
|
||||
btMultiBody* body = m_multiBodies[i];
|
||||
{
|
||||
btMultiBodyLinkCollider* prev = body->getBaseCollider();
|
||||
|
||||
for (int b=0;b<body->getNumLinks();b++)
|
||||
{
|
||||
btMultiBodyLinkCollider* cur = body->getLink(b).m_collider;
|
||||
|
||||
if (((cur) && (!(cur)->isStaticOrKinematicObject())) &&
|
||||
((prev) && (!(prev)->isStaticOrKinematicObject())))
|
||||
{
|
||||
int tagPrev = prev->getIslandTag();
|
||||
int tagCur = cur->getIslandTag();
|
||||
getSimulationIslandManager()->getUnionFind().unite(tagPrev, tagCur);
|
||||
}
|
||||
if (cur && !cur->isStaticOrKinematicObject())
|
||||
prev = cur;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//merge islands linked by multibody constraints
|
||||
{
|
||||
for (int i=0;i<this->m_multiBodyConstraints.size();i++)
|
||||
{
|
||||
btMultiBodyConstraint* c = m_multiBodyConstraints[i];
|
||||
int tagA = c->getIslandIdA();
|
||||
int tagB = c->getIslandIdB();
|
||||
if (tagA>=0 && tagB>=0)
|
||||
getSimulationIslandManager()->getUnionFind().unite(tagA, tagB);
|
||||
}
|
||||
}
|
||||
|
||||
//Store the island id in each body
|
||||
getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld());
|
||||
|
||||
}
|
||||
|
||||
|
||||
void btMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep)
|
||||
{
|
||||
BT_PROFILE("btMultiBodyDynamicsWorld::updateActivationState");
|
||||
|
||||
|
||||
|
||||
for ( int i=0;i<m_multiBodies.size();i++)
|
||||
{
|
||||
btMultiBody* body = m_multiBodies[i];
|
||||
if (body)
|
||||
{
|
||||
body->checkMotionAndSleepIfRequired(timeStep);
|
||||
if (!body->isAwake())
|
||||
{
|
||||
btMultiBodyLinkCollider* col = body->getBaseCollider();
|
||||
if (col && col->getActivationState() == ACTIVE_TAG)
|
||||
{
|
||||
col->setActivationState( WANTS_DEACTIVATION);
|
||||
col->setDeactivationTime(0.f);
|
||||
}
|
||||
for (int b=0;b<body->getNumLinks();b++)
|
||||
{
|
||||
btMultiBodyLinkCollider* col = body->getLink(b).m_collider;
|
||||
if (col && col->getActivationState() == ACTIVE_TAG)
|
||||
{
|
||||
col->setActivationState( WANTS_DEACTIVATION);
|
||||
col->setDeactivationTime(0.f);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
btMultiBodyLinkCollider* col = body->getBaseCollider();
|
||||
if (col && col->getActivationState() != DISABLE_DEACTIVATION)
|
||||
col->setActivationState( ACTIVE_TAG );
|
||||
|
||||
for (int b=0;b<body->getNumLinks();b++)
|
||||
{
|
||||
btMultiBodyLinkCollider* col = body->getLink(b).m_collider;
|
||||
if (col && col->getActivationState() != DISABLE_DEACTIVATION)
|
||||
col->setActivationState( ACTIVE_TAG );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
btDiscreteDynamicsWorld::updateActivationState(timeStep);
|
||||
}
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btGetConstraintIslandId2(const btTypedConstraint* lhs)
|
||||
{
|
||||
int islandId;
|
||||
|
||||
const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
|
||||
const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
|
||||
islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag();
|
||||
return islandId;
|
||||
|
||||
}
|
||||
|
||||
|
||||
class btSortConstraintOnIslandPredicate2
|
||||
{
|
||||
public:
|
||||
|
||||
bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) const
|
||||
{
|
||||
int rIslandId0,lIslandId0;
|
||||
rIslandId0 = btGetConstraintIslandId2(rhs);
|
||||
lIslandId0 = btGetConstraintIslandId2(lhs);
|
||||
return lIslandId0 < rIslandId0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
SIMD_FORCE_INLINE int btGetMultiBodyConstraintIslandId(const btMultiBodyConstraint* lhs)
|
||||
{
|
||||
int islandId;
|
||||
|
||||
int islandTagA = lhs->getIslandIdA();
|
||||
int islandTagB = lhs->getIslandIdB();
|
||||
islandId= islandTagA>=0?islandTagA:islandTagB;
|
||||
return islandId;
|
||||
|
||||
}
|
||||
|
||||
|
||||
class btSortMultiBodyConstraintOnIslandPredicate
|
||||
{
|
||||
public:
|
||||
|
||||
bool operator() ( const btMultiBodyConstraint* lhs, const btMultiBodyConstraint* rhs ) const
|
||||
{
|
||||
int rIslandId0,lIslandId0;
|
||||
rIslandId0 = btGetMultiBodyConstraintIslandId(rhs);
|
||||
lIslandId0 = btGetMultiBodyConstraintIslandId(lhs);
|
||||
return lIslandId0 < rIslandId0;
|
||||
}
|
||||
};
|
||||
|
||||
struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
|
||||
{
|
||||
btContactSolverInfo* m_solverInfo;
|
||||
btMultiBodyConstraintSolver* m_solver;
|
||||
btMultiBodyConstraint** m_multiBodySortedConstraints;
|
||||
int m_numMultiBodyConstraints;
|
||||
|
||||
btTypedConstraint** m_sortedConstraints;
|
||||
int m_numConstraints;
|
||||
btIDebugDraw* m_debugDrawer;
|
||||
btDispatcher* m_dispatcher;
|
||||
|
||||
btAlignedObjectArray<btCollisionObject*> m_bodies;
|
||||
btAlignedObjectArray<btPersistentManifold*> m_manifolds;
|
||||
btAlignedObjectArray<btTypedConstraint*> m_constraints;
|
||||
btAlignedObjectArray<btMultiBodyConstraint*> m_multiBodyConstraints;
|
||||
|
||||
|
||||
MultiBodyInplaceSolverIslandCallback( btMultiBodyConstraintSolver* solver,
|
||||
btDispatcher* dispatcher)
|
||||
:m_solverInfo(NULL),
|
||||
m_solver(solver),
|
||||
m_multiBodySortedConstraints(NULL),
|
||||
m_numConstraints(0),
|
||||
m_debugDrawer(NULL),
|
||||
m_dispatcher(dispatcher)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MultiBodyInplaceSolverIslandCallback& operator=(MultiBodyInplaceSolverIslandCallback& other)
|
||||
{
|
||||
btAssert(0);
|
||||
(void)other;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SIMD_FORCE_INLINE void setup ( btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btMultiBodyConstraint** sortedMultiBodyConstraints, int numMultiBodyConstraints, btIDebugDraw* debugDrawer)
|
||||
{
|
||||
btAssert(solverInfo);
|
||||
m_solverInfo = solverInfo;
|
||||
|
||||
m_multiBodySortedConstraints = sortedMultiBodyConstraints;
|
||||
m_numMultiBodyConstraints = numMultiBodyConstraints;
|
||||
m_sortedConstraints = sortedConstraints;
|
||||
m_numConstraints = numConstraints;
|
||||
|
||||
m_debugDrawer = debugDrawer;
|
||||
m_bodies.resize (0);
|
||||
m_manifolds.resize (0);
|
||||
m_constraints.resize (0);
|
||||
m_multiBodyConstraints.resize(0);
|
||||
}
|
||||
|
||||
|
||||
virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId)
|
||||
{
|
||||
if (islandId<0)
|
||||
{
|
||||
///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
|
||||
m_solver->solveMultiBodyGroup( bodies,numBodies,manifolds, numManifolds,m_sortedConstraints, m_numConstraints, &m_multiBodySortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
|
||||
} else
|
||||
{
|
||||
//also add all non-contact constraints/joints for this island
|
||||
btTypedConstraint** startConstraint = 0;
|
||||
btMultiBodyConstraint** startMultiBodyConstraint = 0;
|
||||
|
||||
int numCurConstraints = 0;
|
||||
int numCurMultiBodyConstraints = 0;
|
||||
|
||||
int i;
|
||||
|
||||
//find the first constraint for this island
|
||||
|
||||
for (i=0;i<m_numConstraints;i++)
|
||||
{
|
||||
if (btGetConstraintIslandId2(m_sortedConstraints[i]) == islandId)
|
||||
{
|
||||
startConstraint = &m_sortedConstraints[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
//count the number of constraints in this island
|
||||
for (;i<m_numConstraints;i++)
|
||||
{
|
||||
if (btGetConstraintIslandId2(m_sortedConstraints[i]) == islandId)
|
||||
{
|
||||
numCurConstraints++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<m_numMultiBodyConstraints;i++)
|
||||
{
|
||||
if (btGetMultiBodyConstraintIslandId(m_multiBodySortedConstraints[i]) == islandId)
|
||||
{
|
||||
|
||||
startMultiBodyConstraint = &m_multiBodySortedConstraints[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
//count the number of multi body constraints in this island
|
||||
for (;i<m_numMultiBodyConstraints;i++)
|
||||
{
|
||||
if (btGetMultiBodyConstraintIslandId(m_multiBodySortedConstraints[i]) == islandId)
|
||||
{
|
||||
numCurMultiBodyConstraints++;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_solverInfo->m_minimumSolverBatchSize<=1)
|
||||
{
|
||||
m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
|
||||
} else
|
||||
{
|
||||
|
||||
for (i=0;i<numBodies;i++)
|
||||
m_bodies.push_back(bodies[i]);
|
||||
for (i=0;i<numManifolds;i++)
|
||||
m_manifolds.push_back(manifolds[i]);
|
||||
for (i=0;i<numCurConstraints;i++)
|
||||
m_constraints.push_back(startConstraint[i]);
|
||||
|
||||
for (i=0;i<numCurMultiBodyConstraints;i++)
|
||||
m_multiBodyConstraints.push_back(startMultiBodyConstraint[i]);
|
||||
|
||||
if ((m_constraints.size()+m_manifolds.size())>m_solverInfo->m_minimumSolverBatchSize)
|
||||
{
|
||||
processConstraints();
|
||||
} else
|
||||
{
|
||||
//printf("deferred\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void processConstraints()
|
||||
{
|
||||
|
||||
btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0;
|
||||
btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0;
|
||||
btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0;
|
||||
btMultiBodyConstraint** multiBodyConstraints = m_multiBodyConstraints.size() ? &m_multiBodyConstraints[0] : 0;
|
||||
|
||||
m_solver->solveMultiBodyGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,multiBodyConstraints, m_multiBodyConstraints.size(), *m_solverInfo,m_debugDrawer,m_dispatcher);
|
||||
m_bodies.resize(0);
|
||||
m_manifolds.resize(0);
|
||||
m_constraints.resize(0);
|
||||
m_multiBodyConstraints.resize(0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
btMultiBodyDynamicsWorld::btMultiBodyDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btMultiBodyConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
|
||||
:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration),
|
||||
m_multiBodyConstraintSolver(constraintSolver)
|
||||
{
|
||||
//split impulse is not yet supported for Featherstone hierarchies
|
||||
getSolverInfo().m_splitImpulse = false;
|
||||
getSolverInfo().m_solverMode |=SOLVER_USE_2_FRICTION_DIRECTIONS;
|
||||
m_solverMultiBodyIslandCallback = new MultiBodyInplaceSolverIslandCallback(constraintSolver,dispatcher);
|
||||
}
|
||||
|
||||
btMultiBodyDynamicsWorld::~btMultiBodyDynamicsWorld ()
|
||||
{
|
||||
delete m_solverMultiBodyIslandCallback;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
|
||||
{
|
||||
|
||||
btAlignedObjectArray<btScalar> scratch_r;
|
||||
btAlignedObjectArray<btVector3> scratch_v;
|
||||
btAlignedObjectArray<btMatrix3x3> scratch_m;
|
||||
|
||||
|
||||
BT_PROFILE("solveConstraints");
|
||||
|
||||
m_sortedConstraints.resize( m_constraints.size());
|
||||
int i;
|
||||
for (i=0;i<getNumConstraints();i++)
|
||||
{
|
||||
m_sortedConstraints[i] = m_constraints[i];
|
||||
}
|
||||
m_sortedConstraints.quickSort(btSortConstraintOnIslandPredicate2());
|
||||
btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0;
|
||||
|
||||
m_sortedMultiBodyConstraints.resize(m_multiBodyConstraints.size());
|
||||
for (i=0;i<m_multiBodyConstraints.size();i++)
|
||||
{
|
||||
m_sortedMultiBodyConstraints[i] = m_multiBodyConstraints[i];
|
||||
}
|
||||
m_sortedMultiBodyConstraints.quickSort(btSortMultiBodyConstraintOnIslandPredicate());
|
||||
|
||||
btMultiBodyConstraint** sortedMultiBodyConstraints = m_sortedMultiBodyConstraints.size() ? &m_sortedMultiBodyConstraints[0] : 0;
|
||||
|
||||
|
||||
m_solverMultiBodyIslandCallback->setup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),sortedMultiBodyConstraints,m_sortedMultiBodyConstraints.size(), getDebugDrawer());
|
||||
m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
|
||||
|
||||
/// solve all the constraints for this island
|
||||
m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),m_solverMultiBodyIslandCallback);
|
||||
|
||||
|
||||
{
|
||||
BT_PROFILE("btMultiBody addForce and stepVelocities");
|
||||
for (int i=0;i<this->m_multiBodies.size();i++)
|
||||
{
|
||||
btMultiBody* bod = m_multiBodies[i];
|
||||
|
||||
bool isSleeping = false;
|
||||
|
||||
if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING)
|
||||
{
|
||||
isSleeping = true;
|
||||
}
|
||||
for (int b=0;b<bod->getNumLinks();b++)
|
||||
{
|
||||
if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING)
|
||||
isSleeping = true;
|
||||
}
|
||||
|
||||
if (!isSleeping)
|
||||
{
|
||||
scratch_r.resize(bod->getNumLinks()+1);
|
||||
scratch_v.resize(bod->getNumLinks()+1);
|
||||
scratch_m.resize(bod->getNumLinks()+1);
|
||||
|
||||
bod->clearForcesAndTorques();
|
||||
bod->addBaseForce(m_gravity * bod->getBaseMass());
|
||||
|
||||
for (int j = 0; j < bod->getNumLinks(); ++j)
|
||||
{
|
||||
bod->addLinkForce(j, m_gravity * bod->getLinkMass(j));
|
||||
}
|
||||
|
||||
bod->stepVelocities(solverInfo.m_timeStep, scratch_r, scratch_v, scratch_m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_solverMultiBodyIslandCallback->processConstraints();
|
||||
|
||||
m_constraintSolver->allSolved(solverInfo, m_debugDrawer);
|
||||
|
||||
}
|
||||
|
||||
void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep)
|
||||
{
|
||||
btDiscreteDynamicsWorld::integrateTransforms(timeStep);
|
||||
|
||||
{
|
||||
BT_PROFILE("btMultiBody stepPositions");
|
||||
//integrate and update the Featherstone hierarchies
|
||||
btAlignedObjectArray<btQuaternion> world_to_local;
|
||||
btAlignedObjectArray<btVector3> local_origin;
|
||||
|
||||
for (int b=0;b<m_multiBodies.size();b++)
|
||||
{
|
||||
btMultiBody* bod = m_multiBodies[b];
|
||||
bool isSleeping = false;
|
||||
if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING)
|
||||
{
|
||||
isSleeping = true;
|
||||
}
|
||||
for (int b=0;b<bod->getNumLinks();b++)
|
||||
{
|
||||
if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING)
|
||||
isSleeping = true;
|
||||
}
|
||||
|
||||
|
||||
if (!isSleeping)
|
||||
{
|
||||
int nLinks = bod->getNumLinks();
|
||||
|
||||
///base + num links
|
||||
world_to_local.resize(nLinks+1);
|
||||
local_origin.resize(nLinks+1);
|
||||
|
||||
bod->stepPositions(timeStep);
|
||||
|
||||
|
||||
|
||||
world_to_local[0] = bod->getWorldToBaseRot();
|
||||
local_origin[0] = bod->getBasePos();
|
||||
|
||||
if (bod->getBaseCollider())
|
||||
{
|
||||
btVector3 posr = local_origin[0];
|
||||
float pos[4]={posr.x(),posr.y(),posr.z(),1};
|
||||
float quat[4]={-world_to_local[0].x(),-world_to_local[0].y(),-world_to_local[0].z(),world_to_local[0].w()};
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(posr);
|
||||
tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3]));
|
||||
|
||||
bod->getBaseCollider()->setWorldTransform(tr);
|
||||
|
||||
}
|
||||
|
||||
for (int k=0;k<bod->getNumLinks();k++)
|
||||
{
|
||||
const int parent = bod->getParent(k);
|
||||
world_to_local[k+1] = bod->getParentToLocalRot(k) * world_to_local[parent+1];
|
||||
local_origin[k+1] = local_origin[parent+1] + (quatRotate(world_to_local[k+1].inverse() , bod->getRVector(k)));
|
||||
}
|
||||
|
||||
|
||||
for (int m=0;m<bod->getNumLinks();m++)
|
||||
{
|
||||
btMultiBodyLinkCollider* col = bod->getLink(m).m_collider;
|
||||
if (col)
|
||||
{
|
||||
int link = col->m_link;
|
||||
btAssert(link == m);
|
||||
|
||||
int index = link+1;
|
||||
|
||||
btVector3 posr = local_origin[index];
|
||||
float pos[4]={posr.x(),posr.y(),posr.z(),1};
|
||||
float quat[4]={-world_to_local[index].x(),-world_to_local[index].y(),-world_to_local[index].z(),world_to_local[index].w()};
|
||||
btTransform tr;
|
||||
tr.setIdentity();
|
||||
tr.setOrigin(posr);
|
||||
tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3]));
|
||||
|
||||
col->setWorldTransform(tr);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
bod->clearVelocities();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btMultiBodyDynamicsWorld::addMultiBodyConstraint( btMultiBodyConstraint* constraint)
|
||||
{
|
||||
m_multiBodyConstraints.push_back(constraint);
|
||||
}
|
||||
|
||||
void btMultiBodyDynamicsWorld::removeMultiBodyConstraint( btMultiBodyConstraint* constraint)
|
||||
{
|
||||
m_multiBodyConstraints.remove(constraint);
|
||||
}
|
56
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
vendored
Normal file
56
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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_MULTIBODY_DYNAMICS_WORLD_H
|
||||
#define BT_MULTIBODY_DYNAMICS_WORLD_H
|
||||
|
||||
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
|
||||
|
||||
|
||||
class btMultiBody;
|
||||
class btMultiBodyConstraint;
|
||||
class btMultiBodyConstraintSolver;
|
||||
struct MultiBodyInplaceSolverIslandCallback;
|
||||
|
||||
///The btMultiBodyDynamicsWorld adds Featherstone multi body dynamics to Bullet
|
||||
///This implementation is still preliminary/experimental.
|
||||
class btMultiBodyDynamicsWorld : public btDiscreteDynamicsWorld
|
||||
{
|
||||
protected:
|
||||
btAlignedObjectArray<btMultiBody*> m_multiBodies;
|
||||
btAlignedObjectArray<btMultiBodyConstraint*> m_multiBodyConstraints;
|
||||
btAlignedObjectArray<btMultiBodyConstraint*> m_sortedMultiBodyConstraints;
|
||||
btMultiBodyConstraintSolver* m_multiBodyConstraintSolver;
|
||||
MultiBodyInplaceSolverIslandCallback* m_solverMultiBodyIslandCallback;
|
||||
|
||||
virtual void calculateSimulationIslands();
|
||||
virtual void updateActivationState(btScalar timeStep);
|
||||
virtual void solveConstraints(btContactSolverInfo& solverInfo);
|
||||
virtual void integrateTransforms(btScalar timeStep);
|
||||
public:
|
||||
|
||||
btMultiBodyDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btMultiBodyConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
|
||||
|
||||
virtual ~btMultiBodyDynamicsWorld ();
|
||||
|
||||
virtual void addMultiBody(btMultiBody* body, short group= btBroadphaseProxy::DefaultFilter, short mask=btBroadphaseProxy::AllFilter);
|
||||
|
||||
virtual void removeMultiBody(btMultiBody* body);
|
||||
|
||||
virtual void addMultiBodyConstraint( btMultiBodyConstraint* constraint);
|
||||
|
||||
virtual void removeMultiBodyConstraint( btMultiBodyConstraint* constraint);
|
||||
};
|
||||
#endif //BT_MULTIBODY_DYNAMICS_WORLD_H
|
133
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp
vendored
Normal file
133
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
///This file was written by Erwin Coumans
|
||||
|
||||
#include "btMultiBodyJointLimitConstraint.h"
|
||||
#include "btMultiBody.h"
|
||||
#include "btMultiBodyLinkCollider.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
|
||||
|
||||
btMultiBodyJointLimitConstraint::btMultiBodyJointLimitConstraint(btMultiBody* body, int link, btScalar lower, btScalar upper)
|
||||
:btMultiBodyConstraint(body,body,link,link,2,true),
|
||||
m_lowerBound(lower),
|
||||
m_upperBound(upper)
|
||||
{
|
||||
// the data.m_jacobians never change, so may as well
|
||||
// initialize them here
|
||||
|
||||
// note: we rely on the fact that data.m_jacobians are
|
||||
// always initialized to zero by the Constraint ctor
|
||||
|
||||
// row 0: the lower bound
|
||||
jacobianA(0)[6 + link] = 1;
|
||||
|
||||
// row 1: the upper bound
|
||||
jacobianB(1)[6 + link] = -1;
|
||||
}
|
||||
btMultiBodyJointLimitConstraint::~btMultiBodyJointLimitConstraint()
|
||||
{
|
||||
}
|
||||
|
||||
int btMultiBodyJointLimitConstraint::getIslandIdA() const
|
||||
{
|
||||
btMultiBodyLinkCollider* col = m_bodyA->getBaseCollider();
|
||||
if (col)
|
||||
return col->getIslandTag();
|
||||
for (int i=0;i<m_bodyA->getNumLinks();i++)
|
||||
{
|
||||
if (m_bodyA->getLink(i).m_collider)
|
||||
return m_bodyA->getLink(i).m_collider->getIslandTag();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int btMultiBodyJointLimitConstraint::getIslandIdB() const
|
||||
{
|
||||
btMultiBodyLinkCollider* col = m_bodyB->getBaseCollider();
|
||||
if (col)
|
||||
return col->getIslandTag();
|
||||
|
||||
for (int i=0;i<m_bodyB->getNumLinks();i++)
|
||||
{
|
||||
col = m_bodyB->getLink(i).m_collider;
|
||||
if (col)
|
||||
return col->getIslandTag();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void btMultiBodyJointLimitConstraint::createConstraintRows(btMultiBodyConstraintArray& constraintRows,
|
||||
btMultiBodyJacobianData& data,
|
||||
const btContactSolverInfo& infoGlobal)
|
||||
{
|
||||
// only positions need to be updated -- data.m_jacobians and force
|
||||
// directions were set in the ctor and never change.
|
||||
|
||||
// row 0: the lower bound
|
||||
setPosition(0, m_bodyA->getJointPos(m_linkA) - m_lowerBound);
|
||||
|
||||
// row 1: the upper bound
|
||||
setPosition(1, m_upperBound - m_bodyA->getJointPos(m_linkA));
|
||||
|
||||
for (int row=0;row<getNumRows();row++)
|
||||
{
|
||||
btMultiBodySolverConstraint& constraintRow = constraintRows.expandNonInitializing();
|
||||
constraintRow.m_multiBodyA = m_bodyA;
|
||||
constraintRow.m_multiBodyB = m_bodyB;
|
||||
|
||||
btScalar rel_vel = fillConstraintRowMultiBodyMultiBody(constraintRow,data,jacobianA(row),jacobianB(row),infoGlobal,0,-m_maxAppliedImpulse,m_maxAppliedImpulse);
|
||||
{
|
||||
btScalar penetration = getPosition(row);
|
||||
btScalar positionalError = 0.f;
|
||||
btScalar velocityError = - rel_vel;// * damping;
|
||||
btScalar erp = infoGlobal.m_erp2;
|
||||
if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
|
||||
{
|
||||
erp = infoGlobal.m_erp;
|
||||
}
|
||||
if (penetration>0)
|
||||
{
|
||||
positionalError = 0;
|
||||
velocityError = -penetration / infoGlobal.m_timeStep;
|
||||
} else
|
||||
{
|
||||
positionalError = -penetration * erp/infoGlobal.m_timeStep;
|
||||
}
|
||||
|
||||
btScalar penetrationImpulse = positionalError*constraintRow.m_jacDiagABInv;
|
||||
btScalar velocityImpulse = velocityError *constraintRow.m_jacDiagABInv;
|
||||
if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
|
||||
{
|
||||
//combine position and velocity into rhs
|
||||
constraintRow.m_rhs = penetrationImpulse+velocityImpulse;
|
||||
constraintRow.m_rhsPenetration = 0.f;
|
||||
|
||||
} else
|
||||
{
|
||||
//split position and velocity into rhs and m_rhsPenetration
|
||||
constraintRow.m_rhs = velocityImpulse;
|
||||
constraintRow.m_rhsPenetration = penetrationImpulse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
44
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h
vendored
Normal file
44
extern/bullet2/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2013 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_MULTIBODY_JOINT_LIMIT_CONSTRAINT_H
|
||||
#define BT_MULTIBODY_JOINT_LIMIT_CONSTRAINT_H
|
||||
|
||||
#include "btMultiBodyConstraint.h"
|
||||
struct btSolverInfo;
|
||||
|
||||
class btMultiBodyJointLimitConstraint : public btMultiBodyConstraint
|
||||
{
|
||||
protected:
|
||||
|
||||
btScalar m_lowerBound;
|
||||
btScalar m_upperBound;
|
||||
public:
|
||||
|
||||
btMultiBodyJointLimitConstraint(btMultiBody* body, int link, btScalar lower, btScalar upper);
|
||||
virtual ~btMultiBodyJointLimitConstraint();
|
||||
|
||||
virtual int getIslandIdA() const;
|
||||
virtual int getIslandIdB() const;
|
||||
|
||||
virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows,
|
||||
btMultiBodyJacobianData& data,
|
||||
const btContactSolverInfo& infoGlobal);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //BT_MULTIBODY_JOINT_LIMIT_CONSTRAINT_H
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user