Index: /code/branches/kicklib2/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/CMakeLists.txt	(revision 8284)
@@ -101,11 +101,28 @@
 OPTION(ORXONOX_RELEASE "Enable when building restributable releases" FALSE)
 
+IF(APPLE)
+  # Set 10.5 as the base SDK by default
+  SET(XCODE_ATTRIBUTE_SDKROOT macosx10.5)
+
+  # 10.6 sets x86_64 as the default architecture.
+  # Because Carbon isn't supported on 64-bit and we still need it, force the architectures to ppc and i386
+  IF(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
+    SET(CMAKE_OSX_ARCHITECTURES "i386")
+  ENDIF()
+  IF(CMAKE_OSX_ARCHITECTURES MATCHES "ppc64")
+    SET(CMAKE_OSX_ARCHITECTURES "ppc")
+  ENDIF()
+  IF(NOT CMAKE_OSX_ARCHITECTURES)
+    SET(CMAKE_OSX_ARCHITECTURES "i386")
+  ENDIF()
+ENDIF()
+
 ########### Subfolders and Subscripts ###########
+
+# General build and compiler options and configurations
+INCLUDE(CompilerConfig)
 
 # Library finding
 INCLUDE(LibraryConfig)
-
-# General build and compiler options and configurations
-INCLUDE(CompilerConfig)
 
 # Configure installation paths and options
Index: /code/branches/kicklib2/cmake/CompilerConfig.cmake
===================================================================
--- /code/branches/kicklib2/cmake/CompilerConfig.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/CompilerConfig.cmake	(revision 8284)
@@ -34,11 +34,2 @@
   MESSAGE(STATUS "Warning: Your compiler is not officially supported.")
 ENDIF()
-
-SET(COMPILER_CONFIG_USER_SCRIPT "" CACHE FILEPATH
-    "Specify a CMake script if you wish to write your own compiler config.
-     See CompilerConfigGCC.cmake or CompilerConfigMSVC.cmake for examples.")
-IF(COMPILER_CONFIG_USER_SCRIPT)
-  IF(EXISTS ${CMAKE_MODULE_PATH}/${COMPILER_CONFIG_USER_SCRIPT})
-    INCLUDE(${CMAKE_MODULE_PATH}/${COMPILER_CONFIG_USER_SCRIPT})
-  ENDIF()
-ENDIF(COMPILER_CONFIG_USER_SCRIPT)
Index: /code/branches/kicklib2/cmake/CompilerConfigGCC.cmake
===================================================================
--- /code/branches/kicklib2/cmake/CompilerConfigGCC.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/CompilerConfigGCC.cmake	(revision 8284)
@@ -26,4 +26,5 @@
 INCLUDE(FlagUtilities)
 INCLUDE(CompareVersionStrings)
+INCLUDE(CheckCXXCompilerFlag)
 
 # Shortcut for CMAKE_COMPILER_IS_GNUCXX and ..._GNUC
@@ -36,12 +37,4 @@
   OUTPUT_VARIABLE GCC_VERSION
 )
-
-# Complain about incompatibilities
-COMPARE_VERSION_STRINGS("${GCC_VERSION}" "4.4.0" _compare_result)
-IF(NOT _compare_result LESS 0)
-  IF(${Boost_VERSION} LESS 103700)
-    MESSAGE(STATUS "Warning: Boost versions earlier than 1.37 may not compile with GCC 4.4 or later!")
-  ENDIF()
-ENDIF()
 
 # GCC may not support #pragma GCC system_header correctly when using
@@ -72,6 +65,25 @@
 
 # CMake doesn't seem to set the PIC flags right on certain 64 bit systems
-IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
+IF(NOT MINGW AND ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
   ADD_COMPILER_FLAGS("-fPIC" CACHE)
+ENDIF()
+
+# Use SSE if possible
+# Commented because this might not work for cross compiling
+#CHECK_CXX_COMPILER_FLAG(-msse _gcc_have_sse)
+#IF(_gcc_have_sse)
+#  ADD_COMPILER_FLAGS("-msse" CACHE)
+#ENDIF()
+
+IF(NOT MINGW)
+  # Have GCC visibility?
+  CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" _gcc_have_visibility)
+  IF(_gcc_have_visibility)
+    # Note: There is a possible bug with the flag in gcc < 4.2 and Debug versions
+    COMPARE_VERSION_STRINGS("${GCC_VERSION}" "4.2.0" _compare_result)
+    IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" OR _compare_result GREATER -1)
+      ADD_COMPILER_FLAGS("-DORXONOX_GCC_VISIBILITY -fvisibility=default -fvisibility-inlines-hidden" CACHE)
+    ENDIF()
+  ENDIF(_gcc_have_visibility)
 ENDIF()
 
Index: /code/branches/kicklib2/cmake/CompilerConfigMSVC.cmake
===================================================================
--- /code/branches/kicklib2/cmake/CompilerConfigMSVC.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/CompilerConfigMSVC.cmake	(revision 8284)
@@ -60,9 +60,20 @@
 
 # Overwrite CMake default flags here for the individual configurations
-SET_COMPILER_FLAGS("-MDd -Od -Zi -D_DEBUG -RTC1" Debug          CACHE)
-SET_COMPILER_FLAGS("-MD  -O2     -DNDEBUG"       Release        CACHE)
-SET_COMPILER_FLAGS("-MD  -O2 -Zi -DNDEBUG"       RelWithDebInfo CACHE)
-SET_COMPILER_FLAGS("-MD  -O1     -DNDEBUG"       MinSizeRel     CACHE)
-ADD_COMPILER_FLAGS("-D_SECURE_SCL=0"       MSVC9 ReleaseAll     CACHE)
+SET_COMPILER_FLAGS("-MDd -Od -Oi -Zi -D_DEBUG -RTC1" Debug          CACHE)
+SET_COMPILER_FLAGS("-MD  -O2         -DNDEBUG"       Release        CACHE)
+SET_COMPILER_FLAGS("-MD  -O2     -Zi -DNDEBUG"       RelWithDebInfo CACHE)
+SET_COMPILER_FLAGS("-MD  -O1         -DNDEBUG"       MinSizeRel     CACHE)
+
+# Enable non standard floating point optimisations
+# Note: It hasn't been checked yet whether we have code that might break
+#ADD_COMPILER_FLAGS("-fp:fast" CACHE)
+
+# No iterator checking for release builds (MSVC 8 dosn't understand this though)
+ADD_COMPILER_FLAGS("-D_SECURE_SCL=0" ReleaseAll CACHE)
+
+# Newer MSVC versions come with std::shared_ptr which conflicts with
+# boost::shared_ptr in cpptcl. And since we don't yet use the new C++ standard
+# anyway, disable it completely.
+ADD_COMPILER_FLAGS("-D_HAS_CPP0X=0" CACHE)
 
 # Use Link time code generation for Release config if ORXONOX_RELEASE is defined
Index: /code/branches/kicklib2/cmake/LibraryConfig.cmake
===================================================================
--- /code/branches/kicklib2/cmake/LibraryConfig.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/LibraryConfig.cmake	(revision 8284)
@@ -40,13 +40,12 @@
 # On Windows using a package causes way less problems
 SET(_option_msg "Set this to true to use precompiled dependecy archives")
-IF(WIN32)
+IF(WIN32 OR APPLE)
   OPTION(DEPENDENCY_PACKAGE_ENABLE "${_option_msg}" ON)
-ELSE(WIN32)
+ELSE()
   OPTION(DEPENDENCY_PACKAGE_ENABLE "${_option_msg}" FALSE)
-ENDIF(WIN32)
+ENDIF()
 
 # Scripts for specific library and CMake config
 INCLUDE(LibraryConfigTardis)
-INCLUDE(LibraryConfigApple)
 
 IF(DEPENDENCY_PACKAGE_ENABLE)
@@ -59,4 +58,6 @@
   ELSEIF(MSVC90)
     SET(_compiler_prefix msvc9)
+  ELSEIF(MSVC100)
+    SET(_compiler_prefix msvc10)
   ENDIF()
   FIND_PATH(DEPENDENCY_PACKAGE_DIR
@@ -73,7 +74,11 @@
                    "Disable LIBRARY_USE_PACKAGE if you have none intalled.")
   ELSE()
-    INCLUDE(PackageConfigMinGW)
-    INCLUDE(PackageConfigMSVC)
-    INCLUDE(PackageConfig) # For both msvc and mingw
+    IF(WIN32)
+      INCLUDE(PackageConfigMinGW)
+      INCLUDE(PackageConfigMSVC)
+      INCLUDE(PackageConfig) # For both msvc and mingw
+    ELSEIF(APPLE)
+      INCLUDE(PackageConfigOSX)
+    ENDIF(WIN32)
   ENDIF()
 ENDIF(DEPENDENCY_PACKAGE_ENABLE)
@@ -141,7 +146,8 @@
 
 ##### Boost #####
-# Expand the next statement if newer boost versions than 1.36.1 are released
+# Expand the next statement if newer boost versions are released
 SET(Boost_ADDITIONAL_VERSIONS 1.37 1.37.0 1.38 1.38.0 1.39 1.39.0 1.40 1.40.0
-                              1.41 1.41.0 1.42 1.42.0 1.43 1.43.0 1.44 1.44.0)
+                              1.41 1.41.0 1.42 1.42.0 1.43 1.43.0 1.44 1.44.0
+                              1.45 1.45.0 1.46 1.46.0 1.46.1)
 IF( NOT TARDIS )
   FIND_PACKAGE(Boost 1.35 REQUIRED thread filesystem system date_time)
@@ -149,4 +155,13 @@
 # No auto linking, so this option is useless anyway
 MARK_AS_ADVANCED(Boost_LIB_DIAGNOSTIC_DEFINITIONS)
+# Complain about incompatibilities
+IF(GCC_VERSION)
+  COMPARE_VERSION_STRINGS("${GCC_VERSION}" "4.4.0" _compare_result)
+  IF(NOT _compare_result LESS 0)
+    IF(${Boost_VERSION} LESS 103700)
+      MESSAGE(STATUS "Warning: Boost versions earlier than 1.37 may not compile with GCC 4.4 or later!")
+    ENDIF()
+  ENDIF()
+ENDIF()
 
 
Index: de/branches/kicklib2/cmake/LibraryConfigApple.cmake
===================================================================
--- /code/branches/kicklib2/cmake/LibraryConfigApple.cmake	(revision 8283)
+++ 	(revision )
@@ -1,43 +1,0 @@
- #
- #             ORXONOX - the hottest 3D action shooter ever to exist
- #                             > www.orxonox.net <
- #
- #        This program is free software; you can redistribute it and/or
- #         modify it under the terms of the GNU General Public License
- #        as published by the Free Software Foundation; either version 2
- #            of the License, or (at your option) any later version.
- #
- #       This program is distributed in the hope that it will be useful,
- #        but WITHOUT ANY WARRANTY; without even the implied warranty of
- #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- #                 GNU General Public License for more details.
- #
- #   You should have received a copy of the GNU General Public License along
- #      with this program; if not, write to the Free Software Foundation,
- #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- #
- #
- #  Author:
- #    Yuning Chai
- #  Description:
- #    Sets necessary library options and paths on Mac.
- #
-
-IF(APPLE)
-  MESSAGE(STATUS "Running on Apple. Using customized paths and options.")
-
-  SET(ENV{OGRE_HOME} "/Developer/SDKs/OgreSDK/Dependencies")
-  SET(ENV{CEGUIDIR} "/Developer/SDKs/OgreSDK/Dependencies")
-
-  #MESSAGE(STATUS $ENV{OGRE_HOME})
-
-  SET(CMAKE_FIND_FRAMEWORK "FIRST")
-
-#  SET(OGRE_LIBRARY_OPTIMIZED "/Developer/SDKs/OgreSDK/Dependencies/Ogre.framework/Ogre")
-
-#  SET(CEGUI_LIBRARY_OPTIMIZED "/Developer/SDKs/OgreSDK/Dependencies/CEGUI.framework/CEGUI")
-
-#  SET(OGRE_LIBRARY_OPTIMIZED  "/Developer/SDKs/OgreSDK/Dependencies/Ogre.framework" CACHE STRING "Ogre lib for OSX")
-#  SET(CEGUI_LIBRARY_OPTIMIZED  "/Developer/SDKs/OgreSDK/Dependencies/CEGUI.framework" CACHE STRING "CEGUI lib for OSX")
-
-ENDIF(APPLE)
Index: /code/branches/kicklib2/cmake/PackageConfig.cmake
===================================================================
--- /code/branches/kicklib2/cmake/PackageConfig.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/PackageConfig.cmake	(revision 8284)
@@ -25,49 +25,4 @@
  #
 
-# Check package version info
-# MAJOR: Breaking change
-# MINOR: No breaking changes by the dependency package
-#        For example any code running on 3.0 should still run on 3.1
-#        But you can specify that the code only runs on 3.1 and higher
-#        or 4.0 and higher (so both 3.1 and 4.0 will work).
-IF(MSVC)
-  SET(ALLOWED_MINIMUM_VERSIONS 4.3 5.1 6.0)
-ELSE()
-  SET(ALLOWED_MINIMUM_VERSIONS 4.1 5.2)
-ENDIF()
-
-IF(NOT EXISTS ${DEPENDENCY_PACKAGE_DIR}/version.txt)
-  SET(DEPENDENCY_VERSION 1.0)
-ELSE()
-  # Get version from file
-  FILE(READ ${DEPENDENCY_PACKAGE_DIR}/version.txt _file_content)
-  SET(_match)
-  STRING(REGEX MATCH "([0-9]+.[0-9]+)" _match ${_file_content})
-  IF(_match)
-    SET(DEPENDENCY_VERSION ${_match})
-  ELSE()
-    MESSAGE(FATAL_ERROR "The version.txt file in the dependency file has corrupt version information.")
-  ENDIF()
-ENDIF()
-
-INCLUDE(CompareVersionStrings)
-SET(_version_match FALSE)
-FOREACH(_version ${ALLOWED_MINIMUM_VERSIONS})
-  # Get major version
-  STRING(REGEX REPLACE "^([0-9]+)\\..*$" "\\1" _major_version "${_version}")
-  COMPARE_VERSION_STRINGS(${DEPENDENCY_VERSION} ${_major_version} _result TRUE)
-  IF(_result EQUAL 0)
-    COMPARE_VERSION_STRINGS(${DEPENDENCY_VERSION} ${_version} _result FALSE)
-    IF(NOT _result LESS 0)
-      SET(_version_match TRUE)
-    ENDIF()
-  ENDIF()
-ENDFOREACH(_version)
-IF(NOT _version_match)
-  MESSAGE(FATAL_ERROR "Your dependency package version is ${DEPENDENCY_VERSION}\n"
-          "Possible required versions: ${ALLOWED_MINIMUM_VERSIONS}\n"
-          "You can get a new version from www.orxonox.net")
-ENDIF()
-
 IF(NOT _INTERNAL_PACKAGE_MESSAGE)
   MESSAGE(STATUS "Using library package for the dependencies.")
@@ -77,6 +32,6 @@
 # Ogre versions >= 1.7 require the POCO library on Windows with MSVC for threading
 COMPARE_VERSION_STRINGS(${DEPENDENCY_VERSION} 5 _result TRUE)
-IF(NOT _result EQUAL -1 AND NOT MINGW)
-    SET(POCO_REQUIRED TRUE)
+IF(NOT _result EQUAL -1 AND NOT APPLE)
+  SET(POCO_REQUIRED TRUE)
 ENDIF()
 
Index: /code/branches/kicklib2/cmake/PackageConfigMSVC.cmake
===================================================================
--- /code/branches/kicklib2/cmake/PackageConfigMSVC.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/PackageConfigMSVC.cmake	(revision 8284)
@@ -28,4 +28,7 @@
 IF(MSVC)
 
+  INCLUDE(CheckPackageVersion)
+  CHECK_PACKAGE_VERSION(4.3 6.0)
+
   # 64 bit system?
   IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
@@ -36,5 +39,5 @@
 
   # Choose right MSVC version
-  STRING(REGEX REPLACE "^Visual Studio ([0-9][0-9]?) .*$" "\\1"
+  STRING(REGEX REPLACE "^Visual Studio ([0-9][0-9]?).*$" "\\1"
          _msvc_version "${CMAKE_GENERATOR}")
 
@@ -56,4 +59,6 @@
   SET(TCL_LIBRARY  ${DEP_LIBRARY_DIR}/tcl85.lib CACHE FILEPATH "")
   SET(ZLIB_LIBRARY ${DEP_LIBRARY_DIR}/zdll.lib  CACHE FILEPATH "")
+  # Part of Platform SDK and usually gets linked automatically
+  SET(WMI_LIBRARY  wbemuuid.lib)
 
 ENDIF(MSVC)
Index: /code/branches/kicklib2/cmake/PackageConfigMinGW.cmake
===================================================================
--- /code/branches/kicklib2/cmake/PackageConfigMinGW.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/PackageConfigMinGW.cmake	(revision 8284)
@@ -28,4 +28,7 @@
 IF(MINGW)
 
+  INCLUDE(CheckPackageVersion)
+  CHECK_PACKAGE_VERSION(6.0)
+
   # 64 bit system?
   IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
@@ -48,5 +51,9 @@
   # to specify the libraries ourselves.
   SET(TCL_LIBRARY  ${DEP_BINARY_DIR}/tcl85.dll CACHE FILEPATH "")
-  SET(ZLIB_LIBRARY ${DEP_BINARY_DIR}/zlib1.dll CACHE FILEPATH "")
+  SET(ZLIB_LIBRARY ${DEP_BINARY_DIR}/libzlib.dll CACHE FILEPATH "")
+
+  # Not included in MinGW, so we need to supply it for OIS
+  SET(WMI_INCLUDE_DIR ${DEP_INCLUDE_DIR}/wmi/include)
+  SET(WMI_LIBRARY     ${DEP_LIBRARY_DIR}/wbemuuid.lib)
 
 ENDIF(MINGW)
Index: /code/branches/kicklib2/cmake/PackageConfigOSX.cmake
===================================================================
--- /code/branches/kicklib2/cmake/PackageConfigOSX.cmake	(revision 8284)
+++ /code/branches/kicklib2/cmake/PackageConfigOSX.cmake	(revision 8284)
@@ -0,0 +1,100 @@
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        This program is free software; you can redistribute it and/or
+ #         modify it under the terms of the GNU General Public License
+ #        as published by the Free Software Foundation; either version 2
+ #            of the License, or (at your option) any later version.
+ #
+ #       This program is distributed in the hope that it will be useful,
+ #        but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #                 GNU General Public License for more details.
+ #
+ #   You should have received a copy of the GNU General Public License along
+ #      with this program; if not, write to the Free Software Foundation,
+ #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ #
+ #
+ #  Author:
+ #    Reto Grieder
+ #  Description:
+ #    OS X package configuration
+ #
+
+INCLUDE(CheckPackageVersion)
+
+CHECK_PACKAGE_VERSION(1.0)
+
+IF(NOT _INTERNAL_PACKAGE_MESSAGE)
+  MESSAGE(STATUS "Using library package for the dependencies.")
+  SET(_INTERNAL_PACKAGE_MESSAGE 1 CACHE INTERNAL "Do not edit!" FORCE)
+ENDIF()
+
+SET(DEP_INCLUDE_DIR ${DEPENDENCY_PACKAGE_DIR}/include)
+SET(DEP_LIBRARY_DIR ${DEPENDENCY_PACKAGE_DIR}/lib)
+SET(DEP_BINARY_DIR  ${DEPENDENCY_PACKAGE_DIR}/bin)
+SET(DEP_FRAMEWORK_DIR ${DEPENDENCY_PACKAGE_DIR}/Library/Frameworks)
+
+# Sets the library path for the FIND_LIBRARY
+SET(CMAKE_LIBRARY_PATH ${DEP_LIBRARY_DIR})
+
+# Include paths and other special treatments
+SET(ENV{ALUTDIR}               ${DEP_FRAMEWORK_DIR})
+SET(ENV{BOOST_ROOT}            ${DEPENDENCY_PACKAGE_DIR})
+SET(ENV{CEGUIDIR}              ${DEP_FRAMEWORK_DIR})
+SET(ENV{LUA_DIR}               ${DEP_INCLUDE_DIR}/lua)
+SET(ENV{LUA5.1_DIR}            ${DEP_INCLUDE_DIR}/lua)
+SET(ENV{OGGDIR}                ${DEP_INCLUDE_DIR})
+SET(ENV{VORBISDIR}             ${DEP_INCLUDE_DIR})
+SET(ENV{OGRE_HOME}             ${DEP_FRAMEWORK_DIR})
+SET(ENV{OGRE_PLUGIN_DIR}       ${DEP_BINARY_DIR})
+
+# For OS X 10.5 we have to ship modified headers to make it compile
+# on gcc >= 4.2 (binaries stay the same)
+# Sets the library path for the FIND_LIBRARY
+IF(CMAKE_SYSTEM_VERSION STREQUAL "10.5")
+  SET(ENV{OPENALDIR} ${DEP_INCLUDE_DIR}/openal)
+ENDIF()
+
+# Xcode won't be able to run the toluabind code generation if we're using the dependency package
+#IF(DEPENDENCY_PACKAGE_ENABLE)
+#  IF(${CMAKE_GENERATOR} STREQUAL "Xcode")
+#    SET(ENV{DYLD_LIBRARY_PATH}               ${DEPENDENCY_PACKAGE_DIR}/lib)
+#    SET(ENV{DYLD_FRAMEWORK_PATH}             ${DEPENDENCY_PACKAGE_DIR}/Library/Frameworks)
+#  ENDIF(${CMAKE_GENERATOR} STREQUAL "Xcode")
+#ENDIF(DEPENDENCY_PACKAGE_ENABLE)
+
+### INSTALL ###
+
+# Tcl script library
+# TODO: How does this work on OS X?
+#INSTALL(
+#  DIRECTORY ${DEP_LIBRARY_DIR}/tcl/
+#  DESTINATION lib/tcl
+#)
+
+# TODO: Install on OSX
+IF(FALSE)
+  ## DEBUG
+  # When installing a debug version, we really can't know which libraries
+  # are used in released mode because there might be deps of deps.
+  # --> Copy all of them, except the debug databases
+  INSTALL(
+    DIRECTORY ${DEP_BINARY_DIR}/
+    DESTINATION bin
+    CONFIGURATIONS Debug
+    REGEX "^.*\\.pdb$" EXCLUDE
+  )
+
+  ## RELEASE
+  # Try to filter out all the debug libraries. If the regex doesn't do the
+  # job anymore, simply adjust it.
+  INSTALL(
+    DIRECTORY ${DEP_BINARY_DIR}/
+    DESTINATION bin
+    CONFIGURATIONS Release RelWithDebInfo MinSizeRel
+    REGEX "_[Dd]\\.[a-zA-Z0-9+-]+$|-mt-gd-|^.*\\.pdb$" EXCLUDE
+  )
+ENDIF()
Index: /code/branches/kicklib2/cmake/tools/CheckOGREPlugins.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/CheckOGREPlugins.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/tools/CheckOGREPlugins.cmake	(revision 8284)
@@ -52,10 +52,10 @@
       NAMES ${_plugin}
       PATHS $ENV{OGRE_HOME} $ENV{OGRE_PLUGIN_DIR}
-      PATH_SUFFIXES bin/Release bin/release Release release lib lib/OGRE bin
+      PATH_SUFFIXES bin/Release bin/release Release release lib lib/OGRE bin Ogre.framework/Resources
     )
     FIND_LIBRARY(OGRE_PLUGIN_${_plugin}_DEBUG
       NAMES ${_plugin}d ${_plugin}_d ${_plugin}
       PATHS $ENV{OGRE_HOME} $ENV{OGRE_PLUGIN_DIR}
-      PATH_SUFFIXES bin/Debug bin/debug Debug debug lib lib/OGRE bin
+      PATH_SUFFIXES bin/Debug bin/debug Debug debug lib lib/OGRE bin Ogre.framework/Resources
     )
     # We only need at least one render system. Check at the end.
Index: /code/branches/kicklib2/cmake/tools/CheckPackageVersion.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/CheckPackageVersion.cmake	(revision 8284)
+++ /code/branches/kicklib2/cmake/tools/CheckPackageVersion.cmake	(revision 8284)
@@ -0,0 +1,66 @@
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        This program is free software; you can redistribute it and/or
+ #         modify it under the terms of the GNU General Public License
+ #        as published by the Free Software Foundation; either version 2
+ #            of the License, or (at your option) any later version.
+ #
+ #       This program is distributed in the hope that it will be useful,
+ #        but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #                 GNU General Public License for more details.
+ #
+ #   You should have received a copy of the GNU General Public License along
+ #      with this program; if not, write to the Free Software Foundation,
+ #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ #
+ #
+ #  Author:
+ #    Reto Grieder
+ #  Description:
+ #    Check package version info
+ #    MAJOR: Breaking change
+ #    MINOR: No breaking changes by the dependency package
+ #           For example any code running on 3.0 should still run on 3.1
+ #           But you can specify that the code only runs on 3.1 and higher
+ #           or 4.0 and higher (so both 3.1 and 4.0 will work).
+
+MACRO(CHECK_PACKAGE_VERSION)
+  SET(_allowed_minimum_versions ${ARGN})
+
+  IF(NOT EXISTS ${DEPENDENCY_PACKAGE_DIR}/version.txt)
+    SET(DEPENDENCY_VERSION 1.0)
+  ELSE()
+    # Get version from file
+    FILE(READ ${DEPENDENCY_PACKAGE_DIR}/version.txt _file_content)
+    SET(_match)
+    STRING(REGEX MATCH "([0-9]+.[0-9]+)" _match ${_file_content})
+    IF(_match)
+      SET(DEPENDENCY_VERSION ${_match})
+    ELSE()
+      MESSAGE(FATAL_ERROR "The version.txt file in the dependency file has corrupt version information.")
+    ENDIF()
+  ENDIF()
+  
+  INCLUDE(CompareVersionStrings)
+  SET(_version_match FALSE)
+  FOREACH(_version ${_allowed_minimum_versions})
+    # Get major version
+    STRING(REGEX REPLACE "^([0-9]+)\\..*$" "\\1" _major_version "${_version}")
+    COMPARE_VERSION_STRINGS(${DEPENDENCY_VERSION} ${_major_version} _result TRUE)
+    IF(_result EQUAL 0)
+      COMPARE_VERSION_STRINGS(${DEPENDENCY_VERSION} ${_version} _result FALSE)
+      IF(NOT _result LESS 0)
+        SET(_version_match TRUE)
+      ENDIF()
+    ENDIF()
+  ENDFOREACH(_version)
+  IF(NOT _version_match)
+    MESSAGE(FATAL_ERROR "Your dependency package version is ${DEPENDENCY_VERSION}\n"
+            "Possible required versions: ${_allowed_minimum_versions}\n"
+            "You can get a new version from www.orxonox.net")
+  ENDIF()
+  
+ENDMACRO(CHECK_PACKAGE_VERSION)
Index: /code/branches/kicklib2/cmake/tools/FindALUT.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/FindALUT.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/tools/FindALUT.cmake	(revision 8284)
@@ -1,72 +1,52 @@
-# - Locate FreeAlut
-# This module defines
-#  ALUT_LIBRARY
-#  ALUT_FOUND, if false, do not try to link against Alut
-#  ALUT_INCLUDE_DIR, where to find the headers
-#
-# $ALUTDIR is an environment variable that would
-# correspond to the ./configure --prefix=$ALUTDIR
-# used in building Alut.
-#
-# Created by Eric Wing. This was influenced by the FindSDL.cmake module.
-# On OSX, this will prefer the Framework version (if found) over others.
-# People will have to manually change the cache values of
-# ALUT_LIBRARY to override this selection.
-# Tiger will include OpenAL as part of the System.
-# But for now, we have to look around.
-# Other (Unix) systems should be able to utilize the non-framework paths.
-#
-# Several changes and additions by Fabian 'x3n' Landau
-# Some simplifications by Adrian Friedli and Reto Grieder
-#                 > www.orxonox.net <
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        This program is free software; you can redistribute it and/or
+ #         modify it under the terms of the GNU General Public License
+ #        as published by the Free Software Foundation; either version 2
+ #            of the License, or (at your option) any later version.
+ #
+ #       This program is distributed in the hope that it will be useful,
+ #        but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #                 GNU General Public License for more details.
+ #
+ #   You should have received a copy of the GNU General Public License along
+ #      with this program; if not, write to the Free Software Foundation,
+ #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ #
+ #
+ #  Author:
+ #    Kevin Young
+ #  Description:
+ #    Variables defined:
+ #      ALUT_FOUND
+ #      ALUT_INCLUDE_DIR
+ #      ALUT_LIBRARY
+ #
 
 INCLUDE(FindPackageHandleStandardArgs)
 INCLUDE(HandleLibraryTypes)
 
-FIND_PATH(ALUT_INCLUDE_DIR AL/alut.h
-  PATHS
-  $ENV{ALUTDIR}
-  ~/Library/Frameworks/OpenAL.framework
-  /Library/Frameworks/OpenAL.framework
-  /System/Library/Frameworks/OpenAL.framework # Tiger
-  PATH_SUFFIXES include include/OpenAL include/AL Headers
+FIND_PATH(ALUT_INCLUDE_DIR alut.h
+  PATHS $ENV{ALUTDIR}
+  PATH_SUFFIXES include include/AL Headers Headers/AL
 )
-
-# I'm not sure if I should do a special casing for Apple. It is
-# unlikely that other Unix systems will find the framework path.
-# But if they do ([Next|Open|GNU]Step?),
-# do they want the -framework option also?
-IF(${ALUT_INCLUDE_DIR} MATCHES ".framework")
-
-  STRING(REGEX REPLACE "(.*)/.*\\.framework/.*" "\\1" ALUT_FRAMEWORK_PATH_TMP ${ALUT_INCLUDE_DIR})
-  IF("${ALUT_FRAMEWORK_PATH_TMP}" STREQUAL "/Library/Frameworks"
-      OR "${ALUT_FRAMEWORK_PATH_TMP}" STREQUAL "/System/Library/Frameworks"
-      )
-    # String is in default search path, don't need to use -F
-    SET (ALUT_LIBRARY_OPTIMIZED "-framework OpenAL" CACHE STRING "OpenAL framework for OSX")
-  ELSE()
-    # String is not /Library/Frameworks, need to use -F
-    SET(ALUT_LIBRARY_OPTIMIZED "-F${ALUT_FRAMEWORK_PATH_TMP} -framework OpenAL" CACHE STRING "OpenAL framework for OSX")
-  ENDIF()
-  # Clear the temp variable so nobody can see it
-  SET(ALUT_FRAMEWORK_PATH_TMP "" CACHE INTERNAL "")
-
-ELSE()
-  FIND_LIBRARY(ALUT_LIBRARY_OPTIMIZED
-    NAMES alut
-    PATHS $ENV{ALUTDIR}
-    PATH_SUFFIXES lib libs
-  )
-  FIND_LIBRARY(ALUT_LIBRARY_DEBUG
-    NAMES alutd alut_d alutD alut_D
-    PATHS $ENV{ALUTDIR}
-    PATH_SUFFIXES lib libs
-  )
-ENDIF()
+FIND_LIBRARY(ALUT_LIBRARY_OPTIMIZED
+  NAMES alut ALUT
+  PATHS $ENV{ALUTDIR}
+  PATH_SUFFIXES lib bin/Release bin/release Release release ALUT
+)
+FIND_LIBRARY(ALUT_LIBRARY_DEBUG
+  NAMES alutd alut_d alutD alut_D ALUTd ALUT_d ALUTD ALUT_D
+  PATHS $ENV{ALUTDIR}
+  PATH_SUFFIXES lib bin/Debug bin/debug Debug debug ALUT
+)
 
 # Handle the REQUIRED argument and set ALUT_FOUND
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(ALUT DEFAULT_MSG
-    ALUT_LIBRARY_OPTIMIZED
-    ALUT_INCLUDE_DIR
+  ALUT_LIBRARY_OPTIMIZED
+  ALUT_INCLUDE_DIR
 )
 
@@ -75,6 +55,6 @@
 
 MARK_AS_ADVANCED(
-    ALUT_INCLUDE_DIR
-    ALUT_LIBRARY_OPTIMIZED
-    ALUT_LIBRARY_DEBUG
+  ALUT_INCLUDE_DIR
+  ALUT_LIBRARY_OPTIMIZED
+  ALUT_LIBRARY_DEBUG
 )
Index: /code/branches/kicklib2/cmake/tools/FindCEGUI.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/FindCEGUI.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/tools/FindCEGUI.cmake	(revision 8284)
@@ -31,5 +31,5 @@
 INCLUDE(HandleLibraryTypes)
 
-# Find headers
+# Find CEGUI headers
 FIND_PATH(CEGUI_INCLUDE_DIR CEGUI.h
   PATHS $ENV{CEGUIDIR}
@@ -44,5 +44,5 @@
   NAMES CEGUIBase CEGUI
   PATHS $ENV{CEGUIDIR}
-  PATH_SUFFIXES lib bin
+  PATH_SUFFIXES lib bin CEGUIBase.framework CEGUI.framework
 )
 FIND_LIBRARY(CEGUI_LIBRARY_DEBUG
@@ -54,9 +54,14 @@
 )
 
+# Find CEGUILua headers
+FIND_PATH(CEGUILUA_INCLUDE_DIR CEGUILua.h
+  PATHS $ENV{CEGUIDIR} ${CEGUI_INCLUDE_DIR}/ScriptingModules/LuaScriptModule
+  PATH_SUFFIXES include include/CEGUI CEGUILuaScriptModule.framework/Headers
+)
 # Find CEGUILua libraries
 FIND_LIBRARY(CEGUILUA_LIBRARY_OPTIMIZED
   NAMES CEGUILua CEGUILuaScriptModule
   PATHS $ENV{CEGUIDIR}
-  PATH_SUFFIXES lib bin
+  PATH_SUFFIXES lib bin CEGUILuaScriptModule.framework
 )
 FIND_LIBRARY(CEGUILUA_LIBRARY_DEBUG
@@ -66,9 +71,22 @@
 )
 
+# Find CEGUI Tolua++ include file
+# We only need to add this path since we use tolua++ like a normal
+# dependency but it is shipped with CEGUILua.
+FIND_PATH(CEGUI_TOLUA_INCLUDE_DIR tolua++.h
+  PATHS
+    ${CEGUILUA_INCLUDE_DIR}
+    # For newer CEGUI versions >= 0.7
+    ${CEGUILUA_INCLUDE_DIR}/support/tolua++
+    # For Apples
+    $ENV{CEGUIDIR}
+  PATH_SUFFIXES ceguitolua++.framework/Headers
+  NO_DEFAULT_PATH # MUST be in CEGUILUA_INCLUDE_DIR somewhere
+)
 # Find CEGUI Tolua++ libraries
 FIND_LIBRARY(CEGUI_TOLUA_LIBRARY_OPTIMIZED
-  NAMES CEGUItoluapp tolua++
+  NAMES CEGUItoluapp tolua++ ceguitolua++
   PATHS $ENV{CEGUIDIR}
-  PATH_SUFFIXES lib bin
+  PATH_SUFFIXES lib bin ceguitolua++.framework
 )
 FIND_LIBRARY(CEGUI_TOLUA_LIBRARY_DEBUG
@@ -81,4 +99,9 @@
 COMPARE_VERSION_STRINGS("${CEGUI_VERSION}" "0.7" _version_compare TRUE)
 IF(_version_compare GREATER -1)
+  # Find CEGUI OGRE Renderer headers
+  FIND_PATH(CEGUI_OGRE_RENDERER_INCLUDE_DIR CEGUIOgreRenderer.h
+    PATHS $ENV{CEGUIDIR} ${CEGUI_INCLUDE_DIR}/RendererModules/Ogre
+    PATH_SUFFIXES include include/CEGUI CEGUI.framework/Headers
+  )
   # Find CEGUI OGRE Renderer libraries
   FIND_LIBRARY(CEGUI_OGRE_RENDERER_LIBRARY_OPTIMIZED
@@ -92,6 +115,10 @@
     PATH_SUFFIXES lib bin
   )
-  SET(CEGUI_OGRE_RENDERER_LIBRARY_NAME CEGUI_OGRE_RENDERER_LIBRARY_OPTIMIZED)
+  SET(CEGUI_OGRE_RENDERER_REQUIRED_VARIABLES
+    CEGUI_OGRE_RENDERER_INCLUDE_DIR
+    CEGUI_OGRE_RENDERER_LIBRARY_OPTIMIZED
+  )
 ELSE()
+  SET(CEGUI_OLD_VERSION TRUE)
   SET(CEGUI_OGRE_RENDERER_BUILD_REQUIRED TRUE)
 ENDIF()
@@ -102,7 +129,9 @@
   CEGUI_INCLUDE_DIR
   CEGUI_LIBRARY_OPTIMIZED
+  CEGUILUA_INCLUDE_DIR
   CEGUILUA_LIBRARY_OPTIMIZED
+  CEGUI_TOLUA_INCLUDE_DIR
   CEGUI_TOLUA_LIBRARY_OPTIMIZED
-  ${CEGUI_OGRE_RENDERER_LIBRARY_NAME}
+  ${CEGUI_OGRE_RENDERER_REQUIRED_VARIABLES}
 )
 
@@ -119,8 +148,11 @@
   CEGUI_LIBRARY_OPTIMIZED
   CEGUI_LIBRARY_DEBUG
+  CEGUILUA_INCLUDE_DIR
   CEGUILUA_LIBRARY_OPTIMIZED
   CEGUILUA_LIBRARY_DEBUG
+  CEGUI_TOLUA_INCLUDE_DIR
   CEGUI_TOLUA_LIBRARY_OPTIMIZED
   CEGUI_TOLUA_LIBRARY_DEBUG
+  CEGUI_OGRE_RENDERER_INCLUDE_DIR
   CEGUI_OGRE_RENDERER_LIBRARY_OPTIMIZED
   CEGUI_OGRE_RENDERER_LIBRARY_DEBUG
Index: /code/branches/kicklib2/cmake/tools/FindOgg.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/FindOgg.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/tools/FindOgg.cmake	(revision 8284)
@@ -22,5 +22,5 @@
 )
 FIND_LIBRARY(OGG_LIBRARY_OPTIMIZED
-  NAMES ogg
+  NAMES ogg ogg-0
   PATHS $ENV{OGGDIR}
   PATH_SUFFIXES lib
Index: /code/branches/kicklib2/cmake/tools/FindPOCO.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/FindPOCO.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/tools/FindPOCO.cmake	(revision 8284)
@@ -29,5 +29,5 @@
 FIND_PATH(POCO_INCLUDE_DIR Poco/Poco.h
   PATHS $ENV{POCODIR}
-  PATH_SUFFIXES include
+  PATH_SUFFIXES include Foundation/include
 )
 FIND_LIBRARY(POCO_LIBRARY_OPTIMIZED
Index: /code/branches/kicklib2/cmake/tools/FindVorbis.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/FindVorbis.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/tools/FindVorbis.cmake	(revision 8284)
@@ -22,5 +22,5 @@
 )
 FIND_LIBRARY(VORBIS_LIBRARY_OPTIMIZED
-  NAMES vorbis
+  NAMES vorbis vorbis-0
   PATHS $ENV{VORBISDIR}
   PATH_SUFFIXES lib
@@ -32,5 +32,5 @@
 )
 FIND_LIBRARY(VORBISFILE_LIBRARY_OPTIMIZED
-  NAMES vorbisfile
+  NAMES vorbisfile vorbisfile-3
   PATHS $ENV{VORBISDIR}
   PATH_SUFFIXES lib
Index: /code/branches/kicklib2/cmake/tools/GenerateToluaBindings.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/GenerateToluaBindings.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/tools/GenerateToluaBindings.cmake	(revision 8284)
@@ -32,4 +32,14 @@
  #    RUNTIME_LIBRARY_DIRECTORY - Working directory
  #
+
+# Workaround for XCode: The folder where the bind files are written to has
+# to be present beforehand.
+# We have to do this here because the header files are all stored in a single
+# location per configuration.
+IF(CMAKE_CONFIGURATION_TYPES)
+  FOREACH(_dir ${CMAKE_CONFIGURATION_TYPES})
+    FILE(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/src/toluabind/${_dir}")
+  ENDFOREACH(_dir)
+ENDIF()
 
 FUNCTION(GENERATE_TOLUA_BINDINGS _tolua_package _target_source_files)
Index: /code/branches/kicklib2/cmake/tools/TargetUtilities.cmake
===================================================================
--- /code/branches/kicklib2/cmake/tools/TargetUtilities.cmake	(revision 8283)
+++ /code/branches/kicklib2/cmake/tools/TargetUtilities.cmake	(revision 8284)
@@ -53,5 +53,5 @@
  #    This function also installs the target!
  #  Prerequisistes:
- #    ORXONOX_DEFAULT_LINK, ORXONOX_CONFIG_FILES
+ #    ORXONOX_DEFAULT_LINK, ORXONOX_CONFIG_FILES, ORXONOX_CONFIG_FILES_GENERATED
  #  Parameters:
  #    _target_name, ARGN for the macro arguments
@@ -169,4 +169,11 @@
     GENERATE_TOLUA_BINDINGS(${_target_name_capitalised} _${_target_name}_files
                             INPUTFILES ${_arg_TOLUA_FILES})
+    # Workaround for XCode: The folder where the bind files are written to has
+    # to be present beforehand.
+    IF(CMAKE_CONFIGURATION_TYPES)
+      FOREACH(_dir ${CMAKE_CONFIGURATION_TYPES})
+        FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_dir})
+      ENDFOREACH(_dir)
+    ENDIF()
   ENDIF()
 
@@ -192,11 +199,17 @@
 
     IF(NOT _arg_ORXONOX_EXTERNAL)
-      # Move the prereqs.h file to the config section
+      # Move the ...Prereqs.h and the PCH files to the 'Config' section
       IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_target_name_capitalised}Prereqs.h)
         SOURCE_GROUP("Config" FILES ${_target_name_capitalised}Prereqs.h)
       ENDIF()
-      # Add config files to the config section
-      LIST(APPEND _${_target_name}_files ${ORXONOX_CONFIG_FILES})
+      IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_arg_PCH_FILE})
+        SOURCE_GROUP("Config" FILES ${CMAKE_CURRENT_SOURCE_DIR}/${_arg_PCH_FILE})
+      ENDIF()
+      # Also include all config files
+      LIST(APPEND _${_target_name}_files ${ORXONOX_CONFIG_FILES} ${ORXONOX_CONFIG_FILES_GENERATED})
+      # Add unprocessed config files to the 'Config' section
       SOURCE_GROUP("Config" FILES ${ORXONOX_CONFIG_FILES})
+      # Add generated config files to the 'Generated' section
+      SOURCE_GROUP("Generated" FILES ${ORXONOX_CONFIG_FILES_GENERATED})
     ENDIF()
   ENDIF()
@@ -217,10 +230,11 @@
   IF(_arg_ORXONOX_EXTERNAL)
     REMOVE_COMPILER_FLAGS("-W3 -W4" MSVC)
-    ADD_COMPILER_FLAGS("-w")
+    ADD_COMPILER_FLAGS("-w" NOT MSVC)
+    ADD_COMPILER_FLAGS("-W0" MSVC)
   ENDIF()
 
   # Don't compile header files
   FOREACH(_file ${_${_target_name}_files})
-    IF(NOT _file MATCHES "\\.(c|cc|cpp|cxx)$")
+    IF(NOT _file MATCHES "\\.(c|cc|cpp|cxx|mm)$")
       SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
     ENDIF()
Index: /code/branches/kicklib2/data/gui/scripts/AudioMenu.lua
===================================================================
--- /code/branches/kicklib2/data/gui/scripts/AudioMenu.lua	(revision 8283)
+++ /code/branches/kicklib2/data/gui/scripts/AudioMenu.lua	(revision 8284)
@@ -32,4 +32,6 @@
     table.insert(themeList, "Default")
     table.insert(themeList, "Drum n' Bass")
+    table.insert(themeList, "8-Bit Style")
+    table.insert(themeList, "Corny Jazz")
     for k,v in pairs(themeList) do
         item = CEGUI.createListboxTextItem(v)
@@ -39,4 +41,8 @@
     if orxonox.getConfig("MoodManager", "mood_") == "dnb" then
         listboxwindow:setItemSelectState(1,true)
+    elseif orxonox.getConfig("MoodManager", "mood_") == "eightbit" then
+        listboxwindow:setItemSelectState(2,true)
+    elseif orxonox.getConfig("MoodManager", "mood_") == "jazzy" then
+        listboxwindow:setItemSelectState(3,true)
     else
         listboxwindow:setItemSelectState(0,true)
@@ -168,4 +174,8 @@
     if listboxwindow:isItemSelected(1) then
         orxonox.config("MoodManager", "mood_", "dnb")
+    elseif listboxwindow:isItemSelected(2) then
+        orxonox.config("MoodManager", "mood_", "eightbit")
+    elseif listboxwindow:isItemSelected(3) then
+        orxonox.config("MoodManager", "mood_", "jazzy")
     else
         orxonox.config("MoodManager", "mood_", "default")
Index: /code/branches/kicklib2/src/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/src/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/src/CMakeLists.txt	(revision 8284)
@@ -69,7 +69,18 @@
 # Set the search paths for include files
 INCLUDE_DIRECTORIES(
+  # OrxonoxConfig.h
+  ${CMAKE_CURRENT_BINARY_DIR}
+
+  # All includes in "externals" should be prefixed with the path
+  # relative to "external" to avoid conflicts
+  ${CMAKE_CURRENT_SOURCE_DIR}/external
+  # Include directories needed even if only included by Orxonox
+  ${CMAKE_CURRENT_SOURCE_DIR}/external/bullet
+  ${CMAKE_CURRENT_SOURCE_DIR}/external/ois
+
   # External
   ${OGRE_INCLUDE_DIR}
   ${CEGUI_INCLUDE_DIR}
+  ${CEGUI_TOLUA_INCLUDE_DIR}
   #${ENET_INCLUDE_DIR}
   ${Boost_INCLUDE_DIRS}
@@ -83,15 +94,9 @@
   ${DIRECTX_INCLUDE_DIR}
   ${ZLIB_INCLUDE_DIR}
+)
 
-  # All includes in "externals" should be prefixed with the path
-  # relative to "external" to avoid conflicts
-  ${CMAKE_CURRENT_SOURCE_DIR}/external
-  # Include directories needed even if only included by Orxonox
-  ${CMAKE_CURRENT_SOURCE_DIR}/external/bullet
-  ${CMAKE_CURRENT_SOURCE_DIR}/external/ois
-
-  # OrxonoxConfig.h
-  ${CMAKE_CURRENT_BINARY_DIR}
-)
+IF(CEGUI_OLD_VERSION)
+  INCLUDE_DIRECTORIES(${CEGUILUA_INCLUDE_DIR})
+ENDIF()
 
 IF (DBGHELP_FOUND)
@@ -165,7 +170,11 @@
     SET(MSVC_PLATFORM "Win32")
   ENDIF()
-  STRING(REGEX REPLACE "^Visual Studio ([0-9][0-9]?) .*$" "\\1"
-         VISUAL_STUDIO_VERSION_SIMPLE "${CMAKE_GENERATOR}")
-  CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/orxonox-main.vcproj.user.in" "${CMAKE_CURRENT_BINARY_DIR}/orxonox-main.vcproj.user")
+  IF(MSVC10)
+    CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/orxonox-main.vcxproj.user.in" "${CMAKE_CURRENT_BINARY_DIR}/orxonox-main.vcxproj.user")
+  ELSE()
+    STRING(REGEX REPLACE "^Visual Studio ([0-9][0-9]?).*$" "\\1"
+           VISUAL_STUDIO_VERSION_SIMPLE "${CMAKE_GENERATOR}")
+    CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/orxonox-main.vcproj.user.in" "${CMAKE_CURRENT_BINARY_DIR}/orxonox-main.vcproj.user")
+  ENDIF()
 ENDIF(MSVC)
 
Index: /code/branches/kicklib2/src/OrxonoxConfig.cmake
===================================================================
--- /code/branches/kicklib2/src/OrxonoxConfig.cmake	(revision 8283)
+++ /code/branches/kicklib2/src/OrxonoxConfig.cmake	(revision 8284)
@@ -32,5 +32,6 @@
 
 # Global switch to disable Precompiled Header Files
-IF(PCH_COMPILER_SUPPORT)
+# Note: PCH temporarily disabled on Mac because of severe problems
+IF(PCH_COMPILER_SUPPORT AND NOT APPLE)
   OPTION(PCH_ENABLE "Global PCH switch" TRUE)
 ENDIF()
@@ -53,11 +54,4 @@
 ENDIF()
 
-# 32/64 bit system check
-IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
-  SET(ORXONOX_ARCH_64 TRUE)
-ELSE()
-  SET(ORXONOX_ARCH_32 TRUE)
-ENDIF()
-
 # Platforms
 SET(ORXONOX_PLATFORM_WINDOWS ${WIN32})
@@ -75,7 +69,11 @@
 ENDIF(MSVC)
 
-# Check iso646.h include (literal operators)
+# Check some non standard system includes
 INCLUDE(CheckIncludeFileCXX)
 CHECK_INCLUDE_FILE_CXX(iso646.h HAVE_ISO646_H)
+CHECK_INCLUDE_FILE_CXX(stdint.h HAVE_STDINT_H)
+
+# Part of a woraround for OS X warnings. See OrxonoxConfig.h.in
+SET(ORX_HAVE_STDINT_H ${HAVE_STDINT_H})
 
 IF(MSVC)
@@ -106,7 +104,9 @@
 
 SET(ORXONOX_CONFIG_FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/OrxonoxConfig.h
   ${CMAKE_CURRENT_SOURCE_DIR}/OrxonoxConfig.h.in
-  ${CMAKE_CURRENT_BINARY_DIR}/SpecialConfig.h
   ${CMAKE_CURRENT_SOURCE_DIR}/SpecialConfig.h.in
 )
+SET(ORXONOX_CONFIG_FILES_GENERATED
+  ${CMAKE_CURRENT_BINARY_DIR}/OrxonoxConfig.h
+  ${CMAKE_CURRENT_BINARY_DIR}/SpecialConfig.h
+)
Index: /code/branches/kicklib2/src/OrxonoxConfig.h.in
===================================================================
--- /code/branches/kicklib2/src/OrxonoxConfig.h.in	(revision 8283)
+++ /code/branches/kicklib2/src/OrxonoxConfig.h.in	(revision 8284)
@@ -80,14 +80,17 @@
 
 // Architecture
-#cmakedefine ORXONOX_ARCH_32
-#cmakedefine ORXONOX_ARCH_64
+#if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || defined(__alpha__) || defined(__ia64__) || defined(__s390__) || defined(__s390x__)
+#   define ORXONOX_ARCH_64
+#else
+#   define ORXONOX_ARCH_32
+#endif
 
 // See if we can use __forceinline or if we need to use __inline instead
 #cmakedefine HAVE_FORCEINLINE
-#ifndef FORCEINLINE
+#ifndef ORX_FORCEINLINE
 #  ifdef HAVE_FORCEINLINE
-#    define FORCEINLINE __forceinline
+#    define ORX_FORCEINLINE __forceinline
 #  else
-#    define FORCEINLINE __inline
+#    define ORX_FORCEINLINE __inline
 #  endif
 #endif
@@ -158,6 +161,9 @@
 #endif
 
-#cmakedefine HAVE_STDINT_H
-#ifdef HAVE_STDINT_H
+// On OS X some headers already define HAVE_STDINT_H and that spits out
+// some warnings. Therefore we use this macro.
+// Note: This requires some extra code in OrxonoxConfig.cmake
+#cmakedefine ORX_HAVE_STDINT_H
+#ifdef ORX_HAVE_STDINT_H
 #  include <stdint.h>
 #elif defined(ORXONOX_COMPILER_MSVC)
Index: /code/branches/kicklib2/src/SpecialConfig.h.in
===================================================================
--- /code/branches/kicklib2/src/SpecialConfig.h.in	(revision 8283)
+++ /code/branches/kicklib2/src/SpecialConfig.h.in	(revision 8284)
@@ -92,8 +92,14 @@
 
     // OGRE PLUGINS
+    // Apple has trouble finding OGRE plugins because of its install-name convention
+    // Adopting the executable_path structure for later use in app bundles
 #ifdef NDEBUG
     const char ogrePlugins[] = "@OGRE_PLUGINS_RELEASE@";
 #  ifdef DEPENDENCY_PACKAGE_ENABLE
-    const char ogrePluginsDirectory[] = ".";
+#    ifdef ORXONOX_PLATFORM_APPLE
+       const char ogrePluginsDirectory[] = "@executable_path/../Plugins";
+#    else
+       const char ogrePluginsDirectory[] = ".";
+#    endif
 #  else
     const char ogrePluginsDirectory[] = "@OGRE_PLUGINS_FOLDER_RELEASE@";
@@ -102,5 +108,9 @@
     const char ogrePlugins[] = "@OGRE_PLUGINS_DEBUG@";
 #  ifdef DEPENDENCY_PACKAGE_ENABLE
-    const char ogrePluginsDirectory[] = ".";
+#    ifdef ORXONOX_PLATFORM_APPLE
+       const char ogrePluginsDirectory[] = "@OGRE_PLUGINS_FOLDER_DEBUG@";
+#    else
+       const char ogrePluginsDirectory[] = ".";
+#    endif
 #  else
     const char ogrePluginsDirectory[] = "@OGRE_PLUGINS_FOLDER_DEBUG@";
Index: /code/branches/kicklib2/src/external/bullet/Bullet-C-Api.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/Bullet-C-Api.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/Bullet-C-Api.h	(revision 8284)
@@ -148,4 +148,5 @@
 	extern  void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);
 	extern	void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);
+	extern	void plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
 
 	typedef struct plRayCastResult {
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h	(revision 8284)
@@ -151,4 +151,6 @@
 	
 	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+	virtual void	aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
+
 	
 	void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
@@ -281,4 +283,29 @@
 			{
 				rayCallback.process(getHandle(m_pEdges[axis][i].m_handle));
+			}
+		}
+	}
+}
+
+template <typename BP_FP_INT_TYPE>
+void	btAxisSweep3Internal<BP_FP_INT_TYPE>::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
+{
+	if (m_raycastAccelerator)
+	{
+		m_raycastAccelerator->aabbTest(aabbMin,aabbMax,callback);
+	} else
+	{
+		//choose axis?
+		BP_FP_INT_TYPE axis = 0;
+		//for each proxy
+		for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
+		{
+			if (m_pEdges[axis][i].IsMax())
+			{
+				Handle* handle = getHandle(m_pEdges[axis][i].m_handle);
+				if (TestAabbAgainstAabb2(aabbMin,aabbMax,handle->m_aabbMin,handle->m_aabbMax))
+				{
+					callback.process(handle);
+				}
 			}
 		}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h	(revision 8284)
@@ -27,5 +27,12 @@
 
 
-struct	btBroadphaseRayCallback
+struct	btBroadphaseAabbCallback
+{
+	virtual ~btBroadphaseAabbCallback() {}
+	virtual bool	process(const btBroadphaseProxy* proxy) = 0;
+};
+
+
+struct	btBroadphaseRayCallback : public btBroadphaseAabbCallback
 {
 	///added some cached data to accelerate ray-AABB tests
@@ -35,5 +42,4 @@
 
 	virtual ~btBroadphaseRayCallback() {}
-	virtual bool	process(const btBroadphaseProxy* proxy) = 0;
 };
 
@@ -55,4 +61,6 @@
 	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
 
+	virtual void	aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) = 0;
+
 	///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
 	virtual void	calculateOverlappingPairs(btDispatcher* dispatcher)=0;
@@ -66,5 +74,5 @@
 
 	///reset broadphase internal structures, to ensure determinism/reproducability
-	virtual void resetPool(btDispatcher* dispatcher) {};
+	virtual void resetPool(btDispatcher* dispatcher) { (void) dispatcher; };
 
 	virtual void	printStats() = 0;
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h	(revision 8284)
@@ -47,4 +47,6 @@
 	MINKOWSKI_SUM_SHAPE_PROXYTYPE,
 	MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
+	BOX_2D_SHAPE_PROXYTYPE,
+	CONVEX_2D_SHAPE_PROXYTYPE,
 	CUSTOM_CONVEX_SHAPE_TYPE,
 //concave shapes
@@ -140,4 +142,9 @@
 	}
 
+	static SIMD_FORCE_INLINE bool	isNonMoving(int proxyType)
+	{
+		return (isConcave(proxyType) && !(proxyType==GIMPACT_SHAPE_PROXYTYPE));
+	}
+
 	static SIMD_FORCE_INLINE bool	isConcave(int proxyType)
 	{
@@ -149,8 +156,20 @@
 		return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
 	}
+
+	static SIMD_FORCE_INLINE bool	isSoftBody(int proxyType)
+	{
+		return (proxyType == SOFTBODY_SHAPE_PROXYTYPE);
+	}
+
 	static SIMD_FORCE_INLINE bool isInfinite(int proxyType)
 	{
 		return (proxyType == STATIC_PLANE_PROXYTYPE);
 	}
+
+	static SIMD_FORCE_INLINE bool isConvex2d(int proxyType)
+	{
+		return (proxyType == BOX_2D_SHAPE_PROXYTYPE) ||	(proxyType == CONVEX_2D_SHAPE_PROXYTYPE);
+	}
+
 	
 }
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp	(revision 8284)
@@ -62,5 +62,5 @@
 	{
 		getmaxdepth(node->childs[0],depth+1,maxdepth);
-		getmaxdepth(node->childs[0],depth+1,maxdepth);
+		getmaxdepth(node->childs[1],depth+1,maxdepth);
 	} else maxdepth=btMax(maxdepth,depth);
 }
@@ -239,5 +239,5 @@
 	for(int i=0,ni=leaves.size();i<ni;++i)
 	{
-		if(dot(axis,leaves[i]->volume.Center()-org)<0)
+		if(btDot(axis,leaves[i]->volume.Center()-org)<0)
 			left.push_back(leaves[i]);
 		else
@@ -320,5 +320,5 @@
 				for(int j=0;j<3;++j)
 				{
-					++splitcount[j][dot(x,axis[j])>0?1:0];
+					++splitcount[j][btDot(x,axis[j])>0?1:0];
 				}
 			}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.h	(revision 8284)
@@ -33,5 +33,5 @@
 
 // Template implementation of ICollide
-#ifdef WIN32
+#ifdef _WIN32
 #if (defined (_MSC_VER) && _MSC_VER >= 1400)
 #define	DBVT_USE_TEMPLATE		1
@@ -58,5 +58,5 @@
 
 //SSE gives errors on a MSVC 7.1
-#ifdef BT_USE_SSE
+#if defined (BT_USE_SSE) && defined (_WIN32)
 #define DBVT_SELECT_IMPL		DBVT_IMPL_SSE
 #define DBVT_MERGE_IMPL			DBVT_IMPL_SSE
@@ -93,5 +93,5 @@
 
 #if DBVT_USE_MEMMOVE
-#ifndef __CELLOS_LV2__
+#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
 #include <memory.h>
 #endif
@@ -485,6 +485,6 @@
 		pi=btVector3(mi.x(),mi.y(),mi.z());break;
 	}
-	if((dot(n,px)+o)<0)		return(-1);
-	if((dot(n,pi)+o)>=0)	return(+1);
+	if((btDot(n,px)+o)<0)		return(-1);
+	if((btDot(n,pi)+o)>=0)	return(+1);
 	return(0);
 }
@@ -497,5 +497,5 @@
 		b[(signs>>1)&1]->y(),
 		b[(signs>>2)&1]->z());
-	return(dot(p,v));
+	return(btDot(p,v));
 }
 
@@ -948,4 +948,5 @@
 								DBVT_IPOLICY) const
 {
+        (void) rayTo;
 	DBVT_CHECKTYPE
 	if(root)
@@ -962,6 +963,6 @@
 		{
 			const btDbvtNode*	node=stack[--depth];
-			bounds[0] = node->volume.Mins()+aabbMin;
-			bounds[1] = node->volume.Maxs()+aabbMax;
+			bounds[0] = node->volume.Mins()-aabbMax;
+			bounds[1] = node->volume.Maxs()-aabbMin;
 			btScalar tmin=1.f,lambda_min=0.f;
 			unsigned int result1=false;
@@ -1001,9 +1002,9 @@
 			rayDir.normalize ();
 
-			///what about division by zero? --> just set rayDirection[i] to INF/1e30
+			///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
 			btVector3 rayDirectionInverse;
-			rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
-			rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
-			rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+			rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
+			rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
+			rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
 			unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2007 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 ///btDbvtBroadphase implementation by Nathanael Presson
 
@@ -124,5 +125,5 @@
 	m_needcleanup		=	true;
 	m_releasepaircache	=	(paircache!=0)?false:true;
-	m_prediction		=	1/(btScalar)2;
+	m_prediction		=	0;
 	m_stageCurrent		=	0;
 	m_fixedleft			=	0;
@@ -250,4 +251,32 @@
 }
 
+
+struct	BroadphaseAabbTester : btDbvt::ICollide
+{
+	btBroadphaseAabbCallback& m_aabbCallback;
+	BroadphaseAabbTester(btBroadphaseAabbCallback& orgCallback)
+		:m_aabbCallback(orgCallback)
+	{
+	}
+	void					Process(const btDbvtNode* leaf)
+	{
+		btDbvtProxy*	proxy=(btDbvtProxy*)leaf->data;
+		m_aabbCallback.process(proxy);
+	}
+};	
+
+void	btDbvtBroadphase::aabbTest(const btVector3& aabbMin,const btVector3& aabbMax,btBroadphaseAabbCallback& aabbCallback)
+{
+	BroadphaseAabbTester callback(aabbCallback);
+
+	const ATTRIBUTE_ALIGNED16(btDbvtVolume)	bounds=btDbvtVolume::FromMM(aabbMin,aabbMax);
+		//process all children, that overlap with  the given AABB bounds
+	m_sets[0].collideTV(m_sets[0].m_root,bounds,callback);
+	m_sets[1].collideTV(m_sets[1].m_root,bounds,callback);
+
+}
+
+
+
 //
 void							btDbvtBroadphase::setAabb(		btBroadphaseProxy* absproxy,
@@ -315,4 +344,45 @@
 		}	
 	}
+}
+
+
+//
+void							btDbvtBroadphase::setAabbForceUpdate(		btBroadphaseProxy* absproxy,
+														  const btVector3& aabbMin,
+														  const btVector3& aabbMax,
+														  btDispatcher* /*dispatcher*/)
+{
+	btDbvtProxy*						proxy=(btDbvtProxy*)absproxy;
+	ATTRIBUTE_ALIGNED16(btDbvtVolume)	aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
+	bool	docollide=false;
+	if(proxy->stage==STAGECOUNT)
+	{/* fixed -> dynamic set	*/ 
+		m_sets[1].remove(proxy->leaf);
+		proxy->leaf=m_sets[0].insert(aabb,proxy);
+		docollide=true;
+	}
+	else
+	{/* dynamic set				*/ 
+		++m_updates_call;
+		/* Teleporting			*/ 
+		m_sets[0].update(proxy->leaf,aabb);
+		++m_updates_done;
+		docollide=true;
+	}
+	listremove(proxy,m_stageRoots[proxy->stage]);
+	proxy->m_aabbMin = aabbMin;
+	proxy->m_aabbMax = aabbMax;
+	proxy->stage	=	m_stageCurrent;
+	listappend(proxy,m_stageRoots[m_stageCurrent]);
+	if(docollide)
+	{
+		m_needcleanup=true;
+		if(!m_deferedcollide)
+		{
+			btDbvtTreeCollider	collider(this);
+			m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider);
+			m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider);
+		}
+	}	
 }
 
@@ -572,5 +642,4 @@
 		m_deferedcollide	=	false;
 		m_needcleanup		=	true;
-		m_prediction		=	1/(btScalar)2;
 		m_stageCurrent		=	0;
 		m_fixedleft			=	0;
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2007 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 ///btDbvtBroadphase implementation by Nathanael Presson
 #ifndef BT_DBVT_BROADPHASE_H
@@ -102,24 +103,43 @@
 	void							collide(btDispatcher* dispatcher);
 	void							optimize();
-	/* btBroadphaseInterface Implementation	*/ 
+	
+	/* btBroadphaseInterface Implementation	*/
 	btBroadphaseProxy*				createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
-	void							destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
-	void							setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
-	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+	virtual void					destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+	virtual void					setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+	virtual void					rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+	virtual void					aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
 
-	virtual void	getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
-	void							calculateOverlappingPairs(btDispatcher* dispatcher);
-	btOverlappingPairCache*			getOverlappingPairCache();
-	const btOverlappingPairCache*	getOverlappingPairCache() const;
-	void							getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
-	void							printStats();
-	static void						benchmark(btBroadphaseInterface*);
+	virtual void					getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+	virtual	void					calculateOverlappingPairs(btDispatcher* dispatcher);
+	virtual	btOverlappingPairCache*	getOverlappingPairCache();
+	virtual	const btOverlappingPairCache*	getOverlappingPairCache() const;
+	virtual	void					getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
+	virtual	void					printStats();
 
-
-	void	performDeferredRemoval(btDispatcher* dispatcher);
 
 	///reset broadphase internal structures, to ensure determinism/reproducability
 	virtual void resetPool(btDispatcher* dispatcher);
 
+	void	performDeferredRemoval(btDispatcher* dispatcher);
+	
+	void	setVelocityPrediction(btScalar prediction)
+	{
+		m_prediction = prediction;
+	}
+	btScalar getVelocityPrediction() const
+	{
+		return m_prediction;
+	}
+
+	///this setAabbForceUpdate is similar to setAabb but always forces the aabb update. 
+	///it is not part of the btBroadphaseInterface but specific to btDbvtBroadphase.
+	///it bypasses certain optimizations that prevent aabb updates (when the aabb shrinks), see
+	///http://code.google.com/p/bullet/issues/detail?id=223
+	void							setAabbForceUpdate(		btBroadphaseProxy* absproxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* /*dispatcher*/);
+
+	static void						benchmark(btBroadphaseInterface*);
+
+
 };
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h	(revision 8284)
@@ -47,6 +47,7 @@
 		m_useEpa(true),
 		m_allowedCcdPenetration(btScalar(0.04)),
-		m_useConvexConservativeDistanceUtil(true),
+		m_useConvexConservativeDistanceUtil(false),
 		m_convexConservativeDistanceThreshold(0.0f),
+		m_convexMaxDistanceUseCPT(false),
 		m_stackAllocator(0)
 	{
@@ -65,4 +66,5 @@
 	bool		m_useConvexConservativeDistanceUtil;
 	btScalar	m_convexConservativeDistanceThreshold;
+	bool		m_convexMaxDistanceUseCPT;
 	btStackAlloc*	m_stackAllocator;
 };
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h	(revision 8284)
@@ -134,6 +134,6 @@
 	virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
 	{
-		aabbMin.setValue(-1e30f,-1e30f,-1e30f);
-		aabbMax.setValue(1e30f,1e30f,1e30f);
+		aabbMin.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT);
+		aabbMax.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT);
 	}
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp	(revision 8284)
@@ -241,5 +241,5 @@
 	int count = m_overlappingPairArray.size();
 	int oldCapacity = m_overlappingPairArray.capacity();
-	void* mem = &m_overlappingPairArray.expand();
+	void* mem = &m_overlappingPairArray.expandNonInitializing();
 
 	//this is where we add an actual pair, so also call the 'ghost'
@@ -468,5 +468,5 @@
 		return 0;
 	
-	void* mem = &m_overlappingPairArray.expand();
+	void* mem = &m_overlappingPairArray.expandNonInitializing();
 	btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
 	
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h	(revision 8284)
@@ -458,4 +458,5 @@
 	virtual void	sortOverlappingPairs(btDispatcher* dispatcher)
 	{
+        (void) dispatcher;
 	}
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp	(revision 8284)
@@ -18,4 +18,5 @@
 #include "LinearMath/btAabbUtil2.h"
 #include "LinearMath/btIDebugDraw.h"
+#include "LinearMath/btSerializer.h"
 
 #define RAYAABB2
@@ -79,8 +80,8 @@
 btVector3 color[4]=
 {
-	btVector3(255,0,0),
-	btVector3(0,255,0),
-	btVector3(0,0,255),
-	btVector3(0,255,255)
+	btVector3(1,0,0),
+	btVector3(0,1,0),
+	btVector3(0,0,1),
+	btVector3(0,1,1)
 };
 #endif //DEBUG_PATCH_COLORS
@@ -475,7 +476,7 @@
 	///what about division by zero? --> just set rayDirection[i] to 1.0
 	btVector3 rayDirectionInverse;
-	rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
-	rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
-	rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+	rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
+	rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
+	rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
 	unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
 #endif
@@ -494,6 +495,6 @@
 		bounds[1] = rootNode->m_aabbMaxOrg;
 		/* Add box cast extents */
-		bounds[0] += aabbMin;
-		bounds[1] += aabbMax;
+		bounds[0] -= aabbMax;
+		bounds[1] -= aabbMin;
 
 		aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
@@ -562,7 +563,7 @@
 	lambda_max = rayDirection.dot(rayTarget-raySource);
 	///what about division by zero? --> just set rayDirection[i] to 1.0
-	rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDirection[0];
-	rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDirection[1];
-	rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDirection[2];
+	rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0];
+	rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[1];
+	rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[2];
 	unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0};
 #endif
@@ -618,6 +619,6 @@
 			bounds[1] = unQuantize(rootNode->m_quantizedAabbMax);
 			/* Add box cast extents */
-			bounds[0] += aabbMin;
-			bounds[1] += aabbMax;
+			bounds[0] -= aabbMax;
+			bounds[1] -= aabbMin;
 			btVector3 normal;
 #if 0
@@ -831,5 +832,5 @@
 }
 
-unsigned btQuantizedBvh::calculateSerializeBufferSize()
+unsigned btQuantizedBvh::calculateSerializeBufferSize() const
 {
 	unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding();
@@ -842,5 +843,5 @@
 }
 
-bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian)
+bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const
 {
 	btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
@@ -1144,5 +1145,231 @@
 }
 
-
-
-
+void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData)
+{
+	m_bvhAabbMax.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMax);
+	m_bvhAabbMin.deSerializeFloat(quantizedBvhFloatData.m_bvhAabbMin);
+	m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization);
+
+	m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex;
+	m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0;
+	
+	{
+		int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes;
+		m_contiguousNodes.resize(numElem);
+
+		if (numElem)
+		{
+			btOptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr;
+
+			for (int i=0;i<numElem;i++,memPtr++)
+			{
+				m_contiguousNodes[i].m_aabbMaxOrg.deSerializeFloat(memPtr->m_aabbMaxOrg);
+				m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg);
+				m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
+				m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
+				m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
+			}
+		}
+	}
+
+	{
+		int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes;
+		m_quantizedContiguousNodes.resize(numElem);
+		
+		if (numElem)
+		{
+			btQuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr;
+			for (int i=0;i<numElem;i++,memPtr++)
+			{
+				m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
+				m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
+			}
+		}
+	}
+
+	m_traversalMode = btTraversalMode(quantizedBvhFloatData.m_traversalMode);
+	
+	{
+		int numElem = quantizedBvhFloatData.m_numSubtreeHeaders;
+		m_SubtreeHeaders.resize(numElem);
+		if (numElem)
+		{
+			btBvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr;
+			for (int i=0;i<numElem;i++,memPtr++)
+			{
+				m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
+				m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
+				m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
+				m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
+				m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
+				m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
+				m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
+				m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
+			}
+		}
+	}
+}
+
+void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData)
+{
+	m_bvhAabbMax.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMax);
+	m_bvhAabbMin.deSerializeDouble(quantizedBvhDoubleData.m_bvhAabbMin);
+	m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization);
+
+	m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex;
+	m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0;
+	
+	{
+		int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes;
+		m_contiguousNodes.resize(numElem);
+
+		if (numElem)
+		{
+			btOptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr;
+
+			for (int i=0;i<numElem;i++,memPtr++)
+			{
+				m_contiguousNodes[i].m_aabbMaxOrg.deSerializeDouble(memPtr->m_aabbMaxOrg);
+				m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg);
+				m_contiguousNodes[i].m_escapeIndex = memPtr->m_escapeIndex;
+				m_contiguousNodes[i].m_subPart = memPtr->m_subPart;
+				m_contiguousNodes[i].m_triangleIndex = memPtr->m_triangleIndex;
+			}
+		}
+	}
+
+	{
+		int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes;
+		m_quantizedContiguousNodes.resize(numElem);
+		
+		if (numElem)
+		{
+			btQuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr;
+			for (int i=0;i<numElem;i++,memPtr++)
+			{
+				m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex = memPtr->m_escapeIndexOrTriangleIndex;
+				m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
+				m_quantizedContiguousNodes[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
+			}
+		}
+	}
+
+	m_traversalMode = btTraversalMode(quantizedBvhDoubleData.m_traversalMode);
+	
+	{
+		int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders;
+		m_SubtreeHeaders.resize(numElem);
+		if (numElem)
+		{
+			btBvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr;
+			for (int i=0;i<numElem;i++,memPtr++)
+			{
+				m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0] ;
+				m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1];
+				m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2];
+				m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0];
+				m_SubtreeHeaders[i].m_quantizedAabbMin[1] = memPtr->m_quantizedAabbMin[1];
+				m_SubtreeHeaders[i].m_quantizedAabbMin[2] = memPtr->m_quantizedAabbMin[2];
+				m_SubtreeHeaders[i].m_rootNodeIndex = memPtr->m_rootNodeIndex;
+				m_SubtreeHeaders[i].m_subtreeSize = memPtr->m_subtreeSize;
+			}
+		}
+	}
+
+}
+
+
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*	btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btQuantizedBvhData* quantizedData = (btQuantizedBvhData*)dataBuffer;
+	
+	m_bvhAabbMax.serialize(quantizedData->m_bvhAabbMax);
+	m_bvhAabbMin.serialize(quantizedData->m_bvhAabbMin);
+	m_bvhQuantization.serialize(quantizedData->m_bvhQuantization);
+
+	quantizedData->m_curNodeIndex = m_curNodeIndex;
+	quantizedData->m_useQuantization = m_useQuantization;
+	
+	quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size();
+	quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0);
+	if (quantizedData->m_contiguousNodesPtr)
+	{
+		int sz = sizeof(btOptimizedBvhNodeData);
+		int numElem = m_contiguousNodes.size();
+		btChunk* chunk = serializer->allocate(sz,numElem);
+		btOptimizedBvhNodeData* memPtr = (btOptimizedBvhNodeData*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			m_contiguousNodes[i].m_aabbMaxOrg.serialize(memPtr->m_aabbMaxOrg);
+			m_contiguousNodes[i].m_aabbMinOrg.serialize(memPtr->m_aabbMinOrg);
+			memPtr->m_escapeIndex = m_contiguousNodes[i].m_escapeIndex;
+			memPtr->m_subPart = m_contiguousNodes[i].m_subPart;
+			memPtr->m_triangleIndex = m_contiguousNodes[i].m_triangleIndex;
+		}
+		serializer->finalizeChunk(chunk,"btOptimizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_contiguousNodes[0]);
+	}
+
+	quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size();
+//	printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes);
+	quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0);
+	if (quantizedData->m_quantizedContiguousNodesPtr)
+	{
+		int sz = sizeof(btQuantizedBvhNodeData);
+		int numElem = m_quantizedContiguousNodes.size();
+		btChunk* chunk = serializer->allocate(sz,numElem);
+		btQuantizedBvhNodeData* memPtr = (btQuantizedBvhNodeData*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			memPtr->m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex;
+			memPtr->m_quantizedAabbMax[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[0];
+			memPtr->m_quantizedAabbMax[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[1];
+			memPtr->m_quantizedAabbMax[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[2];
+			memPtr->m_quantizedAabbMin[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[0];
+			memPtr->m_quantizedAabbMin[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[1];
+			memPtr->m_quantizedAabbMin[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[2];
+		}
+		serializer->finalizeChunk(chunk,"btQuantizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_quantizedContiguousNodes[0]);
+	}
+
+	quantizedData->m_traversalMode = int(m_traversalMode);
+	quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size();
+
+	quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0);
+	if (quantizedData->m_subTreeInfoPtr)
+	{
+		int sz = sizeof(btBvhSubtreeInfoData);
+		int numElem = m_SubtreeHeaders.size();
+		btChunk* chunk = serializer->allocate(sz,numElem);
+		btBvhSubtreeInfoData* memPtr = (btBvhSubtreeInfoData*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			memPtr->m_quantizedAabbMax[0] = m_SubtreeHeaders[i].m_quantizedAabbMax[0];
+			memPtr->m_quantizedAabbMax[1] = m_SubtreeHeaders[i].m_quantizedAabbMax[1];
+			memPtr->m_quantizedAabbMax[2] = m_SubtreeHeaders[i].m_quantizedAabbMax[2];
+			memPtr->m_quantizedAabbMin[0] = m_SubtreeHeaders[i].m_quantizedAabbMin[0];
+			memPtr->m_quantizedAabbMin[1] = m_SubtreeHeaders[i].m_quantizedAabbMin[1];
+			memPtr->m_quantizedAabbMin[2] = m_SubtreeHeaders[i].m_quantizedAabbMin[2];
+
+			memPtr->m_rootNodeIndex = m_SubtreeHeaders[i].m_rootNodeIndex;
+			memPtr->m_subtreeSize = m_SubtreeHeaders[i].m_subtreeSize;
+		}
+		serializer->finalizeChunk(chunk,"btBvhSubtreeInfoData",BT_ARRAY_CODE,(void*)&m_SubtreeHeaders[0]);
+	}
+	return btQuantizedBvhDataName;
+}
+
+
+
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h	(revision 8284)
@@ -17,4 +17,6 @@
 #define QUANTIZED_BVH_H
 
+class btSerializer;
+
 //#define DEBUG_CHECK_DEQUANTIZATION 1
 #ifdef DEBUG_CHECK_DEQUANTIZATION
@@ -29,4 +31,15 @@
 #include "LinearMath/btVector3.h"
 #include "LinearMath/btAlignedAllocator.h"
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btQuantizedBvhData btQuantizedBvhDoubleData
+#define btOptimizedBvhNodeData btOptimizedBvhNodeDoubleData
+#define btQuantizedBvhDataName "btQuantizedBvhDoubleData"
+#else
+#define btQuantizedBvhData btQuantizedBvhFloatData
+#define btOptimizedBvhNodeData btOptimizedBvhNodeFloatData
+#define btQuantizedBvhDataName "btQuantizedBvhFloatData"
+#endif
+
 
 
@@ -191,5 +204,5 @@
 
 	//This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
-	int m_subtreeHeaderCount;
+	mutable int m_subtreeHeaderCount;
 
 	
@@ -444,10 +457,11 @@
 	}
 
+////////////////////////////////////////////////////////////////////
 
 	/////Calculate space needed to store BVH for serialization
-	unsigned calculateSerializeBufferSize();
+	unsigned calculateSerializeBufferSize() const;
 
 	/// Data buffer MUST be 16 byte aligned
-	virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian);
+	virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const;
 
 	///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
@@ -455,4 +469,18 @@
 
 	static unsigned int getAlignmentSerializationPadding();
+//////////////////////////////////////////////////////////////////////
+
+	
+	virtual	int	calculateSerializeBufferSizeNew() const;
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;
+
+	virtual	void deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData);
+
+	virtual	void deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData);
+
+
+////////////////////////////////////////////////////////////////////
 
 	SIMD_FORCE_INLINE bool isQuantized()
@@ -471,3 +499,81 @@
 
 
+struct	btBvhSubtreeInfoData
+{
+	int			m_rootNodeIndex;
+	int			m_subtreeSize;
+	unsigned short m_quantizedAabbMin[3];
+	unsigned short m_quantizedAabbMax[3];
+};
+
+struct btOptimizedBvhNodeFloatData
+{
+	btVector3FloatData	m_aabbMinOrg;
+	btVector3FloatData	m_aabbMaxOrg;
+	int	m_escapeIndex;
+	int	m_subPart;
+	int	m_triangleIndex;
+	char m_pad[4];
+};
+
+struct btOptimizedBvhNodeDoubleData
+{
+	btVector3DoubleData	m_aabbMinOrg;
+	btVector3DoubleData	m_aabbMaxOrg;
+	int	m_escapeIndex;
+	int	m_subPart;
+	int	m_triangleIndex;
+	char	m_pad[4];
+};
+
+
+struct btQuantizedBvhNodeData
+{
+	unsigned short m_quantizedAabbMin[3];
+	unsigned short m_quantizedAabbMax[3];
+	int	m_escapeIndexOrTriangleIndex;
+};
+
+struct	btQuantizedBvhFloatData
+{
+	btVector3FloatData			m_bvhAabbMin;
+	btVector3FloatData			m_bvhAabbMax;
+	btVector3FloatData			m_bvhQuantization;
+	int					m_curNodeIndex;
+	int					m_useQuantization;
+	int					m_numContiguousLeafNodes;
+	int					m_numQuantizedContiguousNodes;
+	btOptimizedBvhNodeFloatData	*m_contiguousNodesPtr;
+	btQuantizedBvhNodeData		*m_quantizedContiguousNodesPtr;
+	btBvhSubtreeInfoData	*m_subTreeInfoPtr;
+	int					m_traversalMode;
+	int					m_numSubtreeHeaders;
+	
+};
+
+struct	btQuantizedBvhDoubleData
+{
+	btVector3DoubleData			m_bvhAabbMin;
+	btVector3DoubleData			m_bvhAabbMax;
+	btVector3DoubleData			m_bvhQuantization;
+	int							m_curNodeIndex;
+	int							m_useQuantization;
+	int							m_numContiguousLeafNodes;
+	int							m_numQuantizedContiguousNodes;
+	btOptimizedBvhNodeDoubleData	*m_contiguousNodesPtr;
+	btQuantizedBvhNodeData			*m_quantizedContiguousNodesPtr;
+
+	int							m_traversalMode;
+	int							m_numSubtreeHeaders;
+	btBvhSubtreeInfoData		*m_subTreeInfoPtr;
+};
+
+
+SIMD_FORCE_INLINE	int	btQuantizedBvh::calculateSerializeBufferSizeNew() const
+{
+	return sizeof(btQuantizedBvhData);
+}
+
+
+
 #endif //QUANTIZED_BVH_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp	(revision 8284)
@@ -21,4 +21,6 @@
 #include "LinearMath/btTransform.h"
 #include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btAabbUtil2.h"
+
 #include <new>
 
@@ -163,4 +165,21 @@
 		}
 		rayCallback.process(proxy);
+	}
+}
+
+
+void	btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback)
+{
+	for (int i=0; i <= m_LastHandleIndex; i++)
+	{
+		btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
+		if(!proxy->m_clientObject)
+		{
+			continue;
+		}
+		if (TestAabbAgainstAabb2(aabbMin,aabbMax,proxy->m_aabbMin,proxy->m_aabbMax))
+		{
+			callback.process(proxy);
+		}
 	}
 }
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h	(revision 8284)
@@ -137,4 +137,5 @@
 
 	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
+	virtual void	aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback);
 		
 	btOverlappingPairCache*	getOverlappingPairCache()
@@ -154,6 +155,6 @@
 	virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
 	{
-		aabbMin.setValue(-1e30f,-1e30f,-1e30f);
-		aabbMax.setValue(1e30f,1e30f,1e30f);
+		aabbMin.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT);
+		aabbMax.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT);
 	}
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CMakeLists.txt	(revision 8284)
@@ -6,7 +6,7 @@
 	BroadphaseCollision/btBroadphaseProxy.cpp
 	BroadphaseCollision/btCollisionAlgorithm.cpp
+	BroadphaseCollision/btDbvt.cpp
+	BroadphaseCollision/btDbvtBroadphase.cpp
 	BroadphaseCollision/btDispatcher.cpp
-	BroadphaseCollision/btDbvtBroadphase.cpp
-	BroadphaseCollision/btDbvt.cpp
 	BroadphaseCollision/btMultiSapBroadphase.cpp
 	BroadphaseCollision/btOverlappingPairCache.cpp
@@ -15,4 +15,7 @@
 
 	CollisionDispatch/btActivatingCollisionAlgorithm.cpp
+	CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
+	CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp
+	CollisionDispatch/btBoxBoxDetector.cpp
 	CollisionDispatch/btCollisionDispatcher.cpp
 	CollisionDispatch/btCollisionObject.cpp
@@ -20,20 +23,22 @@
 	CollisionDispatch/btCompoundCollisionAlgorithm.cpp
 	CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+	CollisionDispatch/btConvexConvexAlgorithm.cpp
+	CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
+	CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
 	CollisionDispatch/btDefaultCollisionConfiguration.cpp
-	CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
-	CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
-	CollisionDispatch/btBoxBoxDetector.cpp
+	CollisionDispatch/btEmptyCollisionAlgorithm.cpp
 	CollisionDispatch/btGhostObject.cpp
-	CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
-	CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
-	CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
-	CollisionDispatch/btConvexConvexAlgorithm.cpp
-	CollisionDispatch/btEmptyCollisionAlgorithm.cpp
+	CollisionDispatch/btInternalEdgeUtility.cpp
+	CollisionDispatch/btInternalEdgeUtility.h
 	CollisionDispatch/btManifoldResult.cpp
 	CollisionDispatch/btSimulationIslandManager.cpp
+	CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
+	CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
+	CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
 	CollisionDispatch/btUnionFind.cpp
 	CollisionDispatch/SphereTriangleDetector.cpp
 
 	CollisionShapes/btBoxShape.cpp
+	CollisionShapes/btBox2dShape.cpp
 	CollisionShapes/btBvhTriangleMeshShape.cpp
 	CollisionShapes/btCapsuleShape.cpp
@@ -43,7 +48,8 @@
 	CollisionShapes/btConeShape.cpp
 	CollisionShapes/btConvexHullShape.cpp
+	CollisionShapes/btConvexInternalShape.cpp
 	CollisionShapes/btConvexPointCloudShape.cpp
 	CollisionShapes/btConvexShape.cpp
-	CollisionShapes/btConvexInternalShape.cpp
+	CollisionShapes/btConvex2dShape.cpp
 	CollisionShapes/btConvexTriangleMeshShape.cpp
 	CollisionShapes/btCylinderShape.cpp
@@ -56,11 +62,11 @@
 	CollisionShapes/btPolyhedralConvexShape.cpp
 	CollisionShapes/btScaledBvhTriangleMeshShape.cpp
-	CollisionShapes/btTetrahedronShape.cpp
+	CollisionShapes/btShapeHull.cpp
 	CollisionShapes/btSphereShape.cpp
-	CollisionShapes/btShapeHull.cpp
 	CollisionShapes/btStaticPlaneShape.cpp
 	CollisionShapes/btStridingMeshInterface.cpp
+	CollisionShapes/btTetrahedronShape.cpp
+	CollisionShapes/btTriangleBuffer.cpp
 	CollisionShapes/btTriangleCallback.cpp
-	CollisionShapes/btTriangleBuffer.cpp
 	CollisionShapes/btTriangleIndexVertexArray.cpp
 	CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
@@ -69,17 +75,9 @@
 	CollisionShapes/btUniformScalingShape.cpp
 
-	Gimpact/btContactProcessing.cpp
-	Gimpact/btGImpactShape.cpp
-	Gimpact/btGImpactBvh.cpp
-	Gimpact/btGenericPoolAllocator.cpp
-	Gimpact/btGImpactCollisionAlgorithm.cpp
-	Gimpact/btTriangleShapeEx.cpp
-	Gimpact/btGImpactQuantizedBvh.cpp
-
 	NarrowPhaseCollision/btContinuousConvexCollision.cpp
+	NarrowPhaseCollision/btConvexCast.cpp
+	NarrowPhaseCollision/btGjkConvexCast.cpp
 	NarrowPhaseCollision/btGjkEpa2.cpp
 	NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
-	NarrowPhaseCollision/btConvexCast.cpp
-	NarrowPhaseCollision/btGjkConvexCast.cpp
 	NarrowPhaseCollision/btGjkPairDetector.cpp
 	NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
@@ -91,11 +89,4 @@
 COMPILATION_END
 
-COMPILATION_BEGIN BulletGImpactCompilation.cpp
-	Gimpact/gim_contact.cpp
-	Gimpact/gim_memory.cpp
-	Gimpact/gim_tri_collision.cpp
-	Gimpact/gim_box_set.cpp
-COMPILATION_END
-
 	# Headers
 	BroadphaseCollision/btAxisSweep3.h
@@ -103,7 +94,7 @@
 	BroadphaseCollision/btBroadphaseProxy.h
 	BroadphaseCollision/btCollisionAlgorithm.h
+	BroadphaseCollision/btDbvt.h
+	BroadphaseCollision/btDbvtBroadphase.h
 	BroadphaseCollision/btDispatcher.h
-	BroadphaseCollision/btDbvtBroadphase.h
-	BroadphaseCollision/btDbvt.h
 	BroadphaseCollision/btMultiSapBroadphase.h
 	BroadphaseCollision/btOverlappingPairCache.h
@@ -113,4 +104,7 @@
 
 	CollisionDispatch/btActivatingCollisionAlgorithm.h
+	CollisionDispatch/btBoxBoxCollisionAlgorithm.h
+	CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h
+	CollisionDispatch/btBoxBoxDetector.h
 	CollisionDispatch/btCollisionConfiguration.h
 	CollisionDispatch/btCollisionCreateFunc.h
@@ -120,23 +114,23 @@
 	CollisionDispatch/btCompoundCollisionAlgorithm.h
 	CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
+	CollisionDispatch/btConvexConvexAlgorithm.h
+	CollisionDispatch/btConvex2dConvex2dAlgorithm.h
+	CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
 	CollisionDispatch/btDefaultCollisionConfiguration.h
-	CollisionDispatch/btSphereSphereCollisionAlgorithm.h
-	CollisionDispatch/btBoxBoxCollisionAlgorithm.h
-	CollisionDispatch/btBoxBoxDetector.h
+	CollisionDispatch/btEmptyCollisionAlgorithm.h
 	CollisionDispatch/btGhostObject.h
-	CollisionDispatch/btSphereBoxCollisionAlgorithm.h
-	CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
-	CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
-	CollisionDispatch/btConvexConvexAlgorithm.h
-	CollisionDispatch/btEmptyCollisionAlgorithm.h
 	CollisionDispatch/btManifoldResult.h
 	CollisionDispatch/btSimulationIslandManager.h
+	CollisionDispatch/btSphereBoxCollisionAlgorithm.h
+	CollisionDispatch/btSphereSphereCollisionAlgorithm.h
+	CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
 	CollisionDispatch/btUnionFind.h
 	CollisionDispatch/SphereTriangleDetector.h
 
 	CollisionShapes/btBoxShape.h
+	CollisionShapes/btBox2dShape.h
 	CollisionShapes/btBvhTriangleMeshShape.h
 	CollisionShapes/btCapsuleShape.h
-	CollisionShapes/btCollisionMargin
+	CollisionShapes/btCollisionMargin.h
 	CollisionShapes/btCollisionShape.h
 	CollisionShapes/btCompoundShape.h
@@ -144,13 +138,14 @@
 	CollisionShapes/btConeShape.h
 	CollisionShapes/btConvexHullShape.h
+	CollisionShapes/btConvexInternalShape.h
 	CollisionShapes/btConvexPointCloudShape.h
 	CollisionShapes/btConvexShape.h
-	CollisionShapes/btConvexInternalShape.h
+	CollisionShapes/btConvex2dShape.h
 	CollisionShapes/btConvexTriangleMeshShape.h
 	CollisionShapes/btCylinderShape.h
 	CollisionShapes/btEmptyShape.h
 	CollisionShapes/btHeightfieldTerrainShape.h
+	CollisionShapes/btMaterial.h
 	CollisionShapes/btMinkowskiSumShape.h
-	CollisionShapes/btMaterial.h
 	CollisionShapes/btMultimaterialTriangleMeshShape.h
 	CollisionShapes/btMultiSphereShape.h
@@ -158,27 +153,18 @@
 	CollisionShapes/btPolyhedralConvexShape.h
 	CollisionShapes/btScaledBvhTriangleMeshShape.h
-	CollisionShapes/btTetrahedronShape.h
+	CollisionShapes/btShapeHull.h
 	CollisionShapes/btSphereShape.h
-	CollisionShapes/btShapeHull.h
 	CollisionShapes/btStaticPlaneShape.h
 	CollisionShapes/btStridingMeshInterface.h
+	CollisionShapes/btTetrahedronShape.h
+	CollisionShapes/btTriangleBuffer.h
 	CollisionShapes/btTriangleCallback.h
-	CollisionShapes/btTriangleBuffer.h
 	CollisionShapes/btTriangleIndexVertexArray.h
 	CollisionShapes/btTriangleIndexVertexMaterialArray.h
+	CollisionShapes/btTriangleInfoMap.h
 	CollisionShapes/btTriangleMesh.h
 	CollisionShapes/btTriangleMeshShape.h
+	CollisionShapes/btTriangleShape.h
 	CollisionShapes/btUniformScalingShape.h
-
-	Gimpact/btGImpactShape.h
-	Gimpact/gim_contact.h
-	Gimpact/btGImpactBvh.h
-	Gimpact/btGenericPoolAllocator.h
-	Gimpact/gim_memory.h
-	Gimpact/btGImpactCollisionAlgorithm.h
-	Gimpact/btTriangleShapeEx.h
-	Gimpact/gim_tri_collision.h
-	Gimpact/btGImpactQuantizedBvh.h
-	Gimpact/gim_box_set.h
 
 	NarrowPhaseCollision/btContinuousConvexCollision.h
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp	(revision 8284)
@@ -38,5 +38,5 @@
 	btScalar timeOfImpact = btScalar(1.);
 	btScalar depth = btScalar(0.);
-//	output.m_distance = btScalar(1e30);
+//	output.m_distance = btScalar(BT_LARGE_FLOAT);
 	//move sphere into triangle space
 	btTransform	sphereInTr = transformB.inverseTimes(transformA);
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h	(revision 8284)
@@ -35,7 +35,9 @@
 	virtual ~SphereTriangleDetector() {};
 
+	bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar	contactBreakingThreshold);
+
 private:
 
-	bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar	contactBreakingThreshold);
+	
 	bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
 	bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp	(revision 8284)
@@ -0,0 +1,435 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+* The b2CollidePolygons routines are Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+
+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.
+*/
+
+///btBox2dBox2dCollisionAlgorithm, with modified b2CollidePolygons routines from the Box2D library.
+///The modifications include: switching from b2Vec to btVector3, redefinition of b2Dot, b2Cross
+
+#include "btBox2dBox2dCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionDispatch/btBoxBoxDetector.h"
+#include "BulletCollision/CollisionShapes/btBox2dShape.h"
+
+#define USE_PERSISTENT_CONTACTS 1
+
+btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
+: btActivatingCollisionAlgorithm(ci,obj0,obj1),
+m_ownManifold(false),
+m_manifoldPtr(mf)
+{
+	if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
+	{
+		m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
+		m_ownManifold = true;
+	}
+}
+
+btBox2dBox2dCollisionAlgorithm::~btBox2dBox2dCollisionAlgorithm()
+{
+	
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr)
+			m_dispatcher->releaseManifold(m_manifoldPtr);
+	}
+	
+}
+
+
+void b2CollidePolygons(btManifoldResult* manifold,  const btBox2dShape* polyA, const btTransform& xfA, const btBox2dShape* polyB, const btTransform& xfB);
+
+//#include <stdio.h>
+void btBox2dBox2dCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	if (!m_manifoldPtr)
+		return;
+
+	btCollisionObject*	col0 = body0;
+	btCollisionObject*	col1 = body1;
+	btBox2dShape* box0 = (btBox2dShape*)col0->getCollisionShape();
+	btBox2dShape* box1 = (btBox2dShape*)col1->getCollisionShape();
+
+	resultOut->setPersistentManifold(m_manifoldPtr);
+
+	b2CollidePolygons(resultOut,box0,col0->getWorldTransform(),box1,col1->getWorldTransform());
+
+	//  refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added
+	if (m_ownManifold)
+	{
+		resultOut->refreshContactPoints();
+	}
+
+}
+
+btScalar btBox2dBox2dCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/)
+{
+	//not yet
+	return 1.f;
+}
+
+
+struct ClipVertex
+{
+	btVector3 v;
+	int id;
+	//b2ContactID id;
+	//b2ContactID id;
+};
+
+#define b2Dot(a,b) (a).dot(b)
+#define b2Mul(a,b) (a)*(b)
+#define b2MulT(a,b) (a).transpose()*(b)
+#define b2Cross(a,b) (a).cross(b)
+#define btCrossS(a,s) btVector3(s * a.getY(), -s * a.getX(),0.f)
+
+int b2_maxManifoldPoints =2;
+
+static int ClipSegmentToLine(ClipVertex vOut[2], ClipVertex vIn[2],
+					  const btVector3& normal, btScalar offset)
+{
+	// Start with no output points
+	int numOut = 0;
+
+	// Calculate the distance of end points to the line
+	btScalar distance0 = b2Dot(normal, vIn[0].v) - offset;
+	btScalar distance1 = b2Dot(normal, vIn[1].v) - offset;
+
+	// If the points are behind the plane
+	if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];
+	if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];
+
+	// If the points are on different sides of the plane
+	if (distance0 * distance1 < 0.0f)
+	{
+		// Find intersection point of edge and plane
+		btScalar interp = distance0 / (distance0 - distance1);
+		vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
+		if (distance0 > 0.0f)
+		{
+			vOut[numOut].id = vIn[0].id;
+		}
+		else
+		{
+			vOut[numOut].id = vIn[1].id;
+		}
+		++numOut;
+	}
+
+	return numOut;
+}
+
+// Find the separation between poly1 and poly2 for a give edge normal on poly1.
+static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1, int edge1,
+							  const btBox2dShape* poly2, const btTransform& xf2)
+{
+	const btVector3* vertices1 = poly1->getVertices();
+	const btVector3* normals1 = poly1->getNormals();
+
+	int count2 = poly2->getVertexCount();
+	const btVector3* vertices2 = poly2->getVertices();
+
+	btAssert(0 <= edge1 && edge1 < poly1->getVertexCount());
+
+	// Convert normal from poly1's frame into poly2's frame.
+	btVector3 normal1World = b2Mul(xf1.getBasis(), normals1[edge1]);
+	btVector3 normal1 = b2MulT(xf2.getBasis(), normal1World);
+
+	// Find support vertex on poly2 for -normal.
+	int index = 0;
+	btScalar minDot = BT_LARGE_FLOAT;
+
+	for (int i = 0; i < count2; ++i)
+	{
+		btScalar dot = b2Dot(vertices2[i], normal1);
+		if (dot < minDot)
+		{
+			minDot = dot;
+			index = i;
+		}
+	}
+
+	btVector3 v1 = b2Mul(xf1, vertices1[edge1]);
+	btVector3 v2 = b2Mul(xf2, vertices2[index]);
+	btScalar separation = b2Dot(v2 - v1, normal1World);
+	return separation;
+}
+
+// Find the max separation between poly1 and poly2 using edge normals from poly1.
+static btScalar FindMaxSeparation(int* edgeIndex,
+								 const btBox2dShape* poly1, const btTransform& xf1,
+								 const btBox2dShape* poly2, const btTransform& xf2)
+{
+	int count1 = poly1->getVertexCount();
+	const btVector3* normals1 = poly1->getNormals();
+
+	// Vector pointing from the centroid of poly1 to the centroid of poly2.
+	btVector3 d = b2Mul(xf2, poly2->getCentroid()) - b2Mul(xf1, poly1->getCentroid());
+	btVector3 dLocal1 = b2MulT(xf1.getBasis(), d);
+
+	// Find edge normal on poly1 that has the largest projection onto d.
+	int edge = 0;
+	btScalar maxDot = -BT_LARGE_FLOAT;
+	for (int i = 0; i < count1; ++i)
+	{
+		btScalar dot = b2Dot(normals1[i], dLocal1);
+		if (dot > maxDot)
+		{
+			maxDot = dot;
+			edge = i;
+		}
+	}
+
+	// Get the separation for the edge normal.
+	btScalar s = EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+	if (s > 0.0f)
+	{
+		return s;
+	}
+
+	// Check the separation for the previous edge normal.
+	int prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1;
+	btScalar sPrev = EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2);
+	if (sPrev > 0.0f)
+	{
+		return sPrev;
+	}
+
+	// Check the separation for the next edge normal.
+	int nextEdge = edge + 1 < count1 ? edge + 1 : 0;
+	btScalar sNext = EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2);
+	if (sNext > 0.0f)
+	{
+		return sNext;
+	}
+
+	// Find the best edge and the search direction.
+	int bestEdge;
+	btScalar bestSeparation;
+	int increment;
+	if (sPrev > s && sPrev > sNext)
+	{
+		increment = -1;
+		bestEdge = prevEdge;
+		bestSeparation = sPrev;
+	}
+	else if (sNext > s)
+	{
+		increment = 1;
+		bestEdge = nextEdge;
+		bestSeparation = sNext;
+	}
+	else
+	{
+		*edgeIndex = edge;
+		return s;
+	}
+
+	// Perform a local search for the best edge normal.
+	for ( ; ; )
+	{
+		if (increment == -1)
+			edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;
+		else
+			edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;
+
+		s = EdgeSeparation(poly1, xf1, edge, poly2, xf2);
+		if (s > 0.0f)
+		{
+			return s;
+		}
+
+		if (s > bestSeparation)
+		{
+			bestEdge = edge;
+			bestSeparation = s;
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	*edgeIndex = bestEdge;
+	return bestSeparation;
+}
+
+static void FindIncidentEdge(ClipVertex c[2],
+							 const btBox2dShape* poly1, const btTransform& xf1, int edge1,
+							 const btBox2dShape* poly2, const btTransform& xf2)
+{
+	const btVector3* normals1 = poly1->getNormals();
+
+	int count2 = poly2->getVertexCount();
+	const btVector3* vertices2 = poly2->getVertices();
+	const btVector3* normals2 = poly2->getNormals();
+
+	btAssert(0 <= edge1 && edge1 < poly1->getVertexCount());
+
+	// Get the normal of the reference edge in poly2's frame.
+	btVector3 normal1 = b2MulT(xf2.getBasis(), b2Mul(xf1.getBasis(), normals1[edge1]));
+
+	// Find the incident edge on poly2.
+	int index = 0;
+	btScalar minDot = BT_LARGE_FLOAT;
+	for (int i = 0; i < count2; ++i)
+	{
+		btScalar dot = b2Dot(normal1, normals2[i]);
+		if (dot < minDot)
+		{
+			minDot = dot;
+			index = i;
+		}
+	}
+
+	// Build the clip vertices for the incident edge.
+	int i1 = index;
+	int i2 = i1 + 1 < count2 ? i1 + 1 : 0;
+
+	c[0].v = b2Mul(xf2, vertices2[i1]);
+//	c[0].id.features.referenceEdge = (unsigned char)edge1;
+//	c[0].id.features.incidentEdge = (unsigned char)i1;
+//	c[0].id.features.incidentVertex = 0;
+
+	c[1].v = b2Mul(xf2, vertices2[i2]);
+//	c[1].id.features.referenceEdge = (unsigned char)edge1;
+//	c[1].id.features.incidentEdge = (unsigned char)i2;
+//	c[1].id.features.incidentVertex = 1;
+}
+
+// Find edge normal of max separation on A - return if separating axis is found
+// Find edge normal of max separation on B - return if separation axis is found
+// Choose reference edge as min(minA, minB)
+// Find incident edge
+// Clip
+
+// The normal points from 1 to 2
+void b2CollidePolygons(btManifoldResult* manifold,
+					  const btBox2dShape* polyA, const btTransform& xfA,
+					  const btBox2dShape* polyB, const btTransform& xfB)
+{
+
+	int edgeA = 0;
+	btScalar separationA = FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB);
+	if (separationA > 0.0f)
+		return;
+
+	int edgeB = 0;
+	btScalar separationB = FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA);
+	if (separationB > 0.0f)
+		return;
+
+	const btBox2dShape* poly1;	// reference poly
+	const btBox2dShape* poly2;	// incident poly
+	btTransform xf1, xf2;
+	int edge1;		// reference edge
+	unsigned char flip;
+	const btScalar k_relativeTol = 0.98f;
+	const btScalar k_absoluteTol = 0.001f;
+
+	// TODO_ERIN use "radius" of poly for absolute tolerance.
+	if (separationB > k_relativeTol * separationA + k_absoluteTol)
+	{
+		poly1 = polyB;
+		poly2 = polyA;
+		xf1 = xfB;
+		xf2 = xfA;
+		edge1 = edgeB;
+		flip = 1;
+	}
+	else
+	{
+		poly1 = polyA;
+		poly2 = polyB;
+		xf1 = xfA;
+		xf2 = xfB;
+		edge1 = edgeA;
+		flip = 0;
+	}
+
+	ClipVertex incidentEdge[2];
+	FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);
+
+	int count1 = poly1->getVertexCount();
+	const btVector3* vertices1 = poly1->getVertices();
+
+	btVector3 v11 = vertices1[edge1];
+	btVector3 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0];
+
+	btVector3 dv = v12 - v11;
+	btVector3 sideNormal = b2Mul(xf1.getBasis(), v12 - v11);
+	sideNormal.normalize();
+	btVector3 frontNormal = btCrossS(sideNormal, 1.0f);
+	
+	
+	v11 = b2Mul(xf1, v11);
+	v12 = b2Mul(xf1, v12);
+
+	btScalar frontOffset = b2Dot(frontNormal, v11);
+	btScalar sideOffset1 = -b2Dot(sideNormal, v11);
+	btScalar sideOffset2 = b2Dot(sideNormal, v12);
+
+	// Clip incident edge against extruded edge1 side edges.
+	ClipVertex clipPoints1[2];
+	clipPoints1[0].v.setValue(0,0,0);
+	clipPoints1[1].v.setValue(0,0,0);
+
+	ClipVertex clipPoints2[2];
+	clipPoints2[0].v.setValue(0,0,0);
+	clipPoints2[1].v.setValue(0,0,0);
+
+
+	int np;
+
+	// Clip to box side 1
+	np = ClipSegmentToLine(clipPoints1, incidentEdge, -sideNormal, sideOffset1);
+
+	if (np < 2)
+		return;
+
+	// Clip to negative box side 1
+	np = ClipSegmentToLine(clipPoints2, clipPoints1,  sideNormal, sideOffset2);
+
+	if (np < 2)
+	{
+		return;
+	}
+
+	// Now clipPoints2 contains the clipped points.
+	btVector3 manifoldNormal = flip ? -frontNormal : frontNormal;
+
+	int pointCount = 0;
+	for (int i = 0; i < b2_maxManifoldPoints; ++i)
+	{
+		btScalar separation = b2Dot(frontNormal, clipPoints2[i].v) - frontOffset;
+
+		if (separation <= 0.0f)
+		{
+			
+			//b2ManifoldPoint* cp = manifold->points + pointCount;
+			//btScalar separation = separation;
+			//cp->localPoint1 = b2MulT(xfA, clipPoints2[i].v);
+			//cp->localPoint2 = b2MulT(xfB, clipPoints2[i].v);
+
+			manifold->addContactPoint(-manifoldNormal,clipPoints2[i].v,separation);
+
+//			cp->id = clipPoints2[i].id;
+//			cp->id.features.flip = flip;
+			++pointCount;
+		}
+	}
+
+//	manifold->pointCount = pointCount;}
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h	(revision 8284)
@@ -0,0 +1,66 @@
+/*
+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 BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
+#define BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
+
+#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+
+class btPersistentManifold;
+
+///box-box collision detection
+class btBox2dBox2dCollisionAlgorithm : public btActivatingCollisionAlgorithm
+{
+	bool	m_ownManifold;
+	btPersistentManifold*	m_manifoldPtr;
+	
+public:
+	btBox2dBox2dCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
+		: btActivatingCollisionAlgorithm(ci) {}
+
+	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+
+	virtual ~btBox2dBox2dCollisionAlgorithm();
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray)
+	{
+		if (m_manifoldPtr && m_ownManifold)
+		{
+			manifoldArray.push_back(m_manifoldPtr);
+		}
+	}
+
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			int bbsize = sizeof(btBox2dBox2dCollisionAlgorithm);
+			void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
+			return new(ptr) btBox2dBox2dCollisionAlgorithm(0,ci,body0,body1);
+		}
+	};
+
+};
+
+#endif //BOX_2D_BOX_2D__COLLISION_ALGORITHM_H
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp	(revision 8284)
@@ -62,5 +62,5 @@
 
 	btDiscreteCollisionDetectorInterface::ClosestPointInput input;
-	input.m_maximumDistanceSquared = 1e30f;
+	input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
 	input.m_transformA = body0->getWorldTransform();
 	input.m_transformB = body1->getWorldTransform();
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp	(revision 8284)
@@ -1,3 +1,2 @@
-
 /*
  * Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith
@@ -213,5 +212,5 @@
 	} else
 	{
-		a=1e30f;
+		a=BT_LARGE_FLOAT;
 	}
     cx = a*(cx + q*(p[n*2-2]+p[0]));
@@ -268,5 +267,5 @@
 {
   const btScalar fudge_factor = btScalar(1.05);
-  btVector3 p,pp,normalC;
+  btVector3 p,pp,normalC(0.f,0.f,0.f);
   const btScalar *normalR = 0;
   btScalar A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33,
@@ -334,7 +333,7 @@
 #define TST(expr1,expr2,n1,n2,n3,cc) \
   s2 = btFabs(expr1) - (expr2); \
-  if (s2 > 0) return 0; \
+  if (s2 > SIMD_EPSILON) return 0; \
   l = btSqrt((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \
-  if (l > 0) { \
+  if (l > SIMD_EPSILON) { \
     s2 /= l; \
     if (s2*fudge_factor > s) { \
@@ -346,4 +345,18 @@
     } \
   }
+
+  btScalar fudge2 (1.0e-5f);
+
+  Q11 += fudge2;
+  Q12 += fudge2;
+  Q13 += fudge2;
+
+  Q21 += fudge2;
+  Q22 += fudge2;
+  Q23 += fudge2;
+
+  Q31 += fudge2;
+  Q32 += fudge2;
+  Q33 += fudge2;
 
   // separating axis = u1 x (v1,v2,v3)
@@ -425,4 +438,5 @@
 #else
 		output.addContactPoint(-normal,pb,-*depth);
+
 #endif //
 		*return_code = code;
@@ -594,13 +608,10 @@
 
   if (cnum <= maxc) {
+
+	  if (code<4) 
+	  {
     // we have less contacts than we need, so we use them all
-    for (j=0; j < cnum; j++) {
-
-		//AddContactPoint...
-
-		//dContactGeom *con = CONTACT(contact,skip*j);
-      //for (i=0; i<3; i++) con->pos[i] = point[j*3+i] + pa[i];
-      //con->depth = dep[j];
-
+    for (j=0; j < cnum; j++) 
+	{
 		btVector3 pointInWorld;
 		for (i=0; i<3; i++) 
@@ -609,4 +620,16 @@
 
     }
+	  } else
+	  {
+		  // we have less contacts than we need, so we use them all
+		for (j=0; j < cnum; j++) 
+		{
+			btVector3 pointInWorld;
+			for (i=0; i<3; i++) 
+				pointInWorld[i] = point[j*3+i] + pa[i]-normal[i]*dep[j];
+				//pointInWorld[i] = point[j*3+i] + pa[i];
+			output.addContactPoint(-normal,pointInWorld,-dep[j]);
+		}
+	  }
   }
   else {
@@ -633,5 +656,11 @@
 		for (i=0; i<3; i++) 
 			posInWorld[i] = point[iret[j]*3+i] + pa[i];
-		output.addContactPoint(-normal,posInWorld,-dep[iret[j]]);
+		if (code<4) 
+	   {
+			output.addContactPoint(-normal,posInWorld,-dep[iret[j]]);
+		} else
+		{
+			output.addContactPoint(-normal,posInWorld-normal*dep[iret[j]],-dep[iret[j]]);
+		}
     }
     cnum = maxc;
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp	(revision 8284)
@@ -35,7 +35,5 @@
 
 btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration): 
-	m_count(0),
-	m_useIslands(true),
-	m_staticWarningReported(false),
+m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD),
 	m_collisionConfiguration(collisionConfiguration)
 {
@@ -80,7 +78,9 @@
 	btCollisionObject* body1 = (btCollisionObject*)b1;
 
-	//test for Bullet 2.74: use a relative contact breaking threshold without clamping against 'gContactBreakingThreshold'
-	//btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold()));
-	btScalar contactBreakingThreshold = btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold());
+	//optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance)
+	
+	btScalar contactBreakingThreshold =  (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ? 
+		btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold) , body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold))
+		: gContactBreakingThreshold ;
 
 	btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
@@ -170,5 +170,5 @@
 
 #ifdef BT_DEBUG
-	if (!m_staticWarningReported)
+	if (!(m_dispatcherFlags & btCollisionDispatcher::CD_STATIC_STATIC_REPORTED))
 	{
 		//broadphase filtering already deals with this
@@ -176,5 +176,5 @@
 			(body1->isStaticObject() || body1->isKinematicObject()))
 		{
-			m_staticWarningReported = true;
+			m_dispatcherFlags |= btCollisionDispatcher::CD_STATIC_STATIC_REPORTED;
 			printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
 		}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h	(revision 8284)
@@ -43,12 +43,8 @@
 class btCollisionDispatcher : public btDispatcher
 {
-	int m_count;
+	int		m_dispatcherFlags;
 	
 	btAlignedObjectArray<btPersistentManifold*>	m_manifoldsPtr;
 
-	bool m_useIslands;
-
-	bool	m_staticWarningReported;
-	
 	btManifoldResult	m_defaultManifoldResult;
 
@@ -60,5 +56,4 @@
 
 	btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
-	
 
 	btCollisionConfiguration*	m_collisionConfiguration;
@@ -66,4 +61,21 @@
 
 public:
+
+	enum DispatcherFlags
+	{
+		CD_STATIC_STATIC_REPORTED = 1,
+		CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD = 2
+	};
+
+	int	getDispatcherFlags() const
+	{
+		return m_dispatcherFlags;
+	}
+
+	void	setDispatcherFlags(int flags)
+	{
+        (void) flags;
+		m_dispatcherFlags = 0;
+	}
 
 	///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp	(revision 8284)
@@ -16,11 +16,13 @@
 
 #include "btCollisionObject.h"
+#include "LinearMath/btSerializer.h"
 
 btCollisionObject::btCollisionObject()
 	:	m_anisotropicFriction(1.f,1.f,1.f),
 	m_hasAnisotropicFriction(false),
-	m_contactProcessingThreshold(1e30f),
+	m_contactProcessingThreshold(BT_LARGE_FLOAT),
 		m_broadphaseHandle(0),
 		m_collisionShape(0),
+		m_extensionPointer(0),
 		m_rootCollisionShape(0),
 		m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT),
@@ -31,6 +33,6 @@
 		m_friction(btScalar(0.5)),
 		m_restitution(btScalar(0.)),
+		m_internalType(CO_COLLISION_OBJECT),
 		m_userObjectPointer(0),
-		m_internalType(CO_COLLISION_OBJECT),
 		m_hitFraction(btScalar(1.)),
 		m_ccdSweptSphereRadius(btScalar(0.)),
@@ -38,5 +40,5 @@
 		m_checkCollideWith(false)
 {
-	
+	m_worldTransform.setIdentity();
 }
 
@@ -65,4 +67,50 @@
 }
 
+const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+
+	btCollisionObjectData* dataOut = (btCollisionObjectData*)dataBuffer;
+
+	m_worldTransform.serialize(dataOut->m_worldTransform);
+	m_interpolationWorldTransform.serialize(dataOut->m_interpolationWorldTransform);
+	m_interpolationLinearVelocity.serialize(dataOut->m_interpolationLinearVelocity);
+	m_interpolationAngularVelocity.serialize(dataOut->m_interpolationAngularVelocity);
+	m_anisotropicFriction.serialize(dataOut->m_anisotropicFriction);
+	dataOut->m_hasAnisotropicFriction = m_hasAnisotropicFriction;
+	dataOut->m_contactProcessingThreshold = m_contactProcessingThreshold;
+	dataOut->m_broadphaseHandle = 0;
+	dataOut->m_collisionShape = serializer->getUniquePointer(m_collisionShape);
+	dataOut->m_rootCollisionShape = 0;//@todo
+	dataOut->m_collisionFlags = m_collisionFlags;
+	dataOut->m_islandTag1 = m_islandTag1;
+	dataOut->m_companionId = m_companionId;
+	dataOut->m_activationState1 = m_activationState1;
+	dataOut->m_activationState1 = m_activationState1;
+	dataOut->m_deactivationTime = m_deactivationTime;
+	dataOut->m_friction = m_friction;
+	dataOut->m_restitution = m_restitution;
+	dataOut->m_internalType = m_internalType;
+	
+	char* name = (char*) serializer->findNameForPointer(this);
+	dataOut->m_name = (char*)serializer->getUniquePointer(name);
+	if (dataOut->m_name)
+	{
+		serializer->serializeName(name);
+	}
+	dataOut->m_hitFraction = m_hitFraction;
+	dataOut->m_ccdSweptSphereRadius = m_ccdSweptSphereRadius;
+	dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
+	dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
+	dataOut->m_checkCollideWith = m_checkCollideWith;
+
+	return btCollisionObjectDataName;
+}
 
 
+void btCollisionObject::serializeSingleObject(class btSerializer* serializer) const
+{
+	int len = calculateSerializeBufferSize();
+	btChunk* chunk = serializer->allocate(len,1);
+	const char* structType = serialize(chunk->m_oldPtr, serializer);
+	serializer->finalizeChunk(chunk,structType,BT_COLLISIONOBJECT_CODE,(void*)this);
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h	(revision 8284)
@@ -28,10 +28,18 @@
 struct	btBroadphaseProxy;
 class	btCollisionShape;
+struct btCollisionShapeData;
 #include "LinearMath/btMotionState.h"
 #include "LinearMath/btAlignedAllocator.h"
 #include "LinearMath/btAlignedObjectArray.h"
 
-
 typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btCollisionObjectData btCollisionObjectDoubleData
+#define btCollisionObjectDataName "btCollisionObjectDoubleData"
+#else
+#define btCollisionObjectData btCollisionObjectFloatData
+#define btCollisionObjectDataName "btCollisionObjectFloatData"
+#endif
 
 
@@ -54,10 +62,12 @@
 	btVector3	m_interpolationAngularVelocity;
 	
-	btVector3		m_anisotropicFriction;
-	bool				m_hasAnisotropicFriction;
-	btScalar		m_contactProcessingThreshold;	
+	btVector3	m_anisotropicFriction;
+	int			m_hasAnisotropicFriction;
+	btScalar	m_contactProcessingThreshold;	
 
 	btBroadphaseProxy*		m_broadphaseHandle;
 	btCollisionShape*		m_collisionShape;
+	///m_extensionPointer is used by some internal low-level Bullet extensions.
+	void*					m_extensionPointer;
 	
 	///m_rootCollisionShape is temporarily used to store the original collision shape
@@ -77,11 +87,11 @@
 	btScalar		m_restitution;
 
-	///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
-	void*			m_userObjectPointer;
-
 	///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
 	///do not assign your own m_internalType unless you write a new dynamics object class.
 	int				m_internalType;
 
+	///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
+	void*			m_userObjectPointer;
+
 	///time of impact calculation
 	btScalar		m_hitFraction; 
@@ -94,7 +104,5 @@
 	
 	/// If some object should have elaborate collision filtering by sub-classes
-	bool			m_checkCollideWith;
-
-	char	m_pad[7];
+	int			m_checkCollideWith;
 
 	virtual bool	checkCollideWithOverride(btCollisionObject* /* co */)
@@ -113,5 +121,7 @@
 		CF_NO_CONTACT_RESPONSE = 4,
 		CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
-		CF_CHARACTER_OBJECT = 16
+		CF_CHARACTER_OBJECT = 16,
+		CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing
+		CF_DISABLE_SPU_COLLISION_PROCESSING = 64//disable parallel/SPU processing
 	};
 
@@ -119,10 +129,11 @@
 	{
 		CO_COLLISION_OBJECT =1,
-		CO_RIGID_BODY,
+		CO_RIGID_BODY=2,
 		///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
 		///It is useful for collision sensors, explosion objects, character controller etc.
-		CO_GHOST_OBJECT,
-		CO_SOFT_BODY,
-		CO_HF_FLUID
+		CO_GHOST_OBJECT=4,
+		CO_SOFT_BODY=8,
+		CO_HF_FLUID=16,
+		CO_USER_TYPE=32
 	};
 
@@ -144,5 +155,5 @@
 	bool	hasAnisotropicFriction() const
 	{
-		return m_hasAnisotropicFriction;
+		return m_hasAnisotropicFriction!=0;
 	}
 
@@ -214,4 +225,17 @@
 	}
 
+	///Avoid using this internal API call, the extension pointer is used by some Bullet extensions. 
+	///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
+	void*		internalGetExtensionPointer() const
+	{
+		return m_extensionPointer;
+	}
+	///Avoid using this internal API call, the extension pointer is used by some Bullet extensions
+	///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
+	void	internalSetExtensionPointer(void* pointer)
+	{
+		m_extensionPointer = pointer;
+	}
+
 	SIMD_FORCE_INLINE	int	getActivationState() const { return m_activationState1;}
 	
@@ -394,5 +418,5 @@
 	void	setCcdMotionThreshold(btScalar ccdMotionThreshold)
 	{
-		m_ccdMotionThreshold = ccdMotionThreshold*ccdMotionThreshold;
+		m_ccdMotionThreshold = ccdMotionThreshold;
 	}
 
@@ -417,5 +441,84 @@
 		return true;
 	}
+
+	virtual	int	calculateSerializeBufferSize()	const;
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+	virtual	const char*	serialize(void* dataBuffer, class btSerializer* serializer) const;
+
+	virtual void serializeSingleObject(class btSerializer* serializer) const;
+
 };
 
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btCollisionObjectDoubleData
+{
+	void					*m_broadphaseHandle;
+	void					*m_collisionShape;
+	btCollisionShapeData	*m_rootCollisionShape;
+	char					*m_name;
+
+	btTransformDoubleData	m_worldTransform;
+	btTransformDoubleData	m_interpolationWorldTransform;
+	btVector3DoubleData		m_interpolationLinearVelocity;
+	btVector3DoubleData		m_interpolationAngularVelocity;
+	btVector3DoubleData		m_anisotropicFriction;
+	double					m_contactProcessingThreshold;	
+	double					m_deactivationTime;
+	double					m_friction;
+	double					m_restitution;
+	double					m_hitFraction; 
+	double					m_ccdSweptSphereRadius;
+	double					m_ccdMotionThreshold;
+
+	int						m_hasAnisotropicFriction;
+	int						m_collisionFlags;
+	int						m_islandTag1;
+	int						m_companionId;
+	int						m_activationState1;
+	int						m_internalType;
+	int						m_checkCollideWith;
+
+	char	m_padding[4];
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btCollisionObjectFloatData
+{
+	void					*m_broadphaseHandle;
+	void					*m_collisionShape;
+	btCollisionShapeData	*m_rootCollisionShape;
+	char					*m_name;
+
+	btTransformFloatData	m_worldTransform;
+	btTransformFloatData	m_interpolationWorldTransform;
+	btVector3FloatData		m_interpolationLinearVelocity;
+	btVector3FloatData		m_interpolationAngularVelocity;
+	btVector3FloatData		m_anisotropicFriction;
+	float					m_contactProcessingThreshold;	
+	float					m_deactivationTime;
+	float					m_friction;
+	float					m_restitution;
+	float					m_hitFraction; 
+	float					m_ccdSweptSphereRadius;
+	float					m_ccdMotionThreshold;
+
+	int						m_hasAnisotropicFriction;
+	int						m_collisionFlags;
+	int						m_islandTag1;
+	int						m_companionId;
+	int						m_activationState1;
+	int						m_internalType;
+	int						m_checkCollideWith;
+};
+
+
+
+SIMD_FORCE_INLINE	int	btCollisionObject::calculateSerializeBufferSize() const
+{
+	return sizeof(btCollisionObjectData);
+}
+
+
+
 #endif //COLLISION_OBJECT_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp	(revision 8284)
@@ -27,9 +27,10 @@
 #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
 #include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
-
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
 #include "LinearMath/btAabbUtil2.h"
 #include "LinearMath/btQuickprof.h"
 #include "LinearMath/btStackAlloc.h"
+#include "LinearMath/btSerializer.h"
 
 //#define USE_BRUTEFORCE_RAYBROADPHASE 1
@@ -43,8 +44,27 @@
 
 
+///for debug drawing
+
+//for debug rendering
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
+#include "BulletCollision/CollisionShapes/btConeShape.h"
+#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btCylinderShape.h"
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
+#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
+#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
+
+
+
 btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
 :m_dispatcher1(dispatcher),
 m_broadphasePairCache(pairCache),
-m_debugDrawer(0)
+m_debugDrawer(0),
+m_forceUpdateAllAabbs(true)
 {
 	m_stackAlloc = collisionConfiguration->getStackAllocator();
@@ -89,26 +109,28 @@
 {
 
+	btAssert(collisionObject);
+
 	//check that the object isn't already added
-		btAssert( m_collisionObjects.findLinearSearch(collisionObject)  == m_collisionObjects.size());
-
-		m_collisionObjects.push_back(collisionObject);
-
-		//calculate new AABB
-		btTransform trans = collisionObject->getWorldTransform();
-
-		btVector3	minAabb;
-		btVector3	maxAabb;
-		collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
-
-		int type = collisionObject->getCollisionShape()->getShapeType();
-		collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
-			minAabb,
-			maxAabb,
-			type,
-			collisionObject,
-			collisionFilterGroup,
-			collisionFilterMask,
-			m_dispatcher1,0
-			))	;
+	btAssert( m_collisionObjects.findLinearSearch(collisionObject)  == m_collisionObjects.size());
+
+	m_collisionObjects.push_back(collisionObject);
+
+	//calculate new AABB
+	btTransform trans = collisionObject->getWorldTransform();
+
+	btVector3	minAabb;
+	btVector3	maxAabb;
+	collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb);
+
+	int type = collisionObject->getCollisionShape()->getShapeType();
+	collisionObject->setBroadphaseHandle( getBroadphase()->createProxy(
+		minAabb,
+		maxAabb,
+		type,
+		collisionObject,
+		collisionFilterGroup,
+		collisionFilterMask,
+		m_dispatcher1,0
+		))	;
 
 
@@ -163,5 +185,5 @@
 
 		//only update aabb of active objects
-		if (colObj->isActive())
+		if (m_forceUpdateAllAabbs || colObj->isActive())
 		{
 			updateSingleAabb(colObj);
@@ -226,8 +248,8 @@
 
 void	btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
-					  btCollisionObject* collisionObject,
-					  const btCollisionShape* collisionShape,
-					  const btTransform& colObjWorldTransform,
-					  RayResultCallback& resultCallback)
+										btCollisionObject* collisionObject,
+										const btCollisionShape* collisionShape,
+										const btTransform& colObjWorldTransform,
+										RayResultCallback& resultCallback)
 {
 	btSphereShape pointShape(btScalar(0.0));
@@ -237,5 +259,5 @@
 	if (collisionShape->isConvex())
 	{
-//		BT_PROFILE("rayTestConvex");
+		//		BT_PROFILE("rayTestConvex");
 		btConvexCast::CastResult castResult;
 		castResult.m_fraction = resultCallback.m_closestHitFraction;
@@ -266,8 +288,8 @@
 					btCollisionWorld::LocalRayResult localRayResult
 						(
-							collisionObject,
-							0,
-							castResult.m_normal,
-							castResult.m_fraction
+						collisionObject,
+						0,
+						castResult.m_normal,
+						castResult.m_fraction
 						);
 
@@ -281,5 +303,5 @@
 		if (collisionShape->isConcave())
 		{
-//			BT_PROFILE("rayTestConcave");
+			//			BT_PROFILE("rayTestConcave");
 			if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
 			{
@@ -297,13 +319,16 @@
 					btTriangleMeshShape*	m_triangleMesh;
 
+					btTransform m_colObjWorldTransform;
+
 					BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
-						btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*	triangleMesh):
-                  //@BP Mod
-						btTriangleRaycastCallback(from,to, resultCallback->m_flags),
-							m_resultCallback(resultCallback),
-							m_collisionObject(collisionObject),
-							m_triangleMesh(triangleMesh)
-						{
-						}
+						btCollisionWorld::RayResultCallback* resultCallback, 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)
+					{
+					}
 
 
@@ -314,11 +339,13 @@
 						shapeInfo.m_triangleIndex = triangleIndex;
 
+						btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
+
 						btCollisionWorld::LocalRayResult rayResult
-						(m_collisionObject,
+							(m_collisionObject,
 							&shapeInfo,
-							hitNormalLocal,
+							hitNormalWorld,
 							hitFraction);
 
-						bool	normalInWorldSpace = false;
+						bool	normalInWorldSpace = true;
 						return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
 					}
@@ -326,5 +353,5 @@
 				};
 
-				BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
+				BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh,colObjWorldTransform);
 				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 				triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
@@ -347,13 +374,16 @@
 					btConcaveShape*	m_triangleMesh;
 
+					btTransform m_colObjWorldTransform;
+
 					BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
-						btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape*	triangleMesh):
-                  //@BP Mod
-                  btTriangleRaycastCallback(from,to, resultCallback->m_flags),
-							m_resultCallback(resultCallback),
-							m_collisionObject(collisionObject),
-							m_triangleMesh(triangleMesh)
-						{
-						}
+						btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,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)
+					{
+					}
 
 
@@ -364,14 +394,14 @@
 						shapeInfo.m_triangleIndex = triangleIndex;
 
+						btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal;
+
 						btCollisionWorld::LocalRayResult rayResult
-						(m_collisionObject,
+							(m_collisionObject,
 							&shapeInfo,
-							hitNormalLocal,
+							hitNormalWorld,
 							hitFraction);
 
-						bool	normalInWorldSpace = false;
+						bool	normalInWorldSpace = true;
 						return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
-
-
 					}
 
@@ -379,5 +409,5 @@
 
 
-				BridgeTriangleRaycastCallback	rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape);
+				BridgeTriangleRaycastCallback	rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
 				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 
@@ -390,5 +420,5 @@
 			}
 		} else {
-//			BT_PROFILE("rayTestCompound");
+			//			BT_PROFILE("rayTestCompound");
 			///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
 			if (collisionShape->isCompound())
@@ -404,9 +434,34 @@
 					btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
 					collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
+                    struct LocalInfoAdder2 : public RayResultCallback {
+						RayResultCallback* m_userCallback;
+						int m_i;
+                        LocalInfoAdder2 (int i, RayResultCallback *user)
+							: m_userCallback(user),
+							m_i(i)
+						{ 
+							m_closestHitFraction = m_userCallback->m_closestHitFraction;
+						}
+						virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b)
+                            {
+                                    btCollisionWorld::LocalShapeInfo	shapeInfo;
+                                    shapeInfo.m_shapePart = -1;
+                                    shapeInfo.m_triangleIndex = m_i;
+                                    if (r.m_localShapeInfo == NULL)
+                                        r.m_localShapeInfo = &shapeInfo;
+
+									const btScalar result = m_userCallback->addSingleResult(r, b);
+									m_closestHitFraction = m_userCallback->m_closestHitFraction;
+									return result;
+                            }
+                    };
+
+                    LocalInfoAdder2 my_cb(i, &resultCallback);
+
 					rayTestSingle(rayFromTrans,rayToTrans,
 						collisionObject,
 						childCollisionShape,
 						childWorldTrans,
-						resultCallback);
+						my_cb);
 					// restore
 					collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
@@ -418,8 +473,8 @@
 
 void	btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
-					  btCollisionObject* collisionObject,
-					  const btCollisionShape* collisionShape,
-					  const btTransform& colObjWorldTransform,
-					  ConvexResultCallback& resultCallback, btScalar allowedPenetration)
+											btCollisionObject* collisionObject,
+											const btCollisionShape* collisionShape,
+											const btTransform& colObjWorldTransform,
+											ConvexResultCallback& resultCallback, btScalar allowedPenetration)
 {
 	if (collisionShape->isConvex())
@@ -433,5 +488,5 @@
 		btVoronoiSimplexSolver	simplexSolver;
 		btGjkEpaPenetrationDepthSolver	gjkEpaPenetrationSolver;
-		
+
 		btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
 		//btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
@@ -439,7 +494,7 @@
 
 		btConvexCast* castPtr = &convexCaster1;
-	
-	
-		
+
+
+
 		if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
 		{
@@ -451,11 +506,11 @@
 					castResult.m_normal.normalize();
 					btCollisionWorld::LocalConvexResult localConvexResult
-								(
-									collisionObject,
-									0,
-									castResult.m_normal,
-									castResult.m_hitPoint,
-									castResult.m_fraction
-								);
+						(
+						collisionObject,
+						0,
+						castResult.m_normal,
+						castResult.m_hitPoint,
+						castResult.m_fraction
+						);
 
 					bool normalInWorldSpace = true;
@@ -487,10 +542,10 @@
 					BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
 						btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*	triangleMesh, const btTransform& triangleToWorld):
-						btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
-							m_resultCallback(resultCallback),
-							m_collisionObject(collisionObject),
-							m_triangleMesh(triangleMesh)
-						{
-						}
+					btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
+						m_resultCallback(resultCallback),
+						m_collisionObject(collisionObject),
+						m_triangleMesh(triangleMesh)
+					{
+					}
 
 
@@ -504,5 +559,5 @@
 
 							btCollisionWorld::LocalConvexResult convexResult
-							(m_collisionObject,
+								(m_collisionObject,
 								&shapeInfo,
 								hitNormalLocal,
@@ -544,10 +599,10 @@
 					BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
 						btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape*	triangleMesh, const btTransform& triangleToWorld):
-						btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
-							m_resultCallback(resultCallback),
-							m_collisionObject(collisionObject),
-							m_triangleMesh(triangleMesh)
-						{
-						}
+					btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
+						m_resultCallback(resultCallback),
+						m_collisionObject(collisionObject),
+						m_triangleMesh(triangleMesh)
+					{
+					}
 
 
@@ -561,5 +616,5 @@
 
 							btCollisionWorld::LocalConvexResult convexResult
-							(m_collisionObject,
+								(m_collisionObject,
 								&shapeInfo,
 								hitNormalLocal,
@@ -604,9 +659,35 @@
 					btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
 					collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
+                    struct	LocalInfoAdder : public ConvexResultCallback {
+                            ConvexResultCallback* m_userCallback;
+							int m_i;
+
+                            LocalInfoAdder (int i, ConvexResultCallback *user)
+								: m_userCallback(user), m_i(i)
+							{
+								m_closestHitFraction = m_userCallback->m_closestHitFraction;
+							}
+                            virtual btScalar addSingleResult (btCollisionWorld::LocalConvexResult&	r,	bool b)
+                            {
+                                    btCollisionWorld::LocalShapeInfo	shapeInfo;
+                                    shapeInfo.m_shapePart = -1;
+                                    shapeInfo.m_triangleIndex = m_i;
+                                    if (r.m_localShapeInfo == NULL)
+                                        r.m_localShapeInfo = &shapeInfo;
+									const btScalar result = m_userCallback->addSingleResult(r, b);
+									m_closestHitFraction = m_userCallback->m_closestHitFraction;
+									return result;
+                                    
+                            }
+                    };
+
+                    LocalInfoAdder my_cb(i, &resultCallback);
+					
+
 					objectQuerySingle(castShape, convexFromTrans,convexToTrans,
 						collisionObject,
 						childCollisionShape,
 						childWorldTrans,
-						resultCallback, allowedPenetration);
+						my_cb, allowedPenetration);
 					// restore
 					collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
@@ -631,8 +712,8 @@
 
 	btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
-	:m_rayFromWorld(rayFromWorld),
-	m_rayToWorld(rayToWorld),
-	m_world(world),
-	m_resultCallback(resultCallback)
+		:m_rayFromWorld(rayFromWorld),
+		m_rayToWorld(rayToWorld),
+		m_world(world),
+		m_resultCallback(resultCallback)
 	{
 		m_rayFromTrans.setIdentity();
@@ -644,8 +725,8 @@
 
 		rayDir.normalize ();
-		///what about division by zero? --> just set rayDirection[i] to INF/1e30
-		m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
-		m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
-		m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+		///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
+		m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
+		m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
+		m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
 		m_signs[0] = m_rayDirectionInverse[0] < 0.0;
 		m_signs[1] = m_rayDirectionInverse[1] < 0.0;
@@ -656,5 +737,5 @@
 	}
 
-	
+
 
 	virtual bool	process(const btBroadphaseProxy* proxy)
@@ -687,7 +768,7 @@
 				m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
 					collisionObject,
-						collisionObject->getCollisionShape(),
-						collisionObject->getWorldTransform(),
-						m_resultCallback);
+					collisionObject->getCollisionShape(),
+					collisionObject->getWorldTransform(),
+					m_resultCallback);
 			}
 		}
@@ -698,5 +779,5 @@
 void	btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
 {
-	BT_PROFILE("rayTest");
+	//BT_PROFILE("rayTest");
 	/// use the broadphase to accelerate the search for objects, based on their aabb
 	/// and for each object with ray-aabb overlap, perform an exact ray test
@@ -737,8 +818,8 @@
 		btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
 		btVector3 rayDir = unnormalizedRayDir.normalized();
-		///what about division by zero? --> just set rayDirection[i] to INF/1e30
-		m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
-		m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
-		m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+		///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT
+		m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
+		m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
+		m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
 		m_signs[0] = m_rayDirectionInverse[0] < 0.0;
 		m_signs[1] = m_rayDirectionInverse[1] < 0.0;
@@ -761,11 +842,11 @@
 			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
 			m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
-					collisionObject,
-						collisionObject->getCollisionShape(),
-						collisionObject->getWorldTransform(),
-						m_resultCallback,
-						m_allowedCcdPenetration);
-		}
-		
+				collisionObject,
+				collisionObject->getCollisionShape(),
+				collisionObject->getWorldTransform(),
+				m_resultCallback,
+				m_allowedCcdPenetration);
+		}
+
 		return true;
 	}
@@ -782,5 +863,5 @@
 	/// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical
 
-	
+
 
 	btTransform	convexFromTrans,convexToTrans;
@@ -825,8 +906,8 @@
 				objectQuerySingle(castShape, convexFromTrans,convexToTrans,
 					collisionObject,
-						collisionObject->getCollisionShape(),
-						collisionObject->getWorldTransform(),
-						resultCallback,
-						allowedCcdPenetration);
+					collisionObject->getCollisionShape(),
+					collisionObject->getWorldTransform(),
+					resultCallback,
+					allowedCcdPenetration);
 			}
 		}
@@ -834,2 +915,518 @@
 #endif //USE_BRUTEFORCE_RAYBROADPHASE
 }
+
+
+
+struct btBridgedManifoldResult : public btManifoldResult
+{
+
+	btCollisionWorld::ContactResultCallback&	m_resultCallback;
+
+	btBridgedManifoldResult( btCollisionObject* obj0,btCollisionObject* obj1,btCollisionWorld::ContactResultCallback& resultCallback )
+		:btManifoldResult(obj0,obj1),
+		m_resultCallback(resultCallback)
+	{
+	}
+
+	virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
+	{
+		bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
+		btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
+		btVector3 localA;
+		btVector3 localB;
+		if (isSwapped)
+		{
+			localA = m_rootTransB.invXform(pointA );
+			localB = m_rootTransA.invXform(pointInWorld);
+		} else
+		{
+			localA = m_rootTransA.invXform(pointA );
+			localB = m_rootTransB.invXform(pointInWorld);
+		}
+		
+		btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
+		newPt.m_positionWorldOnA = pointA;
+		newPt.m_positionWorldOnB = pointInWorld;
+		
+	   //BP mod, store contact triangles.
+		if (isSwapped)
+		{
+			newPt.m_partId0 = m_partId1;
+			newPt.m_partId1 = m_partId0;
+			newPt.m_index0  = m_index1;
+			newPt.m_index1  = m_index0;
+		} else
+		{
+			newPt.m_partId0 = m_partId0;
+			newPt.m_partId1 = m_partId1;
+			newPt.m_index0  = m_index0;
+			newPt.m_index1  = m_index1;
+		}
+
+		//experimental feature info, for per-triangle material etc.
+		btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
+		btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
+		m_resultCallback.addSingleResult(newPt,obj0,newPt.m_partId0,newPt.m_index0,obj1,newPt.m_partId1,newPt.m_index1);
+
+	}
+	
+};
+
+
+
+struct btSingleContactCallback : public btBroadphaseAabbCallback
+{
+
+	btCollisionObject* m_collisionObject;
+	btCollisionWorld*	m_world;
+	btCollisionWorld::ContactResultCallback&	m_resultCallback;
+	
+	
+	btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback)
+		:m_collisionObject(collisionObject),
+		m_world(world),
+		m_resultCallback(resultCallback)
+	{
+	}
+
+	virtual bool	process(const btBroadphaseProxy* proxy)
+	{
+		btCollisionObject*	collisionObject = (btCollisionObject*)proxy->m_clientObject;
+		if (collisionObject == m_collisionObject)
+			return true;
+
+		//only perform raycast if filterMask matches
+		if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
+		{
+			btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(m_collisionObject,collisionObject);
+			if (algorithm)
+			{
+				btBridgedManifoldResult contactPointResult(m_collisionObject,collisionObject, m_resultCallback);
+				//discrete collision detection query
+				algorithm->processCollision(m_collisionObject,collisionObject, m_world->getDispatchInfo(),&contactPointResult);
+
+				algorithm->~btCollisionAlgorithm();
+				m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
+			}
+		}
+		return true;
+	}
+};
+
+
+///contactTest performs a discrete collision test against all objects in the btCollisionWorld, and calls the resultCallback.
+///it reports one or more contact points for every overlapping object (including the one with deepest penetration)
+void	btCollisionWorld::contactTest( btCollisionObject* colObj, ContactResultCallback& resultCallback)
+{
+	btVector3 aabbMin,aabbMax;
+	colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax);
+	btSingleContactCallback	contactCB(colObj,this,resultCallback);
+	
+	m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB);
+}
+
+
+///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
+///it reports one or more contact points (including the one with deepest penetration)
+void	btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback)
+{
+	btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(colObjA,colObjB);
+	if (algorithm)
+	{
+		btBridgedManifoldResult contactPointResult(colObjA,colObjB, resultCallback);
+		//discrete collision detection query
+		algorithm->processCollision(colObjA,colObjB, getDispatchInfo(),&contactPointResult);
+
+		algorithm->~btCollisionAlgorithm();
+		getDispatcher()->freeCollisionAlgorithm(algorithm);
+	}
+
+}
+
+
+
+
+class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback
+{
+	btIDebugDraw*	m_debugDrawer;
+	btVector3	m_color;
+	btTransform	m_worldTrans;
+
+public:
+
+	DebugDrawcallback(btIDebugDraw*	debugDrawer,const btTransform& worldTrans,const btVector3& color) :
+	  m_debugDrawer(debugDrawer),
+		  m_color(color),
+		  m_worldTrans(worldTrans)
+	  {
+	  }
+
+	  virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
+	  {
+		  processTriangle(triangle,partId,triangleIndex);
+	  }
+
+	  virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
+	  {
+		  (void)partId;
+		  (void)triangleIndex;
+
+		  btVector3 wv0,wv1,wv2;
+		  wv0 = m_worldTrans*triangle[0];
+		  wv1 = m_worldTrans*triangle[1];
+		  wv2 = m_worldTrans*triangle[2];
+		  btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.);
+
+		  btVector3 normal = (wv1-wv0).cross(wv2-wv0);
+		  normal.normalize();
+		  btVector3 normalColor(1,1,0);
+		  m_debugDrawer->drawLine(center,center+normal,normalColor);
+
+
+
+		 
+		  m_debugDrawer->drawLine(wv0,wv1,m_color);
+		  m_debugDrawer->drawLine(wv1,wv2,m_color);
+		  m_debugDrawer->drawLine(wv2,wv0,m_color);
+	  }
+};
+
+
+void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
+{
+	// Draw a small simplex at the center of the object
+	getDebugDrawer()->drawTransform(worldTransform,1);
+
+	if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
+	{
+		const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
+		for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
+		{
+			btTransform childTrans = compoundShape->getChildTransform(i);
+			const btCollisionShape* colShape = compoundShape->getChildShape(i);
+			debugDrawObject(worldTransform*childTrans,colShape,color);
+		}
+
+	} else
+	{
+		switch (shape->getShapeType())
+		{
+
+		case BOX_SHAPE_PROXYTYPE:
+			{
+				const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
+				btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
+				getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
+				break;
+			}
+
+		case SPHERE_SHAPE_PROXYTYPE:
+			{
+				const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
+				btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
+
+				getDebugDrawer()->drawSphere(radius, worldTransform, color);
+				break;
+			}
+		case MULTI_SPHERE_SHAPE_PROXYTYPE:
+			{
+				const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
+
+				btTransform childTransform;
+				childTransform.setIdentity();
+
+				for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
+				{
+					childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
+					getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
+				}
+
+				break;
+			}
+		case CAPSULE_SHAPE_PROXYTYPE:
+			{
+				const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
+
+				btScalar radius = capsuleShape->getRadius();
+				btScalar halfHeight = capsuleShape->getHalfHeight();
+
+				int upAxis = capsuleShape->getUpAxis();
+
+
+				btVector3 capStart(0.f,0.f,0.f);
+				capStart[upAxis] = -halfHeight;
+
+				btVector3 capEnd(0.f,0.f,0.f);
+				capEnd[upAxis] = halfHeight;
+
+				// Draw the ends
+				{
+
+					btTransform childTransform = worldTransform;
+					childTransform.getOrigin() = worldTransform * capStart;
+					getDebugDrawer()->drawSphere(radius, childTransform, color);
+				}
+
+				{
+					btTransform childTransform = worldTransform;
+					childTransform.getOrigin() = worldTransform * capEnd;
+					getDebugDrawer()->drawSphere(radius, childTransform, color);
+				}
+
+				// Draw some additional lines
+				btVector3 start = worldTransform.getOrigin();
+
+
+				capStart[(upAxis+1)%3] = radius;
+				capEnd[(upAxis+1)%3] = radius;
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
+				capStart[(upAxis+1)%3] = -radius;
+				capEnd[(upAxis+1)%3] = -radius;
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
+
+				capStart[(upAxis+1)%3] = 0.f;
+				capEnd[(upAxis+1)%3] = 0.f;
+
+				capStart[(upAxis+2)%3] = radius;
+				capEnd[(upAxis+2)%3] = radius;
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
+				capStart[(upAxis+2)%3] = -radius;
+				capEnd[(upAxis+2)%3] = -radius;
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
+
+
+				break;
+			}
+		case CONE_SHAPE_PROXYTYPE:
+			{
+				const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
+				btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
+				btScalar height = coneShape->getHeight();//+coneShape->getMargin();
+				btVector3 start = worldTransform.getOrigin();
+
+				int upAxis= coneShape->getConeUpIndex();
+
+
+				btVector3	offsetHeight(0,0,0);
+				offsetHeight[upAxis] = height * btScalar(0.5);
+				btVector3	offsetRadius(0,0,0);
+				offsetRadius[(upAxis+1)%3] = radius;
+				btVector3	offset2Radius(0,0,0);
+				offset2Radius[(upAxis+2)%3] = radius;
+
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offset2Radius),color);
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offset2Radius),color);
+
+				// Drawing the base of the cone
+				btVector3 yaxis(0,0,0);
+				yaxis[upAxis] = btScalar(1.0);
+				btVector3 xaxis(0,0,0);
+				xaxis[(upAxis+1)%3] = btScalar(1.0);
+				getDebugDrawer()->drawArc(start-worldTransform.getBasis()*(offsetHeight),worldTransform.getBasis()*yaxis,worldTransform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,10.0);
+		break;
+
+			}
+		case CYLINDER_SHAPE_PROXYTYPE:
+			{
+				const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
+				int upAxis = cylinder->getUpAxis();
+				btScalar radius = cylinder->getRadius();
+				btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
+				btVector3 start = worldTransform.getOrigin();
+				btVector3	offsetHeight(0,0,0);
+				offsetHeight[upAxis] = halfHeight;
+				btVector3	offsetRadius(0,0,0);
+				offsetRadius[(upAxis+1)%3] = radius;
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight+offsetRadius),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
+				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight-offsetRadius),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
+
+				// Drawing top and bottom caps of the cylinder
+				btVector3 yaxis(0,0,0);
+				yaxis[upAxis] = btScalar(1.0);
+				btVector3 xaxis(0,0,0);
+				xaxis[(upAxis+1)%3] = btScalar(1.0);
+				getDebugDrawer()->drawArc(start-worldTransform.getBasis()*(offsetHeight),worldTransform.getBasis()*yaxis,worldTransform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0));
+				getDebugDrawer()->drawArc(start+worldTransform.getBasis()*(offsetHeight),worldTransform.getBasis()*yaxis,worldTransform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0));
+				break;
+			}
+
+		case STATIC_PLANE_PROXYTYPE:
+			{
+				const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
+				btScalar planeConst = staticPlaneShape->getPlaneConstant();
+				const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
+				btVector3 planeOrigin = planeNormal * planeConst;
+				btVector3 vec0,vec1;
+				btPlaneSpace1(planeNormal,vec0,vec1);
+				btScalar vecLen = 100.f;
+				btVector3 pt0 = planeOrigin + vec0*vecLen;
+				btVector3 pt1 = planeOrigin - vec0*vecLen;
+				btVector3 pt2 = planeOrigin + vec1*vecLen;
+				btVector3 pt3 = planeOrigin - vec1*vecLen;
+				getDebugDrawer()->drawLine(worldTransform*pt0,worldTransform*pt1,color);
+				getDebugDrawer()->drawLine(worldTransform*pt2,worldTransform*pt3,color);
+				break;
+
+			}
+		default:
+			{
+
+				if (shape->isConcave())
+				{
+					btConcaveShape* concaveMesh = (btConcaveShape*) shape;
+
+					///@todo pass camera, for some culling? no -> we are not a graphics lib
+					btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+					btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
+
+					DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
+					concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
+
+				}
+
+				if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
+				{
+					btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
+					//todo: pass camera for some culling			
+					btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+					btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
+					//DebugDrawcallback drawCallback;
+					DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
+					convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
+				}
+
+
+				/// for polyhedral shapes
+				if (shape->isPolyhedral())
+				{
+					btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
+
+					int i;
+					for (i=0;i<polyshape->getNumEdges();i++)
+					{
+						btVector3 a,b;
+						polyshape->getEdge(i,a,b);
+						btVector3 wa = worldTransform * a;
+						btVector3 wb = worldTransform * b;
+						getDebugDrawer()->drawLine(wa,wb,color);
+
+					}
+
+
+				}
+			}
+		}
+	}
+}
+
+
+void	btCollisionWorld::debugDrawWorld()
+{
+	if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
+	{
+		int numManifolds = getDispatcher()->getNumManifolds();
+		btVector3 color(0,0,0);
+		for (int i=0;i<numManifolds;i++)
+		{
+			btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
+			//btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
+			//btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
+
+			int numContacts = contactManifold->getNumContacts();
+			for (int j=0;j<numContacts;j++)
+			{
+				btManifoldPoint& cp = contactManifold->getContactPoint(j);
+				getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
+			}
+		}
+	}
+
+	if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
+	{
+		int i;
+
+		for (  i=0;i<m_collisionObjects.size();i++)
+		{
+			btCollisionObject* colObj = m_collisionObjects[i];
+			if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0)
+			{
+				if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
+				{
+					btVector3 color(btScalar(1.),btScalar(1.),btScalar(1.));
+					switch(colObj->getActivationState())
+					{
+					case  ACTIVE_TAG:
+						color = btVector3(btScalar(1.),btScalar(1.),btScalar(1.)); break;
+					case ISLAND_SLEEPING:
+						color =  btVector3(btScalar(0.),btScalar(1.),btScalar(0.));break;
+					case WANTS_DEACTIVATION:
+						color = btVector3(btScalar(0.),btScalar(1.),btScalar(1.));break;
+					case DISABLE_DEACTIVATION:
+						color = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));break;
+					case DISABLE_SIMULATION:
+						color = btVector3(btScalar(1.),btScalar(1.),btScalar(0.));break;
+					default:
+						{
+							color = btVector3(btScalar(1),btScalar(0.),btScalar(0.));
+						}
+					};
+
+					debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
+				}
+				if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
+				{
+					btVector3 minAabb,maxAabb;
+					btVector3 colorvec(1,0,0);
+					colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
+					m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
+				}
+			}
+
+		}
+	}
+}
+
+
+void	btCollisionWorld::serializeCollisionObjects(btSerializer* serializer)
+{
+	int i;
+	//serialize all collision objects
+	for (i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		if (colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT)
+		{
+			colObj->serializeSingleObject(serializer);
+		}
+	}
+
+	///keep track of shapes already serialized
+	btHashMap<btHashPtr,btCollisionShape*>	serializedShapes;
+
+	for (i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		btCollisionShape* shape = colObj->getCollisionShape();
+
+		if (!serializedShapes.find(shape))
+		{
+			serializedShapes.insert(shape,shape);
+			shape->serializeSingleShape(serializer);
+		}
+	}
+
+}
+
+
+void	btCollisionWorld::serialize(btSerializer* serializer)
+{
+
+	serializer->startSerialization();
+	
+	serializeCollisionObjects(serializer);
+	
+	serializer->finishSerialization();
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h	(revision 8284)
@@ -23,4 +23,5 @@
  * 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
@@ -30,12 +31,14 @@
  * @subsection step1 Step 1: Download
  * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
+ *
  * @subsection step2 Step 2: Building
- * Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8.
- * The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version).
- * 
- * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org , or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
- * So if you are not using MSVC or cmake, you can run ./autogen.sh ./configure to create both Makefile and Jamfile and then run make or jam.
- * Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files.
- * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/jam
+ * Bullet main build system for all platforms is cmake, you can download http://www.cmake.org
+ * cmake can autogenerate projectfiles for Microsoft Visual Studio, Apple Xcode, KDevelop and Unix Makefiles.
+ * The easiest is to run the CMake cmake-gui graphical user interface and choose the options and generate projectfiles.
+ * You can also use cmake in the command-line. Here are some examples for various platforms:
+ * cmake . -G "Visual Studio 9 2008"
+ * cmake . -G Xcode
+ * cmake . -G "Unix Makefiles"
+ * Although cmake is recommended, you can also use autotools for UNIX: ./autogen.sh ./configure to create a Makefile and then run make.
  * 
  * @subsection step3 Step 3: Testing demos
@@ -54,11 +57,7 @@
  *
  * @section copyright Copyright
- * Copyright (C) 2005-2008 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
- * Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, John McCutchan, Nathanael Presson, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
- * Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt.
+ * For up-to-data information and copyright and contributors list check out the Bullet_User_Manual.pdf
  * 
  */
-
-
  
  
@@ -71,4 +70,6 @@
 class btConvexShape;
 class btBroadphaseInterface;
+class btSerializer;
+
 #include "LinearMath/btVector3.h"
 #include "LinearMath/btTransform.h"
@@ -82,10 +83,8 @@
 {
 
-
 	
 protected:
 
 	btAlignedObjectArray<btCollisionObject*>	m_collisionObjects;
-
 	
 	btDispatcher*	m_dispatcher1;
@@ -99,6 +98,10 @@
 	btIDebugDraw*	m_debugDrawer;
 
-
-	
+	///m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs
+	///it is true by default, because it is error-prone (setting the position of static objects wouldn't update their AABB)
+	bool m_forceUpdateAllAabbs;
+
+	void	serializeCollisionObjects(btSerializer* serializer);
+
 public:
 
@@ -142,5 +145,4 @@
 
 	virtual void	updateAabbs();
-
 	
 	virtual void	setDebugDrawer(btIDebugDraw*	debugDrawer)
@@ -153,4 +155,8 @@
 		return m_debugDrawer;
 	}
+
+	virtual void	debugDrawWorld();
+
+	virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
 
 
@@ -161,5 +167,4 @@
 		int	m_shapePart;
 		int	m_triangleIndex;
-
 		
 		//const btCollisionShape*	m_shapeTemp;
@@ -239,5 +244,4 @@
 		btVector3	m_hitNormalWorld;
 		btVector3	m_hitPointWorld;
-
 			
 		virtual	btScalar	addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
@@ -245,5 +249,4 @@
 			//caller already does the filter on the m_closestHitFraction
 			btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
-
 			
 			m_closestHitFraction = rayResult.m_hitFraction;
@@ -262,4 +265,43 @@
 	};
 
+	struct	AllHitsRayResultCallback : public RayResultCallback
+	{
+		AllHitsRayResultCallback(const btVector3&	rayFromWorld,const btVector3&	rayToWorld)
+		:m_rayFromWorld(rayFromWorld),
+		m_rayToWorld(rayToWorld)
+		{
+		}
+
+		btAlignedObjectArray<btCollisionObject*>		m_collisionObjects;
+
+		btVector3	m_rayFromWorld;//used to calculate hitPointWorld from hitFraction
+		btVector3	m_rayToWorld;
+
+		btAlignedObjectArray<btVector3>	m_hitNormalWorld;
+		btAlignedObjectArray<btVector3>	m_hitPointWorld;
+		btAlignedObjectArray<btScalar> m_hitFractions;
+			
+		virtual	btScalar	addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
+		{
+			m_collisionObject = rayResult.m_collisionObject;
+			m_collisionObjects.push_back(rayResult.m_collisionObject);
+			btVector3 hitNormalWorld;
+			if (normalInWorldSpace)
+			{
+				hitNormalWorld = rayResult.m_hitNormalLocal;
+			} else
+			{
+				///need to transform normal into worldspace
+				hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
+			}
+			m_hitNormalWorld.push_back(hitNormalWorld);
+			btVector3 hitPointWorld;
+			hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction);
+			m_hitPointWorld.push_back(hitPointWorld);
+			m_hitFractions.push_back(rayResult.m_hitFraction);
+			return m_closestHitFraction;
+		}
+	};
+
 
 	struct LocalConvexResult
@@ -292,5 +334,4 @@
 		short int	m_collisionFilterGroup;
 		short int	m_collisionFilterMask;
-
 		
 		ConvexResultCallback()
@@ -304,5 +345,4 @@
 		{
 		}
-
 		
 		bool	hasHit() const
@@ -310,5 +350,4 @@
 			return (m_closestHitFraction < btScalar(1.));
 		}
-
 
 		
@@ -339,5 +378,4 @@
 		btVector3	m_hitPointWorld;
 		btCollisionObject*	m_hitCollisionObject;
-
 		
 		virtual	btScalar	addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace)
@@ -345,5 +383,4 @@
 //caller already does the filter on the m_closestHitFraction
 			btAssert(convexResult.m_hitFraction <= m_closestHitFraction);
-
 						
 			m_closestHitFraction = convexResult.m_hitFraction;
@@ -362,4 +399,32 @@
 	};
 
+	///ContactResultCallback is used to report contact points
+	struct	ContactResultCallback
+	{
+		short int	m_collisionFilterGroup;
+		short int	m_collisionFilterMask;
+		
+		ContactResultCallback()
+			:m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
+			m_collisionFilterMask(btBroadphaseProxy::AllFilter)
+		{
+		}
+
+		virtual ~ContactResultCallback()
+		{
+		}
+		
+		virtual bool needsCollision(btBroadphaseProxy* proxy0) const
+		{
+			bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
+			collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+			return collides;
+		}
+
+		virtual	btScalar	addSingleResult(btManifoldPoint& cp,	const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) = 0;
+	};
+
+
+
 	int	getNumCollisionObjects() const
 	{
@@ -369,9 +434,17 @@
 	/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
 	/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
-	void	rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; 
-
-	// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
-	// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
+	virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; 
+
+	/// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
+	/// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
 	void    convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback,  btScalar allowedCcdPenetration = btScalar(0.)) const;
+
+	///contactTest performs a discrete collision test between colObj against all objects in the btCollisionWorld, and calls the resultCallback.
+	///it reports one or more contact points for every overlapping object (including the one with deepest penetration)
+	void	contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback);
+
+	///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected.
+	///it reports one or more contact points (including the one with deepest penetration)
+	void	contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback);
 
 
@@ -392,5 +465,5 @@
 					  ConvexResultCallback& resultCallback, btScalar	allowedPenetration);
 
-	void	addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
+	virtual void	addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
 
 	btCollisionObjectArray& getCollisionObjectArray()
@@ -405,5 +478,5 @@
 
 
-	void	removeCollisionObject(btCollisionObject* collisionObject);
+	virtual void	removeCollisionObject(btCollisionObject* collisionObject);
 
 	virtual void	performDiscreteCollisionDetection();
@@ -418,4 +491,16 @@
 		return m_dispatchInfo;
 	}
+	
+	bool	getForceUpdateAllAabbs() const
+	{
+		return m_forceUpdateAllAabbs;
+	}
+	void setForceUpdateAllAabbs( bool forceUpdateAllAabbs)
+	{
+		m_forceUpdateAllAabbs = forceUpdateAllAabbs;
+	}
+
+	///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bullet/Demos/SerializeDemo)
+	virtual	void	serialize(btSerializer* serializer);
 
 };
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp	(revision 8284)
@@ -115,6 +115,7 @@
 	void	ProcessChildShape(btCollisionShape* childShape,int index)
 	{
-		
+		btAssert(index>=0);
 		btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
+		btAssert(index<compoundShape->getNumChildShapes());
 
 
@@ -142,4 +143,13 @@
 			if (!m_childCollisionAlgorithms[index])
 				m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(m_compoundColObj,m_otherObj,m_sharedManifold);
+
+			///detect swapping case
+			if (m_resultOut->getBody0Internal() == m_compoundColObj)
+			{
+				m_resultOut->setShapeIdentifiersA(-1,index);
+			} else
+			{
+				m_resultOut->setShapeIdentifiersB(-1,index);
+			}
 
 			m_childCollisionAlgorithms[index]->processCollision(m_compoundColObj,m_otherObj,m_dispatchInfo,m_resultOut);
@@ -258,18 +268,22 @@
 		int i;
 		btManifoldArray	manifoldArray;
-
+        btCollisionShape* childShape = 0;
+        btTransform	orgTrans;
+        btTransform	orgInterpolationTrans;
+        btTransform	newChildWorldTrans;
+        btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;        
+        
 		for (i=0;i<numChildren;i++)
 		{
 			if (m_childCollisionAlgorithms[i])
 			{
-				btCollisionShape* childShape = compoundShape->getChildShape(i);
+				childShape = compoundShape->getChildShape(i);
 			//if not longer overlapping, remove the algorithm
-				btTransform	orgTrans = colObj->getWorldTransform();
-				btTransform	orgInterpolationTrans = colObj->getInterpolationWorldTransform();
+                orgTrans = colObj->getWorldTransform();
+                orgInterpolationTrans = colObj->getInterpolationWorldTransform();
 				const btTransform& childTrans = compoundShape->getChildTransform(i);
-				btTransform	newChildWorldTrans = orgTrans*childTrans ;
+                newChildWorldTrans = orgTrans*childTrans ;
 
 				//perform an AABB check first
-				btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
 				childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
 				otherObj->getCollisionShape()->getAabb(otherObj->getWorldTransform(),aabbMin1,aabbMax1);
@@ -281,11 +295,6 @@
 					m_childCollisionAlgorithms[i] = 0;
 				}
-
 			}
-			
-		}
-
-		
-
+		}
 	}
 }
@@ -312,4 +321,6 @@
 	int numChildren = m_childCollisionAlgorithms.size();
 	int i;
+    btTransform	orgTrans;
+    btScalar frac;
 	for (i=0;i<numChildren;i++)
 	{
@@ -318,5 +329,5 @@
 
 		//backup
-		btTransform	orgTrans = colObj->getWorldTransform();
+        orgTrans = colObj->getWorldTransform();
 	
 		const btTransform& childTrans = compoundShape->getChildTransform(i);
@@ -326,5 +337,5 @@
 		btCollisionShape* tmpShape = colObj->getCollisionShape();
 		colObj->internalSetTemporaryCollisionShape( childShape );
-		btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
+        frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
 		if (frac<hitFraction)
 		{
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp	(revision 8284)
@@ -0,0 +1,247 @@
+/*
+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 "btConvex2dConvex2dAlgorithm.h"
+
+//#include <stdio.h>
+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
+
+
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
+
+
+
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+
+
+btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface*			simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
+{
+	m_numPerturbationIterations = 0;
+	m_minimumPointsPerturbationThreshold = 3;
+	m_simplexSolver = simplexSolver;
+	m_pdSolver = pdSolver;
+}
+
+btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc() 
+{ 
+}
+
+btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+: btActivatingCollisionAlgorithm(ci,body0,body1),
+m_simplexSolver(simplexSolver),
+m_pdSolver(pdSolver),
+m_ownManifold (false),
+m_manifoldPtr(mf),
+m_lowLevelOfDetail(false),
+ m_numPerturbationIterations(numPerturbationIterations),
+m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
+{
+	(void)body0;
+	(void)body1;
+}
+
+
+
+
+btConvex2dConvex2dAlgorithm::~btConvex2dConvex2dAlgorithm()
+{
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr)
+			m_dispatcher->releaseManifold(m_manifoldPtr);
+	}
+}
+
+void	btConvex2dConvex2dAlgorithm ::setLowLevelOfDetail(bool useLowLevel)
+{
+	m_lowLevelOfDetail = useLowLevel;
+}
+
+
+
+extern btScalar gContactBreakingThreshold;
+
+
+//
+// Convex-Convex collision algorithm
+//
+void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+
+	if (!m_manifoldPtr)
+	{
+		//swapped?
+		m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
+		m_ownManifold = true;
+	}
+	resultOut->setPersistentManifold(m_manifoldPtr);
+
+	//comment-out next line to test multi-contact generation
+	//resultOut->getPersistentManifold()->clearManifold();
+
+
+	btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
+	btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
+
+	btVector3  normalOnB;
+	btVector3  pointOnBWorld;
+
+	{
+
+
+		btGjkPairDetector::ClosestPointInput input;
+
+		btGjkPairDetector	gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
+		//TODO: if (dispatchInfo.m_useContinuous)
+		gjkPairDetector.setMinkowskiA(min0);
+		gjkPairDetector.setMinkowskiB(min1);
+
+		{
+			input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
+			input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
+		}
+
+		input.m_stackAlloc = dispatchInfo.m_stackAllocator;
+		input.m_transformA = body0->getWorldTransform();
+		input.m_transformB = body1->getWorldTransform();
+
+		gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+
+		btVector3 v0,v1;
+		btVector3 sepNormalWorldSpace;
+
+	}
+
+	if (m_ownManifold)
+	{
+		resultOut->refreshContactPoints();
+	}
+
+}
+
+
+
+
+btScalar	btConvex2dConvex2dAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)resultOut;
+	(void)dispatchInfo;
+	///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold
+
+	///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
+	///col0->m_worldTransform,
+	btScalar resultFraction = btScalar(1.);
+
+
+	btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2();
+	btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2();
+
+	if (squareMot0 < col0->getCcdSquareMotionThreshold() &&
+		squareMot1 < col1->getCcdSquareMotionThreshold())
+		return resultFraction;
+
+
+	//An adhoc way of testing the Continuous Collision Detection algorithms
+	//One object is approximated as a sphere, to simplify things
+	//Starting in penetration should report no time of impact
+	//For proper CCD, better accuracy and handling of 'allowed' penetration should be added
+	//also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies)
+
+
+	/// Convex0 against sphere for Convex1
+	{
+		btConvexShape* convex0 = static_cast<btConvexShape*>(col0->getCollisionShape());
+
+		btSphereShape	sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation
+		btConvexCast::CastResult result;
+		btVoronoiSimplexSolver voronoiSimplex;
+		//SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
+		///Simplification, one object is simplified as a sphere
+		btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex);
+		//ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
+		if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(),
+			col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result))
+		{
+
+			//store result.m_fraction in both bodies
+
+			if (col0->getHitFraction()> result.m_fraction)
+				col0->setHitFraction( result.m_fraction );
+
+			if (col1->getHitFraction() > result.m_fraction)
+				col1->setHitFraction( result.m_fraction);
+
+			if (resultFraction > result.m_fraction)
+				resultFraction = result.m_fraction;
+
+		}
+
+
+
+
+	}
+
+	/// Sphere (for convex0) against Convex1
+	{
+		btConvexShape* convex1 = static_cast<btConvexShape*>(col1->getCollisionShape());
+
+		btSphereShape	sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation
+		btConvexCast::CastResult result;
+		btVoronoiSimplexSolver voronoiSimplex;
+		//SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
+		///Simplification, one object is simplified as a sphere
+		btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex);
+		//ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
+		if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(),
+			col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result))
+		{
+
+			//store result.m_fraction in both bodies
+
+			if (col0->getHitFraction()	> result.m_fraction)
+				col0->setHitFraction( result.m_fraction);
+
+			if (col1->getHitFraction() > result.m_fraction)
+				col1->setHitFraction( result.m_fraction);
+
+			if (resultFraction > result.m_fraction)
+				resultFraction = result.m_fraction;
+
+		}
+	}
+
+	return resultFraction;
+
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h	(revision 8284)
@@ -0,0 +1,95 @@
+/*
+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 CONVEX_2D_CONVEX_2D_ALGORITHM_H
+#define CONVEX_2D_CONVEX_2D_ALGORITHM_H
+
+#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
+
+class btConvexPenetrationDepthSolver;
+
+
+///The convex2dConvex2dAlgorithm collision algorithm support 2d collision detection for btConvex2dShape
+///Currently it requires the btMinkowskiPenetrationDepthSolver, it has support for 2d penetration depth computation
+class btConvex2dConvex2dAlgorithm : public btActivatingCollisionAlgorithm
+{
+	btSimplexSolverInterface*		m_simplexSolver;
+	btConvexPenetrationDepthSolver* m_pdSolver;
+
+	
+	bool	m_ownManifold;
+	btPersistentManifold*	m_manifoldPtr;
+	bool			m_lowLevelOfDetail;
+	
+	int m_numPerturbationIterations;
+	int m_minimumPointsPerturbationThreshold;
+
+public:
+
+	btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
+
+
+	virtual ~btConvex2dConvex2dAlgorithm();
+
+	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray)
+	{
+		///should we use m_ownManifold to avoid adding duplicates?
+		if (m_manifoldPtr && m_ownManifold)
+			manifoldArray.push_back(m_manifoldPtr);
+	}
+
+
+	void	setLowLevelOfDetail(bool useLowLevel);
+
+
+	const btPersistentManifold*	getManifold()
+	{
+		return m_manifoldPtr;
+	}
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+
+		btConvexPenetrationDepthSolver*		m_pdSolver;
+		btSimplexSolverInterface*			m_simplexSolver;
+		int m_numPerturbationIterations;
+		int m_minimumPointsPerturbationThreshold;
+
+		CreateFunc(btSimplexSolverInterface*			simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
+		
+		virtual ~CreateFunc();
+
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvex2dConvex2dAlgorithm));
+			return new(mem) btConvex2dConvex2dAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+		}
+	};
+
+
+};
+
+#endif //CONVEX_2D_CONVEX_2D_ALGORITHM_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp	(revision 8284)
@@ -96,5 +96,5 @@
 	if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
 	{
-		btVector3 color(255,255,0);
+		btVector3 color(1,1,0);
 		btTransform& tr = ob->getWorldTransform();
 		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
@@ -122,10 +122,14 @@
 		
 		btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
-		///this should use the btDispatcher, so the actual registered algorithm is used
-		//		btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
-
-		m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex);
-	//	cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
-//		cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
+
+		if (m_resultOut->getBody0Internal() == m_triBody)
+		{
+			m_resultOut->setShapeIdentifiersA(partId,triangleIndex);
+		}
+		else
+		{
+			m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
+		}
+	
 		colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
 		colAlgo->~btCollisionAlgorithm();
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp	(revision 8284)
@@ -14,4 +14,9 @@
 */
 
+///Specialized capsule-capsule collision algorithm has been added for Bullet 2.75 release to increase ragdoll performance
+///If you experience problems with capsule-capsule collision, try to define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER and report it in the Bullet forums
+///with reproduction case
+//define BT_DISABLE_CAPSULE_CAPSULE_COLLIDER 1
+
 #include "btConvexConvexAlgorithm.h"
 
@@ -21,4 +26,7 @@
 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
 #include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
+
+
 #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@@ -44,5 +52,124 @@
 
 
-
+///////////
+
+
+
+static SIMD_FORCE_INLINE void segmentsClosestPoints(
+	btVector3& ptsVector,
+	btVector3& offsetA,
+	btVector3& offsetB,
+	btScalar& tA, btScalar& tB,
+	const btVector3& translation,
+	const btVector3& dirA, btScalar hlenA,
+	const btVector3& dirB, btScalar hlenB )
+{
+	// compute the parameters of the closest points on each line segment
+
+	btScalar dirA_dot_dirB = btDot(dirA,dirB);
+	btScalar dirA_dot_trans = btDot(dirA,translation);
+	btScalar dirB_dot_trans = btDot(dirB,translation);
+
+	btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB;
+
+	if ( denom == 0.0f ) {
+		tA = 0.0f;
+	} else {
+		tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom;
+		if ( tA < -hlenA )
+			tA = -hlenA;
+		else if ( tA > hlenA )
+			tA = hlenA;
+	}
+
+	tB = tA * dirA_dot_dirB - dirB_dot_trans;
+
+	if ( tB < -hlenB ) {
+		tB = -hlenB;
+		tA = tB * dirA_dot_dirB + dirA_dot_trans;
+
+		if ( tA < -hlenA )
+			tA = -hlenA;
+		else if ( tA > hlenA )
+			tA = hlenA;
+	} else if ( tB > hlenB ) {
+		tB = hlenB;
+		tA = tB * dirA_dot_dirB + dirA_dot_trans;
+
+		if ( tA < -hlenA )
+			tA = -hlenA;
+		else if ( tA > hlenA )
+			tA = hlenA;
+	}
+
+	// compute the closest points relative to segment centers.
+
+	offsetA = dirA * tA;
+	offsetB = dirB * tB;
+
+	ptsVector = translation - offsetA + offsetB;
+}
+
+
+static SIMD_FORCE_INLINE btScalar capsuleCapsuleDistance(
+	btVector3& normalOnB,
+	btVector3& pointOnB,
+	btScalar capsuleLengthA,
+	btScalar	capsuleRadiusA,
+	btScalar capsuleLengthB,
+	btScalar	capsuleRadiusB,
+	int capsuleAxisA,
+	int capsuleAxisB,
+	const btTransform& transformA,
+	const btTransform& transformB,
+	btScalar distanceThreshold )
+{
+	btVector3 directionA = transformA.getBasis().getColumn(capsuleAxisA);
+	btVector3 translationA = transformA.getOrigin();
+	btVector3 directionB = transformB.getBasis().getColumn(capsuleAxisB);
+	btVector3 translationB = transformB.getOrigin();
+
+	// translation between centers
+
+	btVector3 translation = translationB - translationA;
+
+	// compute the closest points of the capsule line segments
+
+	btVector3 ptsVector;           // the vector between the closest points
+	
+	btVector3 offsetA, offsetB;    // offsets from segment centers to their closest points
+	btScalar tA, tB;              // parameters on line segment
+
+	segmentsClosestPoints( ptsVector, offsetA, offsetB, tA, tB, translation,
+						   directionA, capsuleLengthA, directionB, capsuleLengthB );
+
+	btScalar distance = ptsVector.length() - capsuleRadiusA - capsuleRadiusB;
+
+	if ( distance > distanceThreshold )
+		return distance;
+
+	btScalar lenSqr = ptsVector.length2();
+	if (lenSqr<= (SIMD_EPSILON*SIMD_EPSILON))
+	{
+		//degenerate case where 2 capsules are likely at the same location: take a vector tangential to 'directionA'
+		btVector3 q;
+		btPlaneSpace1(directionA,normalOnB,q);
+	} else
+	{
+		// compute the contact normal
+		normalOnB = ptsVector*-btRecipSqrt(lenSqr);
+	}
+	pointOnB = transformB.getOrigin()+offsetB + normalOnB * capsuleRadiusB;
+
+	return distance;
+}
+
+
+
+
+
+
+
+//////////
 
 
@@ -70,5 +197,5 @@
 m_lowLevelOfDetail(false),
 #ifdef USE_SEPDISTANCE_UTIL2
-,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
+m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
 			  (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()),
 #endif
@@ -112,6 +239,6 @@
 		m_transformA(transformA),
 		m_transformB(transformB),
+		m_unPerturbedTransform(unPerturbedTransform),
 		m_perturbA(perturbA),
-		m_unPerturbedTransform(unPerturbedTransform),
 		m_debugDrawer(debugDrawer)
 	{
@@ -156,4 +283,5 @@
 extern btScalar gContactBreakingThreshold;
 
+
 //
 // Convex-Convex collision algorithm
@@ -177,6 +305,37 @@
 	btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
 
+	btVector3  normalOnB;
+		btVector3  pointOnBWorld;
+#ifndef BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
+	if ((min0->getShapeType() == CAPSULE_SHAPE_PROXYTYPE) && (min1->getShapeType() == CAPSULE_SHAPE_PROXYTYPE))
+	{
+		btCapsuleShape* capsuleA = (btCapsuleShape*) min0;
+		btCapsuleShape* capsuleB = (btCapsuleShape*) min1;
+		btVector3 localScalingA = capsuleA->getLocalScaling();
+		btVector3 localScalingB = capsuleB->getLocalScaling();
+		
+		btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
+
+		btScalar dist = capsuleCapsuleDistance(normalOnB,	pointOnBWorld,capsuleA->getHalfHeight(),capsuleA->getRadius(),
+			capsuleB->getHalfHeight(),capsuleB->getRadius(),capsuleA->getUpAxis(),capsuleB->getUpAxis(),
+			body0->getWorldTransform(),body1->getWorldTransform(),threshold);
+
+		if (dist<threshold)
+		{
+			btAssert(normalOnB.length2()>=(SIMD_EPSILON*SIMD_EPSILON));
+			resultOut->addContactPoint(normalOnB,pointOnBWorld,dist);	
+		}
+		resultOut->refreshContactPoints();
+		return;
+	}
+#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
+
+
 #ifdef USE_SEPDISTANCE_UTIL2
-	m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
+	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+	{
+		m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
+	}
+
 	if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
 #endif //USE_SEPDISTANCE_UTIL2
@@ -195,9 +354,15 @@
 	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
 	{
-		input.m_maximumDistanceSquared = 1e30f;
+		input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
 	} else
 #endif //USE_SEPDISTANCE_UTIL2
 	{
-		input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
+		if (dispatchInfo.m_convexMaxDistanceUseCPT)
+		{
+			input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
+		} else
+		{
+			input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
+		}
 		input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
 	}
@@ -208,17 +373,34 @@
 
 	gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
-	btScalar sepDist = gjkPairDetector.getCachedSeparatingDistance()+dispatchInfo.m_convexConservativeDistanceThreshold;
-
-	//now perturbe directions to get multiple contact points
-	btVector3 v0,v1;
-	btVector3 sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
-	btPlaneSpace1(sepNormalWorldSpace,v0,v1);
+
+	
+
+#ifdef USE_SEPDISTANCE_UTIL2
+	btScalar sepDist = 0.f;
+	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+	{
+		sepDist = gjkPairDetector.getCachedSeparatingDistance();
+		if (sepDist>SIMD_EPSILON)
+		{
+			sepDist += dispatchInfo.m_convexConservativeDistanceThreshold;
+			//now perturbe directions to get multiple contact points
+			
+		}
+	}
+#endif //USE_SEPDISTANCE_UTIL2
+
 	//now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
 	
 	//perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
-	if (resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
+	if (m_numPerturbationIterations && resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
 	{
 		
 		int i;
+		btVector3 v0,v1;
+		btVector3 sepNormalWorldSpace;
+	
+		sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
+		btPlaneSpace1(sepNormalWorldSpace,v0,v1);
+
 
 		bool perturbeA = true;
@@ -250,4 +432,6 @@
 		for ( i=0;i<m_numPerturbationIterations;i++)
 		{
+			if (v0.length2()>SIMD_EPSILON)
+			{
 			btQuaternion perturbeRot(v0,perturbeAngle);
 			btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
@@ -273,6 +457,6 @@
 			btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
 			gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
+			}
 			
-			
 		}
 	}
@@ -281,5 +465,5 @@
 
 #ifdef USE_SEPDISTANCE_UTIL2
-	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+	if (dispatchInfo.m_useConvexConservativeDistanceUtil && (sepDist>SIMD_EPSILON))
 	{
 		m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform());
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h	(revision 8284)
@@ -32,5 +32,6 @@
 ///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util
 ///for certain pairs that have a small size ratio
-///#define USE_SEPDISTANCE_UTIL2 1
+
+//#define USE_SEPDISTANCE_UTIL2 1
 
 ///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp	(revision 8284)
@@ -103,7 +103,7 @@
 	btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
 
-    bool hasCollision = false;
+    
 	const btVector3& planeNormal = planeShape->getPlaneNormal();
-	const btScalar& planeConstant = planeShape->getPlaneConstant();
+	//const btScalar& planeConstant = planeShape->getPlaneConstant();
 
 	//first perform a collision query with the non-perturbated collision objects
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h	(revision 8284)
@@ -61,6 +61,6 @@
 			
 		CreateFunc() 
-			: m_numPerturbationIterations(3),
-			m_minimumPointsPerturbationThreshold(3)
+			: m_numPerturbationIterations(1),
+			m_minimumPointsPerturbationThreshold(1)
 		{
 		}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp	(revision 8284)
@@ -46,15 +46,15 @@
 	void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16);
 	m_simplexSolver = new (mem)btVoronoiSimplexSolver();
-	
-#define USE_EPA 1
-#ifdef USE_EPA
-	mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
-	m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver;
-#else
-	mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16);
-	m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver;
-#endif//USE_EPA	
-	
-
+
+	if (constructionInfo.m_useEpaPenetrationAlgorithm)
+	{
+		mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
+		m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver;
+	}else
+	{
+		mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16);
+		m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver;
+	}
+	
 	//default CreationFunctions, filling the m_doubleDispatch table
 	mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
@@ -103,5 +103,6 @@
 	int sl = sizeof(btConvexSeparatingDistanceUtil);
 	sl = sizeof(btGjkPairDetector);
-	int	collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
+	int	collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize);
+	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
 	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h	(revision 8284)
@@ -28,5 +28,7 @@
 	int					m_defaultMaxPersistentManifoldPoolSize;
 	int					m_defaultMaxCollisionAlgorithmPoolSize;
+	int					m_customCollisionAlgorithmMaxElementSize;
 	int					m_defaultStackAllocatorSize;
+	int					m_useEpaPenetrationAlgorithm;
 
 	btDefaultCollisionConstructionInfo()
@@ -36,5 +38,7 @@
 		m_defaultMaxPersistentManifoldPoolSize(4096),
 		m_defaultMaxCollisionAlgorithmPoolSize(4096),
-		m_defaultStackAllocatorSize(0)
+		m_customCollisionAlgorithmMaxElementSize(0),
+		m_defaultStackAllocatorSize(0),
+		m_useEpaPenetrationAlgorithm(true)
 	{
 	}
@@ -109,4 +113,9 @@
 	}
 
+	virtual	btVoronoiSimplexSolver*	getSimplexSolver()
+	{
+		return m_simplexSolver;
+	}
+
 
 	virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.h	(revision 8284)
@@ -161,5 +161,5 @@
 	}
 
-	virtual void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher)
+	virtual void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
 	{
 		btAssert(0);
@@ -173,2 +173,3 @@
 
 #endif
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp	(revision 8284)
@@ -0,0 +1,772 @@
+#include "btInternalEdgeUtility.h"
+
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
+#include "LinearMath/btIDebugDraw.h"
+
+
+//#define DEBUG_INTERNAL_EDGE
+
+
+#ifdef DEBUG_INTERNAL_EDGE
+#include <stdio.h>
+#endif //DEBUG_INTERNAL_EDGE
+
+
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+static btIDebugDraw* gDebugDrawer = 0;
+
+void	btSetDebugDrawer(btIDebugDraw* debugDrawer)
+{
+	gDebugDrawer = debugDrawer;
+}
+
+static void    btDebugDrawLine(const btVector3& from,const btVector3& to, const btVector3& color)
+{
+	if (gDebugDrawer)
+		gDebugDrawer->drawLine(from,to,color);
+}
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+
+static int	btGetHash(int partId, int triangleIndex)
+{
+	int hash = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
+	return hash;
+}
+
+
+
+static btScalar btGetAngle(const btVector3& edgeA, const btVector3& normalA,const btVector3& normalB)
+{
+	const btVector3 refAxis0  = edgeA;
+	const btVector3 refAxis1  = normalA;
+	const btVector3 swingAxis = normalB;
+	btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1));
+	return  angle;
+}
+
+
+struct btConnectivityProcessor : public btTriangleCallback
+{
+	int				m_partIdA;
+	int				m_triangleIndexA;
+	btVector3*		m_triangleVerticesA;
+	btTriangleInfoMap*	m_triangleInfoMap;
+
+
+	virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
+	{
+		//skip self-collisions
+		if ((m_partIdA == partId) && (m_triangleIndexA == triangleIndex))
+			return;
+
+		//skip duplicates (disabled for now)
+		//if ((m_partIdA <= partId) && (m_triangleIndexA <= triangleIndex))
+		//	return;
+
+		//search for shared vertices and edges
+		int numshared = 0;
+		int sharedVertsA[3]={-1,-1,-1};
+		int sharedVertsB[3]={-1,-1,-1};
+
+		///skip degenerate triangles
+		btScalar crossBSqr = ((triangle[1]-triangle[0]).cross(triangle[2]-triangle[0])).length2();
+		if (crossBSqr < m_triangleInfoMap->m_equalVertexThreshold)
+			return;
+
+
+		btScalar crossASqr = ((m_triangleVerticesA[1]-m_triangleVerticesA[0]).cross(m_triangleVerticesA[2]-m_triangleVerticesA[0])).length2();
+		///skip degenerate triangles
+		if (crossASqr< m_triangleInfoMap->m_equalVertexThreshold)
+			return;
+
+#if 0
+		printf("triangle A[0]	=	(%f,%f,%f)\ntriangle A[1]	=	(%f,%f,%f)\ntriangle A[2]	=	(%f,%f,%f)\n",
+			m_triangleVerticesA[0].getX(),m_triangleVerticesA[0].getY(),m_triangleVerticesA[0].getZ(),
+			m_triangleVerticesA[1].getX(),m_triangleVerticesA[1].getY(),m_triangleVerticesA[1].getZ(),
+			m_triangleVerticesA[2].getX(),m_triangleVerticesA[2].getY(),m_triangleVerticesA[2].getZ());
+
+		printf("partId=%d, triangleIndex=%d\n",partId,triangleIndex);
+		printf("triangle B[0]	=	(%f,%f,%f)\ntriangle B[1]	=	(%f,%f,%f)\ntriangle B[2]	=	(%f,%f,%f)\n",
+			triangle[0].getX(),triangle[0].getY(),triangle[0].getZ(),
+			triangle[1].getX(),triangle[1].getY(),triangle[1].getZ(),
+			triangle[2].getX(),triangle[2].getY(),triangle[2].getZ());
+#endif
+
+		for (int i=0;i<3;i++)
+		{
+			for (int j=0;j<3;j++)
+			{
+				if ( (m_triangleVerticesA[i]-triangle[j]).length2() < m_triangleInfoMap->m_equalVertexThreshold)
+				{
+					sharedVertsA[numshared] = i;
+					sharedVertsB[numshared] = j;
+					numshared++;
+					///degenerate case
+					if(numshared >= 3)
+						return;
+				}
+			}
+			///degenerate case
+			if(numshared >= 3)
+				return;
+		}
+		switch (numshared)
+		{
+		case 0:
+			{
+				break;
+			}
+		case 1:
+			{
+				//shared vertex
+				break;
+			}
+		case 2:
+			{
+				//shared edge
+				//we need to make sure the edge is in the order V2V0 and not V0V2 so that the signs are correct
+				if (sharedVertsA[0] == 0 && sharedVertsA[1] == 2)
+				{
+					sharedVertsA[0] = 2;
+					sharedVertsA[1] = 0;
+					int tmp = sharedVertsB[1];
+					sharedVertsB[1] = sharedVertsB[0];
+					sharedVertsB[0] = tmp;
+				}
+
+				int hash = btGetHash(m_partIdA,m_triangleIndexA);
+
+				btTriangleInfo* info = m_triangleInfoMap->find(hash);
+				if (!info)
+				{
+					btTriangleInfo tmp;
+					m_triangleInfoMap->insert(hash,tmp);
+					info = m_triangleInfoMap->find(hash);
+				}
+
+				int sumvertsA = sharedVertsA[0]+sharedVertsA[1];
+				int otherIndexA = 3-sumvertsA;
+
+				
+				btVector3 edge(m_triangleVerticesA[sharedVertsA[1]]-m_triangleVerticesA[sharedVertsA[0]]);
+
+				btTriangleShape tA(m_triangleVerticesA[0],m_triangleVerticesA[1],m_triangleVerticesA[2]);
+				int otherIndexB = 3-(sharedVertsB[0]+sharedVertsB[1]);
+
+				btTriangleShape tB(triangle[sharedVertsB[1]],triangle[sharedVertsB[0]],triangle[otherIndexB]);
+				//btTriangleShape tB(triangle[0],triangle[1],triangle[2]);
+
+				btVector3 normalA;
+				btVector3 normalB;
+				tA.calcNormal(normalA);
+				tB.calcNormal(normalB);
+				edge.normalize();
+				btVector3 edgeCrossA = edge.cross(normalA).normalize();
+
+				{
+					btVector3 tmp = m_triangleVerticesA[otherIndexA]-m_triangleVerticesA[sharedVertsA[0]];
+					if (edgeCrossA.dot(tmp) < 0)
+					{
+						edgeCrossA*=-1;
+					}
+				}
+
+				btVector3 edgeCrossB = edge.cross(normalB).normalize();
+
+				{
+					btVector3 tmp = triangle[otherIndexB]-triangle[sharedVertsB[0]];
+					if (edgeCrossB.dot(tmp) < 0)
+					{
+						edgeCrossB*=-1;
+					}
+				}
+
+				btScalar	angle2 = 0;
+				btScalar	ang4 = 0.f;
+
+
+				btVector3 calculatedEdge = edgeCrossA.cross(edgeCrossB);
+				btScalar len2 = calculatedEdge.length2();
+
+				btScalar correctedAngle(0);
+				btVector3 calculatedNormalB = normalA;
+				bool isConvex = false;
+
+				if (len2<m_triangleInfoMap->m_planarEpsilon)
+				{
+					angle2 = 0.f;
+					ang4 = 0.f;
+				} else
+				{
+
+					calculatedEdge.normalize();
+					btVector3 calculatedNormalA = calculatedEdge.cross(edgeCrossA);
+					calculatedNormalA.normalize();
+					angle2 = btGetAngle(calculatedNormalA,edgeCrossA,edgeCrossB);
+					ang4 = SIMD_PI-angle2;
+					btScalar dotA = normalA.dot(edgeCrossB);
+					///@todo: check if we need some epsilon, due to floating point imprecision
+					isConvex = (dotA<0.);
+
+					correctedAngle = isConvex ? ang4 : -ang4;
+					btQuaternion orn2(calculatedEdge,-correctedAngle);
+					calculatedNormalB = btMatrix3x3(orn2)*normalA;
+
+
+				}
+
+				
+
+				
+							
+				//alternatively use 
+				//btVector3 calculatedNormalB2 = quatRotate(orn,normalA);
+
+
+				switch (sumvertsA)
+				{
+				case 1:
+					{
+						btVector3 edge = m_triangleVerticesA[0]-m_triangleVerticesA[1];
+						btQuaternion orn(edge,-correctedAngle);
+						btVector3 computedNormalB = quatRotate(orn,normalA);
+						btScalar bla = computedNormalB.dot(normalB);
+						if (bla<0)
+						{
+							computedNormalB*=-1;
+							info->m_flags |= TRI_INFO_V0V1_SWAP_NORMALB;
+						}
+#ifdef DEBUG_INTERNAL_EDGE
+						if ((computedNormalB-normalB).length()>0.0001)
+						{
+							printf("warning: normals not identical\n");
+						}
+#endif//DEBUG_INTERNAL_EDGE
+
+						info->m_edgeV0V1Angle = -correctedAngle;
+
+						if (isConvex)
+							info->m_flags |= TRI_INFO_V0V1_CONVEX;
+						break;
+					}
+				case 2:
+					{
+						btVector3 edge = m_triangleVerticesA[2]-m_triangleVerticesA[0];
+						btQuaternion orn(edge,-correctedAngle);
+						btVector3 computedNormalB = quatRotate(orn,normalA);
+						if (computedNormalB.dot(normalB)<0)
+						{
+							computedNormalB*=-1;
+							info->m_flags |= TRI_INFO_V2V0_SWAP_NORMALB;
+						}
+
+#ifdef DEBUG_INTERNAL_EDGE
+						if ((computedNormalB-normalB).length()>0.0001)
+						{
+							printf("warning: normals not identical\n");
+						}
+#endif //DEBUG_INTERNAL_EDGE
+						info->m_edgeV2V0Angle = -correctedAngle;
+						if (isConvex)
+							info->m_flags |= TRI_INFO_V2V0_CONVEX;
+						break;	
+					}
+				case 3:
+					{
+						btVector3 edge = m_triangleVerticesA[1]-m_triangleVerticesA[2];
+						btQuaternion orn(edge,-correctedAngle);
+						btVector3 computedNormalB = quatRotate(orn,normalA);
+						if (computedNormalB.dot(normalB)<0)
+						{
+							info->m_flags |= TRI_INFO_V1V2_SWAP_NORMALB;
+							computedNormalB*=-1;
+						}
+#ifdef DEBUG_INTERNAL_EDGE
+						if ((computedNormalB-normalB).length()>0.0001)
+						{
+							printf("warning: normals not identical\n");
+						}
+#endif //DEBUG_INTERNAL_EDGE
+						info->m_edgeV1V2Angle = -correctedAngle;
+
+						if (isConvex)
+							info->m_flags |= TRI_INFO_V1V2_CONVEX;
+						break;
+					}
+				}
+
+				break;
+			}
+		default:
+			{
+				//				printf("warning: duplicate triangle\n");
+			}
+
+		}
+	}
+};
+/////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////
+
+void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap)
+{
+	//the user pointer shouldn't already be used for other purposes, we intend to store connectivity info there!
+	if (trimeshShape->getTriangleInfoMap())
+		return;
+
+	trimeshShape->setTriangleInfoMap(triangleInfoMap);
+
+	btStridingMeshInterface* meshInterface = trimeshShape->getMeshInterface();
+	const btVector3& meshScaling = meshInterface->getScaling();
+
+	for (int partId = 0; partId< meshInterface->getNumSubParts();partId++)
+	{
+		const unsigned char *vertexbase = 0;
+		int numverts = 0;
+		PHY_ScalarType type = PHY_INTEGER;
+		int stride = 0;
+		const unsigned char *indexbase = 0;
+		int indexstride = 0;
+		int numfaces = 0;
+		PHY_ScalarType indicestype = PHY_INTEGER;
+		//PHY_ScalarType indexType=0;
+
+		btVector3 triangleVerts[3];
+		meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,	type,stride,&indexbase,indexstride,numfaces,indicestype,partId);
+		btVector3 aabbMin,aabbMax;
+
+		for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++)
+		{
+			unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride);
+
+			for (int j=2;j>=0;j--)
+			{
+
+				int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
+				if (type == PHY_FLOAT)
+				{
+					float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+					triangleVerts[j] = btVector3(
+						graphicsbase[0]*meshScaling.getX(),
+						graphicsbase[1]*meshScaling.getY(),
+						graphicsbase[2]*meshScaling.getZ());
+				}
+				else
+				{
+					double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+					triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ()));
+				}
+			}
+			aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+			aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); 
+			aabbMin.setMin(triangleVerts[0]);
+			aabbMax.setMax(triangleVerts[0]);
+			aabbMin.setMin(triangleVerts[1]);
+			aabbMax.setMax(triangleVerts[1]);
+			aabbMin.setMin(triangleVerts[2]);
+			aabbMax.setMax(triangleVerts[2]);
+
+			btConnectivityProcessor connectivityProcessor;
+			connectivityProcessor.m_partIdA = partId;
+			connectivityProcessor.m_triangleIndexA = triangleIndex;
+			connectivityProcessor.m_triangleVerticesA = &triangleVerts[0];
+			connectivityProcessor.m_triangleInfoMap  = triangleInfoMap;
+
+			trimeshShape->processAllTriangles(&connectivityProcessor,aabbMin,aabbMax);
+		}
+
+	}
+
+}
+
+
+
+
+// Given a point and a line segment (defined by two points), compute the closest point
+// in the line.  Cap the point at the endpoints of the line segment.
+void btNearestPointInLineSegment(const btVector3 &point, const btVector3& line0, const btVector3& line1, btVector3& nearestPoint)
+{
+	btVector3 lineDelta     = line1 - line0;
+
+	// Handle degenerate lines
+	if ( lineDelta.fuzzyZero())
+	{
+		nearestPoint = line0;
+	}
+	else
+	{
+		btScalar delta = (point-line0).dot(lineDelta) / (lineDelta).dot(lineDelta);
+
+		// Clamp the point to conform to the segment's endpoints
+		if ( delta < 0 )
+			delta = 0;
+		else if ( delta > 1 )
+			delta = 1;
+
+		nearestPoint = line0 + lineDelta*delta;
+	}
+}
+
+
+
+
+bool	btClampNormal(const btVector3& edge,const btVector3& tri_normal_org,const btVector3& localContactNormalOnB, btScalar correctedEdgeAngle, btVector3 & clampedLocalNormal)
+{
+	btVector3 tri_normal = tri_normal_org;
+	//we only have a local triangle normal, not a local contact normal -> only normal in world space...
+	//either compute the current angle all in local space, or all in world space
+
+	btVector3 edgeCross = edge.cross(tri_normal).normalize();
+	btScalar curAngle = btGetAngle(edgeCross,tri_normal,localContactNormalOnB);
+
+	if (correctedEdgeAngle<0)
+	{
+		if (curAngle < correctedEdgeAngle)
+		{
+			btScalar diffAngle = correctedEdgeAngle-curAngle;
+			btQuaternion rotation(edge,diffAngle );
+			clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB;
+			return true;
+		}
+	}
+
+	if (correctedEdgeAngle>=0)
+	{
+		if (curAngle > correctedEdgeAngle)
+		{
+			btScalar diffAngle = correctedEdgeAngle-curAngle;
+			btQuaternion rotation(edge,diffAngle );
+			clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB;
+			return true;
+		}
+	}
+	return false;
+}
+
+
+
+/// Changes a btManifoldPoint collision normal to the normal from the mesh.
+void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* colObj0,const btCollisionObject* colObj1, int partId0, int index0, int normalAdjustFlags)
+{
+	//btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE);
+	if (colObj0->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE)
+		return;
+
+	btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)colObj0->getRootCollisionShape();
+	btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*) trimesh->getTriangleInfoMap();
+	if (!triangleInfoMapPtr)
+		return;
+
+	int hash = btGetHash(partId0,index0);
+
+
+	btTriangleInfo* info = triangleInfoMapPtr->find(hash);
+	if (!info)
+		return;
+
+	btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE)==0? 1.f : -1.f;
+	
+	const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0->getCollisionShape());
+	btVector3 v0,v1,v2;
+	tri_shape->getVertex(0,v0);
+	tri_shape->getVertex(1,v1);
+	tri_shape->getVertex(2,v2);
+
+	btVector3 center = (v0+v1+v2)*btScalar(1./3.);
+
+	btVector3 red(1,0,0), green(0,1,0),blue(0,0,1),white(1,1,1),black(0,0,0);
+	btVector3 tri_normal;
+	tri_shape->calcNormal(tri_normal);
+
+	//btScalar dot = tri_normal.dot(cp.m_normalWorldOnB);
+	btVector3 nearest;
+	btNearestPointInLineSegment(cp.m_localPointB,v0,v1,nearest);
+
+	btVector3 contact = cp.m_localPointB;
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+	const btTransform& tr = colObj0->getWorldTransform();
+	btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,red);
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+
+
+	bool isNearEdge = false;
+
+	int numConcaveEdgeHits = 0;
+	int numConvexEdgeHits = 0;
+
+	btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
+	localContactNormalOnB.normalize();//is this necessary?
+
+	if ((info->m_edgeV0V1Angle)< SIMD_2_PI)
+	{
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+		btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
+#endif
+		btScalar len = (contact-nearest).length();
+		if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
+		{
+			btVector3 edge(v0-v1);
+			isNearEdge = true;
+
+			if (info->m_edgeV0V1Angle==btScalar(0))
+			{
+				numConcaveEdgeHits++;
+			} else
+			{
+
+				bool isEdgeConvex = (info->m_flags & TRI_INFO_V0V1_CONVEX);
+				btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
+	#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+				btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
+	#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+				btVector3 nA = swapFactor * tri_normal;
+
+				btQuaternion orn(edge,info->m_edgeV0V1Angle);
+				btVector3 computedNormalB = quatRotate(orn,tri_normal);
+				if (info->m_flags & TRI_INFO_V0V1_SWAP_NORMALB)
+					computedNormalB*=-1;
+				btVector3 nB = swapFactor*computedNormalB;
+
+				btScalar	NdotA = localContactNormalOnB.dot(nA);
+				btScalar	NdotB = localContactNormalOnB.dot(nB);
+				bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
+
+#ifdef DEBUG_INTERNAL_EDGE
+				{
+					
+					btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
+				}
+#endif //DEBUG_INTERNAL_EDGE
+
+
+				if (backFacingNormal)
+				{
+					numConcaveEdgeHits++;
+				}
+				else
+				{
+					numConvexEdgeHits++;
+					btVector3 clampedLocalNormal;
+					bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV0V1Angle,clampedLocalNormal);
+					if (isClamped)
+					{
+						if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
+						{
+							btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
+							//					cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
+							cp.m_normalWorldOnB = newNormal;
+							// Reproject collision point along normal. (what about cp.m_distance1?)
+							cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
+							cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
+							
+						}
+					}
+				}
+			}
+		}
+	}
+
+	btNearestPointInLineSegment(contact,v1,v2,nearest);
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+	btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,green);
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+	if ((info->m_edgeV1V2Angle)< SIMD_2_PI)
+	{
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+		btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+
+
+		btScalar len = (contact-nearest).length();
+		if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
+		{
+			isNearEdge = true;
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+			btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white);
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+			btVector3 edge(v1-v2);
+
+			isNearEdge = true;
+
+			if (info->m_edgeV1V2Angle == btScalar(0))
+			{
+				numConcaveEdgeHits++;
+			} else
+			{
+				bool isEdgeConvex = (info->m_flags & TRI_INFO_V1V2_CONVEX)!=0;
+				btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
+	#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+				btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
+	#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+				btVector3 nA = swapFactor * tri_normal;
+				
+				btQuaternion orn(edge,info->m_edgeV1V2Angle);
+				btVector3 computedNormalB = quatRotate(orn,tri_normal);
+				if (info->m_flags & TRI_INFO_V1V2_SWAP_NORMALB)
+					computedNormalB*=-1;
+				btVector3 nB = swapFactor*computedNormalB;
+
+#ifdef DEBUG_INTERNAL_EDGE
+				{
+					btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
+				}
+#endif //DEBUG_INTERNAL_EDGE
+
+
+				btScalar	NdotA = localContactNormalOnB.dot(nA);
+				btScalar	NdotB = localContactNormalOnB.dot(nB);
+				bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
+
+				if (backFacingNormal)
+				{
+					numConcaveEdgeHits++;
+				}
+				else
+				{
+					numConvexEdgeHits++;
+					btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
+					btVector3 clampedLocalNormal;
+					bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal);
+					if (isClamped)
+					{
+						if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
+						{
+							btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
+							//					cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
+							cp.m_normalWorldOnB = newNormal;
+							// Reproject collision point along normal.
+							cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
+							cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	btNearestPointInLineSegment(contact,v2,v0,nearest);
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+	btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,blue);
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+	if ((info->m_edgeV2V0Angle)< SIMD_2_PI)
+	{
+
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+		btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black);
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+		btScalar len = (contact-nearest).length();
+		if(len<triangleInfoMapPtr->m_edgeDistanceThreshold)
+		{
+			isNearEdge = true;
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+			btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white);
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+			btVector3 edge(v2-v0);
+
+			if (info->m_edgeV2V0Angle==btScalar(0))
+			{
+				numConcaveEdgeHits++;
+			} else
+			{
+
+				bool isEdgeConvex = (info->m_flags & TRI_INFO_V2V0_CONVEX)!=0;
+				btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1);
+	#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+				btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white);
+	#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+				btVector3 nA = swapFactor * tri_normal;
+				btQuaternion orn(edge,info->m_edgeV2V0Angle);
+				btVector3 computedNormalB = quatRotate(orn,tri_normal);
+				if (info->m_flags & TRI_INFO_V2V0_SWAP_NORMALB)
+					computedNormalB*=-1;
+				btVector3 nB = swapFactor*computedNormalB;
+
+#ifdef DEBUG_INTERNAL_EDGE
+				{
+					btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red);
+				}
+#endif //DEBUG_INTERNAL_EDGE
+
+				btScalar	NdotA = localContactNormalOnB.dot(nA);
+				btScalar	NdotB = localContactNormalOnB.dot(nB);
+				bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotB<triangleInfoMapPtr->m_convexEpsilon);
+
+				if (backFacingNormal)
+				{
+					numConcaveEdgeHits++;
+				}
+				else
+				{
+					numConvexEdgeHits++;
+					//				printf("hitting convex edge\n");
+
+
+					btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
+					btVector3 clampedLocalNormal;
+					bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal);
+					if (isClamped)
+					{
+						if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
+						{
+							btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
+							//					cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
+							cp.m_normalWorldOnB = newNormal;
+							// Reproject collision point along normal.
+							cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
+							cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
+						}
+					}
+				} 
+			}
+			
+
+		}
+	}
+
+#ifdef DEBUG_INTERNAL_EDGE
+	{
+		btVector3 color(0,1,1);
+		btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+cp.m_normalWorldOnB*10,color);
+	}
+#endif //DEBUG_INTERNAL_EDGE
+
+	if (isNearEdge)
+	{
+
+		if (numConcaveEdgeHits>0)
+		{
+			if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_DOUBLE_SIDED)!=0)
+			{
+				//fix tri_normal so it pointing the same direction as the current local contact normal
+				if (tri_normal.dot(localContactNormalOnB) < 0)
+				{
+					tri_normal *= -1;
+				}
+				cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis()*tri_normal;
+			} else
+			{
+				//modify the normal to be the triangle normal (or backfacing normal)
+				cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis() *(tri_normal *frontFacing);
+			}
+			
+			
+			// Reproject collision point along normal.
+			cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
+			cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
+		}
+	}
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h	(revision 8284)
@@ -0,0 +1,46 @@
+
+#ifndef BT_INTERNAL_EDGE_UTILITY_H
+#define BT_INTERNAL_EDGE_UTILITY_H
+
+#include "LinearMath/btHashMap.h"
+#include "LinearMath/btVector3.h"
+
+#include "BulletCollision/CollisionShapes/btTriangleInfoMap.h"
+
+///The btInternalEdgeUtility helps to avoid or reduce artifacts due to wrong collision normals caused by internal edges.
+///See also http://code.google.com/p/bullet/issues/detail?id=27
+
+class btBvhTriangleMeshShape;
+class btCollisionObject;
+class btManifoldPoint;
+class btIDebugDraw;
+
+
+
+enum btInternalEdgeAdjustFlags
+{
+	BT_TRIANGLE_CONVEX_BACKFACE_MODE = 1,
+	BT_TRIANGLE_CONCAVE_DOUBLE_SIDED = 2, //double sided options are experimental, single sided is recommended
+	BT_TRIANGLE_CONVEX_DOUBLE_SIDED = 4
+};
+
+
+///Call btGenerateInternalEdgeInfo to create triangle info, store in the shape 'userInfo'
+void	btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap);
+
+
+///Call the btFixMeshNormal to adjust the collision normal, using the triangle info map (generated using btGenerateInternalEdgeInfo)
+///If this info map is missing, or the triangle is not store in this map, nothing will be done
+void	btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* trimeshColObj0,const btCollisionObject* otherColObj1, int partId0, int index0, int normalAdjustFlags = 0);
+
+///Enable the BT_INTERNAL_EDGE_DEBUG_DRAW define and call btSetDebugDrawer, to get visual info to see if the internal edge utility works properly.
+///If the utility doesn't work properly, you might have to adjust the threshold values in btTriangleInfoMap
+//#define BT_INTERNAL_EDGE_DEBUG_DRAW
+
+#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW
+void	btSetDebugDrawer(btIDebugDraw* debugDrawer);
+#endif //BT_INTERNAL_EDGE_DEBUG_DRAW
+
+
+#endif //BT_INTERNAL_EDGE_UTILITY_H
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp	(revision 8284)
@@ -48,4 +48,10 @@
 		m_body0(body0),
 		m_body1(body1)
+#ifdef DEBUG_PART_INDEX
+		,m_partId0(-1),
+	m_partId1(-1),
+	m_index0(-1),
+	m_index1(-1)
+#endif //DEBUG_PART_INDEX
 {
 	m_rootTransA = body0->getWorldTransform();
@@ -89,8 +95,17 @@
 
    //BP mod, store contact triangles.
-   newPt.m_partId0 = m_partId0;
-   newPt.m_partId1 = m_partId1;
-   newPt.m_index0  = m_index0;
-   newPt.m_index1  = m_index1;
+	if (isSwapped)
+	{
+		newPt.m_partId0 = m_partId1;
+		newPt.m_partId1 = m_partId0;
+		newPt.m_index0  = m_index1;
+		newPt.m_index1  = m_index0;
+	} else
+	{
+		newPt.m_partId0 = m_partId0;
+		newPt.m_partId1 = m_partId1;
+		newPt.m_index0  = m_index0;
+		newPt.m_index1  = m_index1;
+	}
 	//printf("depth=%f\n",depth);
 	///@todo, check this for any side effects
@@ -113,5 +128,5 @@
 		btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
 		btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
-		(*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);
+		(*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0,newPt.m_partId0,newPt.m_index0,obj1,newPt.m_partId1,newPt.m_index1);
 	}
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.h	(revision 8284)
@@ -29,4 +29,5 @@
 extern ContactAddedCallback		gContactAddedCallback;
 
+//#define DEBUG_PART_INDEX 1
 
 
@@ -34,4 +35,6 @@
 class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
 {
+protected:
+
 	btPersistentManifold* m_manifoldPtr;
 
@@ -51,4 +54,11 @@
 
 	btManifoldResult()
+#ifdef DEBUG_PART_INDEX
+		:
+	m_partId0(-1),
+	m_partId1(-1),
+	m_index0(-1),
+	m_index1(-1)
+#endif //DEBUG_PART_INDEX
 	{
 	}
@@ -72,10 +82,14 @@
 	}
 
-	virtual void setShapeIdentifiers(int partId0,int index0,	int partId1,int index1)
+	virtual void setShapeIdentifiersA(int partId0,int index0)
 	{
-			m_partId0=partId0;
-			m_partId1=partId1;
-			m_index0=index0;
-			m_index1=index1;		
+		m_partId0=partId0;
+		m_index0=index0;
+	}
+
+	virtual void setShapeIdentifiersB(	int partId1,int index1)
+	{
+		m_partId1=partId1;
+		m_index1=index1;
 	}
 
@@ -100,5 +114,14 @@
 	}
 
+	const btCollisionObject* getBody0Internal() const
+	{
+		return m_body0;
+	}
 
+	const btCollisionObject* getBody1Internal() const
+	{
+		return m_body1;
+	}
+	
 };
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp	(revision 8284)
@@ -1,2 +1,3 @@
+
 /*
 Bullet Continuous Collision Detection and Physics Library
@@ -45,8 +46,10 @@
 	
 	{
+		btOverlappingPairCache* pairCachePtr = colWorld->getPairCache();
+		const int numOverlappingPairs = pairCachePtr->getNumOverlappingPairs();
+		btBroadphasePair* pairPtr = pairCachePtr->getOverlappingPairArrayPtr();
 		
-		for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
-		{
-			btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
+		for (int i=0;i<numOverlappingPairs;i++)
+		{
 			const btBroadphasePair& collisionPair = pairPtr[i];
 			btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
@@ -64,13 +67,67 @@
 }
 
-
+#ifdef STATIC_SIMULATION_ISLAND_OPTIMIZATION
+void   btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher)
+{
+
+	// put the index into m_controllers into m_tag   
+	int index = 0;
+	{
+
+		int i;
+		for (i=0;i<colWorld->getCollisionObjectArray().size(); i++)
+		{
+			btCollisionObject*   collisionObject= colWorld->getCollisionObjectArray()[i];
+			//Adding filtering here
+			if (!collisionObject->isStaticOrKinematicObject())
+			{
+				collisionObject->setIslandTag(index++);
+			}
+			collisionObject->setCompanionId(-1);
+			collisionObject->setHitFraction(btScalar(1.));
+		}
+	}
+	// do the union find
+
+	initUnionFind( index );
+
+	findUnions(dispatcher,colWorld);
+}
+
+void   btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld)
+{
+	// put the islandId ('find' value) into m_tag   
+	{
+		int index = 0;
+		int i;
+		for (i=0;i<colWorld->getCollisionObjectArray().size();i++)
+		{
+			btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
+			if (!collisionObject->isStaticOrKinematicObject())
+			{
+				collisionObject->setIslandTag( m_unionFind.find(index) );
+				//Set the correct object offset in Collision Object Array
+				m_unionFind.getElement(index).m_sz = i;
+				collisionObject->setCompanionId(-1);
+				index++;
+			} else
+			{
+				collisionObject->setIslandTag(-1);
+				collisionObject->setCompanionId(-2);
+			}
+		}
+	}
+}
+
+
+#else //STATIC_SIMULATION_ISLAND_OPTIMIZATION
 void	btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher)
 {
-	
+
 	initUnionFind( int (colWorld->getCollisionObjectArray().size()));
-	
+
 	// put the index into m_controllers into m_tag	
 	{
-		
+
 		int index = 0;
 		int i;
@@ -82,17 +139,11 @@
 			collisionObject->setHitFraction(btScalar(1.));
 			index++;
-			
+
 		}
 	}
 	// do the union find
-	
+
 	findUnions(dispatcher,colWorld);
-	
-
-	
-}
-
-
-
+}
 
 void	btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld)
@@ -100,6 +151,6 @@
 	// put the islandId ('find' value) into m_tag	
 	{
-		
-		
+
+
 		int index = 0;
 		int i;
@@ -120,4 +171,6 @@
 	}
 }
+
+#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION
 
 inline	int	getIslandId(const btPersistentManifold* lhs)
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp	(revision 8284)
@@ -60,5 +60,5 @@
 	
 	btDiscreteCollisionDetectorInterface::ClosestPointInput input;
-	input.m_maximumDistanceSquared = btScalar(1e30);///@todo: tighter bounds
+	input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);///@todo: tighter bounds
 	input.m_transformA = sphereObj->getWorldTransform();
 	input.m_transformB = triObj->getWorldTransform();
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.cpp	(revision 8284)
@@ -71,5 +71,7 @@
 	{
 		m_elements[i].m_id = find(i);
+#ifndef STATIC_SIMULATION_ISLAND_OPTIMIZATION
 		m_elements[i].m_sz = i;
+#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION
 	}
 	
@@ -79,3 +81,2 @@
 
 }
-
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.h	(revision 8284)
@@ -19,5 +19,8 @@
 #include "LinearMath/btAlignedObjectArray.h"
 
-	#define USE_PATH_COMPRESSION 1
+#define USE_PATH_COMPRESSION 1
+
+///see for discussion of static island optimizations by Vroonsh here: http://code.google.com/p/bullet/issues/detail?id=406
+#define STATIC_SIMULATION_ISLAND_OPTIMIZATION 1
 
 struct	btElement
@@ -107,8 +110,10 @@
 	
 		#ifdef USE_PATH_COMPRESSION
-				//
-				m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id;
-		#endif //
+				const btElement* elementPtr = &m_elements[m_elements[x].m_id];
+				m_elements[x].m_id = elementPtr->m_id;
+				x = elementPtr->m_id;			
+		#else//
 				x = m_elements[x].m_id;
+		#endif		
 				//btAssert(x < m_N);
 				//btAssert(x >= 0);
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBox2dShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBox2dShape.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBox2dShape.cpp	(revision 8284)
@@ -0,0 +1,42 @@
+/*
+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 "btBox2dShape.h"
+
+
+//{ 
+
+
+void btBox2dShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax);
+}
+
+
+void	btBox2dShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	//btScalar margin = btScalar(0.);
+	btVector3 halfExtents = getHalfExtentsWithMargin();
+
+	btScalar lx=btScalar(2.)*(halfExtents.x());
+	btScalar ly=btScalar(2.)*(halfExtents.y());
+	btScalar lz=btScalar(2.)*(halfExtents.z());
+
+	inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
+					mass/(btScalar(12.0)) * (lx*lx + lz*lz),
+					mass/(btScalar(12.0)) * (lx*lx + ly*ly));
+
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBox2dShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBox2dShape.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBox2dShape.h	(revision 8284)
@@ -0,0 +1,363 @@
+/*
+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 OBB_BOX_2D_SHAPE_H
+#define OBB_BOX_2D_SHAPE_H
+
+#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMinMax.h"
+
+///The btBox2dShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
+class btBox2dShape: public btPolyhedralConvexShape
+{
+
+	//btVector3	m_boxHalfExtents1; //use m_implicitShapeDimensions instead
+
+	btVector3 m_centroid;
+	btVector3 m_vertices[4];
+	btVector3 m_normals[4];
+
+public:
+
+	btVector3 getHalfExtentsWithMargin() const
+	{
+		btVector3 halfExtents = getHalfExtentsWithoutMargin();
+		btVector3 margin(getMargin(),getMargin(),getMargin());
+		halfExtents += margin;
+		return halfExtents;
+	}
+	
+	const btVector3& getHalfExtentsWithoutMargin() const
+	{
+		return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
+	}
+	
+
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec) const
+	{
+		btVector3 halfExtents = getHalfExtentsWithoutMargin();
+		btVector3 margin(getMargin(),getMargin(),getMargin());
+		halfExtents += margin;
+		
+		return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
+			btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
+			btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
+	}
+
+	SIMD_FORCE_INLINE  btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+	{
+		const btVector3& halfExtents = getHalfExtentsWithoutMargin();
+		
+		return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
+			btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
+			btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
+	}
+
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+	{
+		const btVector3& halfExtents = getHalfExtentsWithoutMargin();
+	
+		for (int i=0;i<numVectors;i++)
+		{
+			const btVector3& vec = vectors[i];
+			supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
+				btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
+				btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); 
+		}
+
+	}
+
+
+	btBox2dShape( const btVector3& boxHalfExtents) 
+		: btPolyhedralConvexShape(),
+		m_centroid(0,0,0)
+	{
+		m_vertices[0].setValue(-boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
+		m_vertices[1].setValue(boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
+		m_vertices[2].setValue(boxHalfExtents.getX(),boxHalfExtents.getY(),0);
+		m_vertices[3].setValue(-boxHalfExtents.getX(),boxHalfExtents.getY(),0);
+
+		m_normals[0].setValue(0,-1,0);
+		m_normals[1].setValue(1,0,0);
+		m_normals[2].setValue(0,1,0);
+		m_normals[3].setValue(-1,0,0);
+
+		m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
+		btVector3 margin(getMargin(),getMargin(),getMargin());
+		m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
+	};
+
+	virtual void setMargin(btScalar collisionMargin)
+	{
+		//correct the m_implicitShapeDimensions for the margin
+		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
+		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
+		
+		btConvexInternalShape::setMargin(collisionMargin);
+		btVector3 newMargin(getMargin(),getMargin(),getMargin());
+		m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
+
+	}
+	virtual void	setLocalScaling(const btVector3& scaling)
+	{
+		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
+		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
+		btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
+
+		btConvexInternalShape::setLocalScaling(scaling);
+
+		m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
+
+	}
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+
+
+
+
+	int	getVertexCount() const
+	{
+		return 4;
+	}
+
+	virtual int getNumVertices()const
+	{
+		return 4;
+	}
+
+	const btVector3* getVertices() const
+	{
+		return &m_vertices[0];
+	}
+
+	const btVector3* getNormals() const
+	{
+		return &m_normals[0];
+	}
+
+
+
+
+
+
+
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
+	{
+		//this plane might not be aligned...
+		btVector4 plane ;
+		getPlaneEquation(plane,i);
+		planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
+		planeSupport = localGetSupportingVertex(-planeNormal);
+	}
+
+
+	const btVector3& getCentroid() const
+	{
+		return m_centroid;
+	}
+	
+	virtual int getNumPlanes() const
+	{
+		return 6;
+	}	
+	
+	
+
+	virtual int getNumEdges() const
+	{
+		return 12;
+	}
+
+
+	virtual void getVertex(int i,btVector3& vtx) const
+	{
+		btVector3 halfExtents = getHalfExtentsWithoutMargin();
+
+		vtx = btVector3(
+				halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
+				halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
+				halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
+	}
+	
+
+	virtual void	getPlaneEquation(btVector4& plane,int i) const
+	{
+		btVector3 halfExtents = getHalfExtentsWithoutMargin();
+
+		switch (i)
+		{
+		case 0:
+			plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
+			break;
+		case 1:
+			plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
+			break;
+		case 2:
+			plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
+			break;
+		case 3:
+			plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
+			break;
+		case 4:
+			plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
+			break;
+		case 5:
+			plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
+			break;
+		default:
+			btAssert(0);
+		}
+	}
+
+	
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
+	//virtual void getEdge(int i,Edge& edge) const
+	{
+		int edgeVert0 = 0;
+		int edgeVert1 = 0;
+
+		switch (i)
+		{
+		case 0:
+				edgeVert0 = 0;
+				edgeVert1 = 1;
+			break;
+		case 1:
+				edgeVert0 = 0;
+				edgeVert1 = 2;
+			break;
+		case 2:
+			edgeVert0 = 1;
+			edgeVert1 = 3;
+
+			break;
+		case 3:
+			edgeVert0 = 2;
+			edgeVert1 = 3;
+			break;
+		case 4:
+			edgeVert0 = 0;
+			edgeVert1 = 4;
+			break;
+		case 5:
+			edgeVert0 = 1;
+			edgeVert1 = 5;
+
+			break;
+		case 6:
+			edgeVert0 = 2;
+			edgeVert1 = 6;
+			break;
+		case 7:
+			edgeVert0 = 3;
+			edgeVert1 = 7;
+			break;
+		case 8:
+			edgeVert0 = 4;
+			edgeVert1 = 5;
+			break;
+		case 9:
+			edgeVert0 = 4;
+			edgeVert1 = 6;
+			break;
+		case 10:
+			edgeVert0 = 5;
+			edgeVert1 = 7;
+			break;
+		case 11:
+			edgeVert0 = 6;
+			edgeVert1 = 7;
+			break;
+		default:
+			btAssert(0);
+
+		}
+
+		getVertex(edgeVert0,pa );
+		getVertex(edgeVert1,pb );
+	}
+
+
+
+
+	
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const
+	{
+		btVector3 halfExtents = getHalfExtentsWithoutMargin();
+
+		//btScalar minDist = 2*tolerance;
+		
+		bool result =	(pt.x() <= (halfExtents.x()+tolerance)) &&
+						(pt.x() >= (-halfExtents.x()-tolerance)) &&
+						(pt.y() <= (halfExtents.y()+tolerance)) &&
+						(pt.y() >= (-halfExtents.y()-tolerance)) &&
+						(pt.z() <= (halfExtents.z()+tolerance)) &&
+						(pt.z() >= (-halfExtents.z()-tolerance));
+		
+		return result;
+	}
+
+
+	//debugging
+	virtual const char*	getName()const
+	{
+		return "Box2d";
+	}
+
+	virtual int		getNumPreferredPenetrationDirections() const
+	{
+		return 6;
+	}
+	
+	virtual void	getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
+	{
+		switch (index)
+		{
+		case 0:
+			penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
+			break;
+		case 1:
+			penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
+			break;
+		case 2:
+			penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
+			break;
+		case 3:
+			penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
+			break;
+		case 4:
+			penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
+			break;
+		case 5:
+			penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
+			break;
+		default:
+			btAssert(0);
+		}
+	}
+
+};
+
+#endif //OBB_BOX_2D_SHAPE_H
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,5 +13,4 @@
 3. This notice may not be removed or altered from any source distribution.
 */
-
 #include "btBoxShape.h"
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -42,5 +42,5 @@
 	const btVector3& getHalfExtentsWithoutMargin() const
 	{
-		return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
+		return m_implicitShapeDimensions;//scaling is included, margin is not
 	}
 	
@@ -313,4 +313,5 @@
 };
 
+
 #endif //OBB_BOX_MINKOWSKI_H
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -18,4 +18,5 @@
 #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
 #include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
+#include "LinearMath/btSerializer.h"
 
 ///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
@@ -24,4 +25,5 @@
 :btTriangleMeshShape(meshInterface),
 m_bvh(0),
+m_triangleInfoMap(0),
 m_useQuantizedAabbCompression(useQuantizedAabbCompression),
 m_ownsBvh(false)
@@ -31,20 +33,7 @@
 #ifndef DISABLE_BVH
 
-	btVector3 bvhAabbMin,bvhAabbMax;
-	if(meshInterface->hasPremadeAabb())
-	{
-		meshInterface->getPremadeAabb(&bvhAabbMin, &bvhAabbMax);
-	}
-	else
-	{
-		meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
-	}
-	
 	if (buildBvh)
 	{
-		void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
-		m_bvh = new (mem) btOptimizedBvh();
-		m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
-		m_ownsBvh = true;
+		buildOptimizedBvh();
 	}
 
@@ -56,4 +45,5 @@
 :btTriangleMeshShape(meshInterface),
 m_bvh(0),
+m_triangleInfoMap(0),
 m_useQuantizedAabbCompression(useQuantizedAabbCompression),
 m_ownsBvh(false)
@@ -344,16 +334,21 @@
    {
       btTriangleMeshShape::setLocalScaling(scaling);
-      if (m_ownsBvh)
-      {
-         m_bvh->~btOptimizedBvh();
-         btAlignedFree(m_bvh);
-      }
-      ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
-      void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
-      m_bvh = new(mem) btOptimizedBvh();
-      //rebuild the bvh...
-      m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
-      m_ownsBvh = true;
+	  buildOptimizedBvh();
    }
+}
+
+void   btBvhTriangleMeshShape::buildOptimizedBvh()
+{
+	if (m_ownsBvh)
+	{
+		m_bvh->~btOptimizedBvh();
+		btAlignedFree(m_bvh);
+	}
+	///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
+	void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+	m_bvh = new(mem) btOptimizedBvh();
+	//rebuild the bvh...
+	m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
+	m_ownsBvh = true;
 }
 
@@ -373,2 +368,99 @@
 
 
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*	btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btTriangleMeshShapeData* trimeshData = (btTriangleMeshShapeData*) dataBuffer;
+
+	btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer);
+
+	m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer);
+
+	trimeshData->m_collisionMargin = float(m_collisionMargin);
+
+	
+
+	if (m_bvh && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_BVH))
+	{
+		void* chunk = serializer->findPointer(m_bvh);
+		if (chunk)
+		{
+#ifdef BT_USE_DOUBLE_PRECISION
+			trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)chunk;
+			trimeshData->m_quantizedFloatBvh = 0;
+#else
+			trimeshData->m_quantizedFloatBvh  = (btQuantizedBvhData*)chunk;
+			trimeshData->m_quantizedDoubleBvh= 0;
+#endif //BT_USE_DOUBLE_PRECISION
+		} else
+		{
+
+#ifdef BT_USE_DOUBLE_PRECISION
+			trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh);
+			trimeshData->m_quantizedFloatBvh = 0;
+#else
+			trimeshData->m_quantizedFloatBvh  = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh);
+			trimeshData->m_quantizedDoubleBvh= 0;
+#endif //BT_USE_DOUBLE_PRECISION
+	
+			int sz = m_bvh->calculateSerializeBufferSizeNew();
+			btChunk* chunk = serializer->allocate(sz,1);
+			const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer);
+			serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,m_bvh);
+		}
+	} else
+	{
+		trimeshData->m_quantizedFloatBvh = 0;
+		trimeshData->m_quantizedDoubleBvh = 0;
+	}
+
+	
+
+	if (m_triangleInfoMap && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_TRIANGLEINFOMAP))
+	{
+		void* chunk = serializer->findPointer(m_triangleInfoMap);
+		if (chunk)
+		{
+			trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)chunk;
+		} else
+		{
+			trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)serializer->getUniquePointer(m_triangleInfoMap);
+			int sz = m_triangleInfoMap->calculateSerializeBufferSize();
+			btChunk* chunk = serializer->allocate(sz,1);
+			const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer);
+			serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,m_triangleInfoMap);
+		}
+	} else
+	{
+		trimeshData->m_triangleInfoMap = 0;
+	}
+
+	return "btTriangleMeshShapeData";
+}
+
+void	btBvhTriangleMeshShape::serializeSingleBvh(btSerializer* serializer) const
+{
+	if (m_bvh)
+	{
+		int len = m_bvh->calculateSerializeBufferSizeNew(); //make sure not to use calculateSerializeBufferSize because it is used for in-place
+		btChunk* chunk = serializer->allocate(len,1);
+		const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer);
+		serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,(void*)m_bvh);
+	}
+}
+
+void	btBvhTriangleMeshShape::serializeSingleTriangleInfoMap(btSerializer* serializer) const
+{
+	if (m_triangleInfoMap)
+	{
+		int len = m_triangleInfoMap->calculateSerializeBufferSize();
+		btChunk* chunk = serializer->allocate(len,1);
+		const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer);
+		serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,(void*)m_triangleInfoMap);
+	}
+}
+
+
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -20,5 +20,5 @@
 #include "btOptimizedBvh.h"
 #include "LinearMath/btAlignedAllocator.h"
-
+#include "btTriangleInfoMap.h"
 
 ///The btBvhTriangleMeshShape is a static-triangle mesh shape with several optimizations, such as bounding volume hierarchy and cache friendly traversal for PlayStation 3 Cell SPU. It is recommended to enable useQuantizedAabbCompression for better memory usage.
@@ -30,4 +30,6 @@
 
 	btOptimizedBvh*	m_bvh;
+	btTriangleInfoMap*	m_triangleInfoMap;
+
 	bool m_useQuantizedAabbCompression;
 	bool m_ownsBvh;
@@ -38,5 +40,5 @@
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 
-	btBvhTriangleMeshShape() : btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;};
+	btBvhTriangleMeshShape() : btTriangleMeshShape(0),m_bvh(0),m_triangleInfoMap(0),m_ownsBvh(false) {m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;};
 	btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true);
 
@@ -74,6 +76,7 @@
 	}
 
+	void	setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& localScaling=btVector3(1,1,1));
 
-	void	setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& localScaling=btVector3(1,1,1));
+	void    buildOptimizedBvh();
 
 	bool	usesQuantizedAabbCompression() const
@@ -81,6 +84,56 @@
 		return	m_useQuantizedAabbCompression;
 	}
+
+	void	setTriangleInfoMap(btTriangleInfoMap* triangleInfoMap)
+	{
+		m_triangleInfoMap = triangleInfoMap;
+	}
+
+	const btTriangleInfoMap*	getTriangleInfoMap() const
+	{
+		return m_triangleInfoMap;
+	}
+	
+	btTriangleInfoMap*	getTriangleInfoMap()
+	{
+		return m_triangleInfoMap;
+	}
+
+	virtual	int	calculateSerializeBufferSize() const;
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;
+
+	virtual void	serializeSingleBvh(btSerializer* serializer) const;
+
+	virtual void	serializeSingleTriangleInfoMap(btSerializer* serializer) const;
+
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btTriangleMeshShapeData
+{
+	btCollisionShapeData	m_collisionShapeData;
+
+	btStridingMeshInterfaceData m_meshInterface;
+
+	btQuantizedBvhFloatData		*m_quantizedFloatBvh;
+	btQuantizedBvhDoubleData	*m_quantizedDoubleBvh;
+
+	btTriangleInfoMapData	*m_triangleInfoMap;
+	
+	float	m_collisionMargin;
+
+	char m_pad3[4];
+	
+};
+
+
+SIMD_FORCE_INLINE	int	btBvhTriangleMeshShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btTriangleMeshShapeData);
 }
-;
+
+
 
 #endif //BVH_TRIANGLE_MESH_SHAPE_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -33,5 +33,5 @@
 	btVector3 supVec(0,0,0);
 
-	btScalar maxDot(btScalar(-1e30));
+	btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
 
 	btVector3 vec = vec0;
@@ -89,5 +89,5 @@
 	for (int j=0;j<numVectors;j++)
 	{
-		btScalar maxDot(btScalar(-1e30));
+		btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
 		const btVector3& vec = vectors[j];
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -44,4 +44,16 @@
 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
 	
+	virtual void setMargin(btScalar collisionMargin)
+	{
+		//correct the m_implicitShapeDimensions for the margin
+		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
+		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
+		
+		btConvexInternalShape::setMargin(collisionMargin);
+		btVector3 newMargin(getMargin(),getMargin(),getMargin());
+		m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
+
+	}
+
 	virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
 	{
@@ -77,4 +89,22 @@
 		return m_implicitShapeDimensions[m_upAxis];
 	}
+
+	virtual void	setLocalScaling(const btVector3& scaling)
+	{
+		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
+		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
+		btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
+
+		btConvexInternalShape::setLocalScaling(scaling);
+
+		m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
+
+	}
+
+	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;
+
 
 };
@@ -114,5 +144,30 @@
 };
 
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btCapsuleShapeData
+{
+	btConvexInternalShapeData	m_convexInternalShapeData;
 
+	int	m_upAxis;
+
+	char	m_padding[4];
+};
+
+SIMD_FORCE_INLINE	int	btCapsuleShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btCapsuleShapeData);
+}
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+SIMD_FORCE_INLINE	const char*	btCapsuleShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btCapsuleShapeData* shapeData = (btCapsuleShapeData*) dataBuffer;
+	
+	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer);
+
+	shapeData->m_upAxis = m_upAxis;
+	
+	return "btCapsuleShapeData";
+}
 
 #endif //BT_CAPSULE_SHAPE_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionMargin.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionMargin.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionMargin.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,10 +13,6 @@
 3. This notice may not be removed or altered from any source distribution.
 */
-
 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
-
-
-btScalar gContactThresholdFactor=btScalar(0.02);
-
+#include "LinearMath/btSerializer.h"
 
 /*
@@ -46,8 +42,10 @@
 }
 
-btScalar	btCollisionShape::getContactBreakingThreshold() const
+
+btScalar	btCollisionShape::getContactBreakingThreshold(btScalar defaultContactThreshold) const
 {
-	return getAngularMotionDisc() * gContactThresholdFactor;
+	return getAngularMotionDisc() * defaultContactThreshold;
 }
+
 btScalar	btCollisionShape::getAngularMotionDisc() const
 {
@@ -97,2 +95,25 @@
 	temporalAabbMax += angularMotion3d;
 }
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*	btCollisionShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btCollisionShapeData* shapeData = (btCollisionShapeData*) dataBuffer;
+	char* name = (char*) serializer->findNameForPointer(this);
+	shapeData->m_name = (char*)serializer->getUniquePointer(name);
+	if (shapeData->m_name)
+	{
+		serializer->serializeName(name);
+	}
+	shapeData->m_shapeType = m_shapeType;
+	//shapeData->m_padding//??
+	return "btCollisionShapeData";
+}
+
+void	btCollisionShape::serializeSingleShape(btSerializer* serializer) const
+{
+	int len = calculateSerializeBufferSize();
+	btChunk* chunk = serializer->allocate(len,1);
+	const char* structType = serialize(chunk->m_oldPtr, serializer);
+	serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,(void*)this);
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -21,4 +21,6 @@
 #include "LinearMath/btMatrix3x3.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
+class btSerializer;
+
 
 ///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects.
@@ -47,5 +49,5 @@
 	virtual btScalar	getAngularMotionDisc() const;
 
-	virtual btScalar	getContactBreakingThreshold() const;
+	virtual btScalar	getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const;
 
 
@@ -54,5 +56,5 @@
 	void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const;
 
-#ifndef __SPU__
+
 
 	SIMD_FORCE_INLINE bool	isPolyhedral() const
@@ -61,7 +63,16 @@
 	}
 
+	SIMD_FORCE_INLINE bool	isConvex2d() const
+	{
+		return btBroadphaseProxy::isConvex2d(getShapeType());
+	}
+
 	SIMD_FORCE_INLINE bool	isConvex() const
 	{
 		return btBroadphaseProxy::isConvex(getShapeType());
+	}
+	SIMD_FORCE_INLINE bool	isNonMoving() const
+	{
+		return btBroadphaseProxy::isNonMoving(getShapeType());
 	}
 	SIMD_FORCE_INLINE bool	isConcave() const
@@ -74,4 +85,9 @@
 	}
 
+	SIMD_FORCE_INLINE bool	isSoftBody() const
+	{
+		return btBroadphaseProxy::isSoftBody(getShapeType());
+	}
+
 	///isInfinite is used to catch simulation error (aabb check)
 	SIMD_FORCE_INLINE bool isInfinite() const
@@ -80,5 +96,5 @@
 	}
 
-	
+#ifndef __SPU__
 	virtual void	setLocalScaling(const btVector3& scaling) =0;
 	virtual const btVector3& getLocalScaling() const =0;
@@ -107,5 +123,27 @@
 	}
 
+	virtual	int	calculateSerializeBufferSize() const;
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;
+
+	virtual void	serializeSingleShape(btSerializer* serializer) const;
+
 };	
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btCollisionShapeData
+{
+	char	*m_name;
+	int		m_shapeType;
+	char	m_padding[4];
+};
+
+SIMD_FORCE_INLINE	int	btCollisionShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btCollisionShapeData);
+}
+
+
 
 #endif //COLLISION_SHAPE_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -17,12 +17,13 @@
 #include "btCollisionShape.h"
 #include "BulletCollision/BroadphaseCollision/btDbvt.h"
+#include "LinearMath/btSerializer.h"
 
 btCompoundShape::btCompoundShape(bool enableDynamicAabbTree)
-: m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
-m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
+: m_localAabbMin(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)),
+m_localAabbMax(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)),
+m_dynamicAabbTree(0),
+m_updateRevision(1),
 m_collisionMargin(btScalar(0.)),
-m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
-m_dynamicAabbTree(0),
-m_updateRevision(1)
+m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
 {
 	m_shapeType = COMPOUND_SHAPE_PROXYTYPE;
@@ -52,4 +53,5 @@
 	//m_childShapes.push_back(shape);
 	btCompoundShapeChild child;
+	child.m_node = 0;
 	child.m_transform = localTransform;
 	child.m_childShape = shape;
@@ -94,5 +96,5 @@
 		m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax);
 		ATTRIBUTE_ALIGNED16(btDbvtVolume)	bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
-		int index = m_children.size()-1;
+		//int index = m_children.size()-1;
 		m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds);
 	}
@@ -110,4 +112,6 @@
 	}
 	m_children.swap(childShapeIndex,m_children.size()-1);
+    if (m_dynamicAabbTree) 
+		m_children[childShapeIndex].m_node->dataAsInt = childShapeIndex;
 	m_children.pop_back();
 
@@ -125,12 +129,5 @@
 		if(m_children[i].m_childShape == shape)
 		{
-			m_children.swap(i,m_children.size()-1);
-			m_children.pop_back();
-			//remove it from the m_dynamicAabbTree too
-			//@todo: this leads to problems due to caching in the btCompoundCollisionAlgorithm
-			//so effectively, removeChildShape is broken at the moment
-			//m_dynamicAabbTree->remove(m_aabbProxies[i]);
-			//m_aabbProxies.swap(i,m_children.size()-1);
-			//m_aabbProxies.pop_back();
+			removeChildShapeByIndex(i);
 		}
 	}
@@ -146,6 +143,6 @@
 	// Brute force, it iterates over all the shapes left.
 
-	m_localAabbMin = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
-	m_localAabbMax = btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+	m_localAabbMin = btVector3(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+	m_localAabbMax = btVector3(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
 
 	//extend the local aabbMin/aabbMax
@@ -224,7 +221,11 @@
 	for (k = 0; k < n; k++)
 	{
+		btAssert(masses[k]>0);
 		center += m_children[k].m_transform.getOrigin() * masses[k];
 		totalMass += masses[k];
 	}
+
+	btAssert(totalMass>0);
+
 	center /= totalMass;
 	principal.setOrigin(center);
@@ -272,2 +273,79 @@
 
 
+void btCompoundShape::setLocalScaling(const btVector3& scaling)
+{
+
+	for(int i = 0; i < m_children.size(); i++)
+	{
+		btTransform childTrans = getChildTransform(i);
+		btVector3 childScale = m_children[i].m_childShape->getLocalScaling();
+//		childScale = childScale * (childTrans.getBasis() * scaling);
+		childScale = childScale * scaling / m_localScaling;
+		m_children[i].m_childShape->setLocalScaling(childScale);
+		childTrans.setOrigin((childTrans.getOrigin())*scaling);
+		updateChildTransform(i, childTrans);
+		recalculateLocalAabb();
+	}
+	m_localScaling = scaling;
+}
+
+
+void btCompoundShape::createAabbTreeFromChildren()
+{
+    if ( !m_dynamicAabbTree )
+    {
+        void* mem = btAlignedAlloc(sizeof(btDbvt),16);
+        m_dynamicAabbTree = new(mem) btDbvt();
+        btAssert(mem==m_dynamicAabbTree);
+
+        for ( int index = 0; index < m_children.size(); index++ )
+        {
+            btCompoundShapeChild &child = m_children[index];
+
+            //extend the local aabbMin/aabbMax
+            btVector3 localAabbMin,localAabbMax;
+            child.m_childShape->getAabb(child.m_transform,localAabbMin,localAabbMax);
+
+            const btDbvtVolume  bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
+            child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
+        }
+    }
+}
+
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*	btCompoundShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+
+	btCompoundShapeData* shapeData = (btCompoundShapeData*) dataBuffer;
+	btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer);
+
+	shapeData->m_collisionMargin = float(m_collisionMargin);
+	shapeData->m_numChildShapes = m_children.size();
+	shapeData->m_childShapePtr = 0;
+	if (shapeData->m_numChildShapes)
+	{
+		btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData),shapeData->m_numChildShapes);
+		btCompoundShapeChildData* memPtr = (btCompoundShapeChildData*)chunk->m_oldPtr;
+		shapeData->m_childShapePtr = (btCompoundShapeChildData*)serializer->getUniquePointer(memPtr);
+
+		for (int i=0;i<shapeData->m_numChildShapes;i++,memPtr++)
+		{
+			memPtr->m_childMargin = float(m_children[i].m_childMargin);
+			memPtr->m_childShape = (btCollisionShapeData*)serializer->getUniquePointer(m_children[i].m_childShape);
+			//don't serialize shapes that already have been serialized
+			if (!serializer->findPointer(m_children[i].m_childShape))
+			{
+				btChunk* chunk = serializer->allocate(m_children[i].m_childShape->calculateSerializeBufferSize(),1);
+				const char* structType = m_children[i].m_childShape->serialize(chunk->m_oldPtr,serializer);
+				serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,m_children[i].m_childShape);
+			} 
+
+			memPtr->m_childShapeType = m_children[i].m_childShapeType;
+			m_children[i].m_transform.serializeFloat(memPtr->m_transform);
+		}
+		serializer->finalizeChunk(chunk,"btCompoundShapeChildData",BT_ARRAY_CODE,chunk->m_oldPtr);
+	}
+	return "btCompoundShapeData";
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -63,4 +63,9 @@
 	int								m_updateRevision;
 
+	btScalar	m_collisionMargin;
+
+protected:
+	btVector3	m_localScaling;
+
 public:
 	BT_DECLARE_ALIGNED_ALLOCATOR();
@@ -117,8 +122,6 @@
 	virtual void recalculateLocalAabb(); 
 
-	virtual void	setLocalScaling(const btVector3& scaling)
-	{
-		m_localScaling = scaling;
-	}
+	virtual void	setLocalScaling(const btVector3& scaling);
+
 	virtual const btVector3& getLocalScaling() const 
 	{
@@ -141,6 +144,4 @@
 	}
 
-	//this is optional, but should make collision queries faster, by culling non-overlapping nodes
-	void	createAabbTreeFromChildren();
 
 	btDbvt*							getDynamicAabbTree()
@@ -148,4 +149,6 @@
 		return m_dynamicAabbTree;
 	}
+
+	void createAabbTreeFromChildren();
 
 	///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia
@@ -161,10 +164,43 @@
 	}
 
-private:
-	btScalar	m_collisionMargin;
-protected:
-	btVector3	m_localScaling;
-
-};
+	virtual	int	calculateSerializeBufferSize() const;
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;
+
+
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct btCompoundShapeChildData
+{
+	btTransformFloatData	m_transform;
+	btCollisionShapeData	*m_childShape;
+	int						m_childShapeType;
+	float					m_childMargin;
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btCompoundShapeData
+{
+	btCollisionShapeData		m_collisionShapeData;
+
+	btCompoundShapeChildData	*m_childShapePtr;
+
+	int							m_numChildShapes;
+
+	float	m_collisionMargin;
+
+};
+
+
+SIMD_FORCE_INLINE	int	btCompoundShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btCompoundShapeData);
+}
+
+
+
+
 
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.cpp	(revision 8284)
@@ -1,6 +1,5 @@
-
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvex2dShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvex2dShape.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvex2dShape.cpp	(revision 8284)
@@ -0,0 +1,92 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2009 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 "btConvex2dShape.h"
+
+btConvex2dShape::btConvex2dShape(	btConvexShape* convexChildShape):
+btConvexShape (), m_childConvexShape(convexChildShape)
+{
+	m_shapeType = CONVEX_2D_SHAPE_PROXYTYPE;
+}
+	
+btConvex2dShape::~btConvex2dShape()
+{
+}
+
+	
+
+btVector3	btConvex2dShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+{
+	return m_childConvexShape->localGetSupportingVertexWithoutMargin(vec);
+}
+
+void	btConvex2dShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors);
+}
+
+
+btVector3	btConvex2dShape::localGetSupportingVertex(const btVector3& vec)const
+{
+	return m_childConvexShape->localGetSupportingVertex(vec);
+}
+
+
+void	btConvex2dShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	///this linear upscaling is not realistic, but we don't deal with large mass ratios...
+	m_childConvexShape->calculateLocalInertia(mass,inertia);
+}
+
+
+	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+void btConvex2dShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	m_childConvexShape->getAabb(t,aabbMin,aabbMax);
+}
+
+void btConvex2dShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	m_childConvexShape->getAabbSlow(t,aabbMin,aabbMax);
+}
+
+void	btConvex2dShape::setLocalScaling(const btVector3& scaling) 
+{
+	m_childConvexShape->setLocalScaling(scaling);
+}
+
+const btVector3& btConvex2dShape::getLocalScaling() const
+{
+	return m_childConvexShape->getLocalScaling();
+}
+
+void	btConvex2dShape::setMargin(btScalar margin)
+{
+	m_childConvexShape->setMargin(margin);
+}
+btScalar	btConvex2dShape::getMargin() const
+{
+	return m_childConvexShape->getMargin();
+}
+
+int		btConvex2dShape::getNumPreferredPenetrationDirections() const
+{
+	return m_childConvexShape->getNumPreferredPenetrationDirections();
+}
+	
+void	btConvex2dShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
+{
+	m_childConvexShape->getPreferredPenetrationDirection(index,penetrationVector);
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvex2dShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvex2dShape.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvex2dShape.h	(revision 8284)
@@ -0,0 +1,80 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2009 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_CONVEX_2D_SHAPE_H
+#define BT_CONVEX_2D_SHAPE_H
+
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+
+///The btConvex2dShape allows to use arbitrary convex shapes are 2d convex shapes, with the Z component assumed to be 0.
+///For 2d boxes, the btBox2dShape is recommended.
+class btConvex2dShape : public btConvexShape
+{
+	btConvexShape*	m_childConvexShape;
+
+	public:
+	
+	btConvex2dShape(	btConvexShape* convexChildShape);
+	
+	virtual ~btConvex2dShape();
+	
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
+
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	btConvexShape*	getChildShape() 
+	{
+		return m_childConvexShape;
+	}
+
+	const btConvexShape*	getChildShape() const
+	{
+		return m_childConvexShape;
+	}
+
+	virtual const char*	getName()const 
+	{
+		return "Convex2dShape";
+	}
+	
+
+
+	///////////////////////////
+
+
+	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+	void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	virtual void	setLocalScaling(const btVector3& scaling) ;
+	virtual const btVector3& getLocalScaling() const ;
+
+	virtual void	setMargin(btScalar margin);
+	virtual btScalar	getMargin() const;
+
+	virtual int		getNumPreferredPenetrationDirections() const;
+	
+	virtual void	getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const;
+
+
+};
+
+#endif //BT_CONVEX_2D_SHAPE_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,22 +13,23 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 #include "btConvexHullShape.h"
 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
 
 #include "LinearMath/btQuaternion.h"
-
-
-
-btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexShape ()
+#include "LinearMath/btSerializer.h"
+
+btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexAabbCachingShape ()
 {
 	m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
 	m_unscaledPoints.resize(numPoints);
 
-	unsigned char* pointsBaseAddress = (unsigned char*)points;
+	unsigned char* pointsAddress = (unsigned char*)points;
 
 	for (int i=0;i<numPoints;i++)
 	{
-		btVector3* point = (btVector3*)(pointsBaseAddress + i*stride);
-		m_unscaledPoints[i] = point[0];
+		btScalar* point = (btScalar*)pointsAddress;
+		m_unscaledPoints[i] = btVector3(point[0], point[1], point[2]);
+		pointsAddress += stride;
 	}
 
@@ -52,20 +53,8 @@
 }
 
-btVector3	btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
+btVector3	btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
 {
 	btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
-	btScalar newDot,maxDot = btScalar(-1e30);
-
-	btVector3 vec = vec0;
-	btScalar lenSqr = vec.length2();
-	if (lenSqr < btScalar(0.0001))
-	{
-		vec.setValue(1,0,0);
-	} else
-	{
-		btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
-		vec *= rlen;
-	}
-
+	btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
 
 	for (int i=0;i<m_unscaledPoints.size();i++)
@@ -90,5 +79,5 @@
 		for (int i=0;i<numVectors;i++)
 		{
-			supportVerticesOut[i][3] = btScalar(-1e30);
+			supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
 		}
 	}
@@ -186,2 +175,37 @@
 }
 
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*	btConvexHullShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	//int szc = sizeof(btConvexHullShapeData);
+	btConvexHullShapeData* shapeData = (btConvexHullShapeData*) dataBuffer;
+	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer);
+
+	int numElem = m_unscaledPoints.size();
+	shapeData->m_numUnscaledPoints = numElem;
+#ifdef BT_USE_DOUBLE_PRECISION
+	shapeData->m_unscaledPointsFloatPtr = 0;
+	shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]):  0;
+#else
+	shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]):  0;
+	shapeData->m_unscaledPointsDoublePtr = 0;
+#endif
+	
+	if (numElem)
+	{
+		int sz = sizeof(btVector3Data);
+	//	int sz2 = sizeof(btVector3DoubleData);
+	//	int sz3 = sizeof(btVector3FloatData);
+		btChunk* chunk = serializer->allocate(sz,numElem);
+		btVector3Data* memPtr = (btVector3Data*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			m_unscaledPoints[i].serialize(*memPtr);
+		}
+		serializer->finalizeChunk(chunk,btVector3DataName,BT_ARRAY_CODE,(void*)&m_unscaledPoints[0]);
+	}
+	
+	return "btConvexHullShapeData";
+}
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -21,7 +21,8 @@
 #include "LinearMath/btAlignedObjectArray.h"
 
+
 ///The btConvexHullShape implements an implicit convex hull of an array of vertices.
 ///Bullet provides a general and fast collision detector for convex shapes based on GJK and EPA using localGetSupportingVertex.
-ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape
+ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexAabbCachingShape
 {
 	btAlignedObjectArray<btVector3>	m_unscaledPoints;
@@ -89,5 +90,29 @@
 	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;
+
 };
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btConvexHullShapeData
+{
+	btConvexInternalShapeData	m_convexInternalShapeData;
+
+	btVector3FloatData	*m_unscaledPointsFloatPtr;
+	btVector3DoubleData	*m_unscaledPointsDoublePtr;
+
+	int		m_numUnscaledPoints;
+	char m_padding3[4];
+
+};
+
+
+SIMD_FORCE_INLINE	int	btConvexHullShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btConvexHullShapeData);
+}
 
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -35,5 +35,6 @@
 void	btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const
 {
-
+#ifndef __SPU__
+	//use localGetSupportingVertexWithoutMargin?
 	btScalar margin = getMargin();
 	for (int i=0;i<3;i++)
@@ -50,4 +51,5 @@
 		minAabb[i] = tmp[i]-margin;
 	}
+#endif
 }
 
@@ -80,2 +82,70 @@
 
 
+btConvexInternalAabbCachingShape::btConvexInternalAabbCachingShape()
+	:	btConvexInternalShape(),
+m_localAabbMin(1,1,1),
+m_localAabbMax(-1,-1,-1),
+m_isLocalAabbValid(false)
+{
+}
+
+
+void btConvexInternalAabbCachingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin());
+}
+
+void	btConvexInternalAabbCachingShape::setLocalScaling(const btVector3& scaling)
+{
+	btConvexInternalShape::setLocalScaling(scaling);
+	recalcLocalAabb();
+}
+
+
+void	btConvexInternalAabbCachingShape::recalcLocalAabb()
+{
+	m_isLocalAabbValid = true;
+	
+	#if 1
+	static const btVector3 _directions[] =
+	{
+		btVector3( 1.,  0.,  0.),
+		btVector3( 0.,  1.,  0.),
+		btVector3( 0.,  0.,  1.),
+		btVector3( -1., 0.,  0.),
+		btVector3( 0., -1.,  0.),
+		btVector3( 0.,  0., -1.)
+	};
+	
+	btVector3 _supporting[] =
+	{
+		btVector3( 0., 0., 0.),
+		btVector3( 0., 0., 0.),
+		btVector3( 0., 0., 0.),
+		btVector3( 0., 0., 0.),
+		btVector3( 0., 0., 0.),
+		btVector3( 0., 0., 0.)
+	};
+	
+	batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6);
+	
+	for ( int i = 0; i < 3; ++i )
+	{
+		m_localAabbMax[i] = _supporting[i][i] + m_collisionMargin;
+		m_localAabbMin[i] = _supporting[i + 3][i] - m_collisionMargin;
+	}
+	
+	#else
+
+	for (int i=0;i<3;i++)
+	{
+		btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
+		vec[i] = btScalar(1.);
+		btVector3 tmp = localGetSupportingVertex(vec);
+		m_localAabbMax[i] = tmp[i]+m_collisionMargin;
+		vec[i] = btScalar(-1.);
+		tmp = localGetSupportingVertex(vec);
+		m_localAabbMin[i] = tmp[i]-m_collisionMargin;
+	}
+	#endif
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h	(revision 8284)
@@ -1,2 +1,16 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2009 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_CONVEX_INTERNAL_SHAPE_H
@@ -4,4 +18,6 @@
 
 #include "btConvexShape.h"
+#include "LinearMath/btAabbUtil2.h"
+
 
 ///The btConvexInternalShape is an internal base class, shared by most convex shape implementations.
@@ -36,4 +52,13 @@
 	{
 		return m_implicitShapeDimensions;
+	}
+
+	///warning: use setImplicitShapeDimensions with care
+	///changing a collision shape while the body is in the world is not recommended,
+	///it is best to remove the body from the world, then make the change, and re-add it
+	///alternatively flush the contact points, see documentation for 'cleanProxyFromPairs'
+	void	setImplicitShapeDimensions(const btVector3& dimensions)
+	{
+		m_implicitShapeDimensions = dimensions;
 	}
 
@@ -86,8 +111,92 @@
 	}
 
+	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	btConvexInternalShapeData
+{
+	btCollisionShapeData	m_collisionShapeData;
+
+	btVector3FloatData	m_localScaling;
+
+	btVector3FloatData	m_implicitShapeDimensions;
+	
+	float			m_collisionMargin;
+
+	int	m_padding;
+
+};
+
+
+
+SIMD_FORCE_INLINE	int	btConvexInternalShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btConvexInternalShapeData);
+}
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+SIMD_FORCE_INLINE	const char*	btConvexInternalShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btConvexInternalShapeData* shapeData = (btConvexInternalShapeData*) dataBuffer;
+	btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer);
+
+	m_implicitShapeDimensions.serializeFloat(shapeData->m_implicitShapeDimensions);
+	m_localScaling.serializeFloat(shapeData->m_localScaling);
+	shapeData->m_collisionMargin = float(m_collisionMargin);
+
+	return "btConvexInternalShapeData";
+}
+
+
+
+
+///btConvexInternalAabbCachingShape adds local aabb caching for convex shapes, to avoid expensive bounding box calculations
+class btConvexInternalAabbCachingShape : public btConvexInternalShape
+{
+	btVector3	m_localAabbMin;
+	btVector3	m_localAabbMax;
+	bool		m_isLocalAabbValid;
+	
+protected:
+					
+	btConvexInternalAabbCachingShape();
+	
+	void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax)
+	{
+		m_isLocalAabbValid = true;
+		m_localAabbMin = aabbMin;
+		m_localAabbMax = aabbMax;
+	}
+
+	inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const
+	{
+		btAssert(m_isLocalAabbValid);
+		aabbMin = m_localAabbMin;
+		aabbMax = m_localAabbMax;
+	}
+
+	inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const
+	{
+
+		//lazy evaluation of local aabb
+		btAssert(m_isLocalAabbValid);
+		btTransformAabb(m_localAabbMin,m_localAabbMax,margin,trans,aabbMin,aabbMax);
+	}
+		
+public:
+		
+	virtual void	setLocalScaling(const btVector3& scaling);
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	void	recalcLocalAabb();
+
+};
 
 #endif //BT_CONVEX_INTERNAL_SHAPE_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 #include "btConvexPointCloudShape.h"
 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
@@ -28,5 +29,5 @@
 {
 	btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
-	btScalar newDot,maxDot = btScalar(-1e30);
+	btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
 
 	btVector3 vec = vec0;
@@ -63,5 +64,5 @@
 		for (int i=0;i<numVectors;i++)
 		{
-			supportVerticesOut[i][3] = btScalar(-1e30);
+			supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
 		}
 	}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -22,5 +22,5 @@
 
 ///The btConvexPointCloudShape implements an implicit convex hull of an array of vertices.
-ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexShape
+ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexAabbCachingShape
 {
 	btVector3* m_unscaledPoints;
@@ -29,4 +29,12 @@
 public:
 	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btConvexPointCloudShape()
+	{
+		m_localScaling.setValue(1.f,1.f,1.f);
+		m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE;
+		m_unscaledPoints = 0;
+		m_numPoints = 0;
+	}
 
 	btConvexPointCloudShape(btVector3* points,int numPoints, const btVector3& localScaling,bool computeAabb = true)
@@ -41,8 +49,9 @@
 	}
 
-	void setPoints (btVector3* points, int numPoints, bool computeAabb = true)
+	void setPoints (btVector3* points, int numPoints, bool computeAabb = true,const btVector3& localScaling=btVector3(1.f,1.f,1.f))
 	{
 		m_unscaledPoints = points;
 		m_numPoints = numPoints;
+		m_localScaling = localScaling;
 
 		if (computeAabb)
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -22,4 +22,16 @@
 #include "btConvexPointCloudShape.h"
 
+///not supported on IBM SDK, until we fix the alignment of btVector3
+#if defined (__CELLOS_LV2__) && defined (__SPU__)
+#include <spu_intrinsics.h>
+static inline vec_float4 vec_dot3( vec_float4 vec0, vec_float4 vec1 )
+{
+    vec_float4 result;
+    result = spu_mul( vec0, vec1 );
+    result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result );
+    return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result );
+}
+#endif //__SPU__
+
 btConvexShape::btConvexShape ()
 {
@@ -33,33 +45,69 @@
 
 
-static btVector3 convexHullSupport (const btVector3& localDir, const btVector3* points, int numPoints, const btVector3& localScaling)
-{
-	btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
-	btScalar newDot,maxDot = btScalar(-1e30);
-
-	btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
-	btVector3 vec = vec0;
-	btScalar lenSqr = vec.length2();
-	if (lenSqr < btScalar(0.0001))
-	{
-		vec.setValue(1,0,0);
-	} else {
-		btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
-		vec *= rlen;
-	}
-
+static btVector3 convexHullSupport (const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling)
+{	
+
+	btVector3 vec = localDirOrg * localScaling;
+
+#if defined (__CELLOS_LV2__) && defined (__SPU__)
+
+	btVector3 localDir = vec;
+
+	vec_float4 v_distMax = {-FLT_MAX,0,0,0};
+	vec_int4 v_idxMax = {-999,0,0,0};
+	int v=0;
+	int numverts = numPoints;
+
+	for(;v<(int)numverts-4;v+=4) {
+		vec_float4 p0 = vec_dot3(points[v  ].get128(),localDir.get128());
+		vec_float4 p1 = vec_dot3(points[v+1].get128(),localDir.get128());
+		vec_float4 p2 = vec_dot3(points[v+2].get128(),localDir.get128());
+		vec_float4 p3 = vec_dot3(points[v+3].get128(),localDir.get128());
+		const vec_int4 i0 = {v  ,0,0,0};
+		const vec_int4 i1 = {v+1,0,0,0};
+		const vec_int4 i2 = {v+2,0,0,0};
+		const vec_int4 i3 = {v+3,0,0,0};
+		vec_uint4  retGt01 = spu_cmpgt(p0,p1);
+		vec_float4 pmax01 = spu_sel(p1,p0,retGt01);
+		vec_int4   imax01 = spu_sel(i1,i0,retGt01);
+		vec_uint4  retGt23 = spu_cmpgt(p2,p3);
+		vec_float4 pmax23 = spu_sel(p3,p2,retGt23);
+		vec_int4   imax23 = spu_sel(i3,i2,retGt23);
+		vec_uint4  retGt0123 = spu_cmpgt(pmax01,pmax23);
+		vec_float4 pmax0123 = spu_sel(pmax23,pmax01,retGt0123);
+		vec_int4   imax0123 = spu_sel(imax23,imax01,retGt0123);
+		vec_uint4  retGtMax = spu_cmpgt(v_distMax,pmax0123);
+		v_distMax = spu_sel(pmax0123,v_distMax,retGtMax);
+		v_idxMax = spu_sel(imax0123,v_idxMax,retGtMax);
+	}
+	for(;v<(int)numverts;v++) {
+		vec_float4 p = vec_dot3(points[v].get128(),localDir.get128());
+		const vec_int4 i = {v,0,0,0};
+		vec_uint4  retGtMax = spu_cmpgt(v_distMax,p);
+		v_distMax = spu_sel(p,v_distMax,retGtMax);
+		v_idxMax = spu_sel(i,v_idxMax,retGtMax);
+	}
+	int ptIndex = spu_extract(v_idxMax,0);
+	const btVector3& supVec= points[ptIndex] * localScaling;
+	return supVec;
+#else
+
+	btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
+	int ptIndex = -1;
 
 	for (int i=0;i<numPoints;i++)
 	{
-		btVector3 vtx = points[i] * localScaling;
-
-		newDot = vec.dot(vtx);
+
+		newDot = vec.dot(points[i]);
 		if (newDot > maxDot)
 		{
 			maxDot = newDot;
-			supVec = vtx;
-		}
-	}
-	return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
+			ptIndex = i;
+		}
+	}
+	btAssert(ptIndex >= 0);
+	btVector3 supVec = points[ptIndex] * localScaling;
+	return supVec;
+#endif //__SPU__
 }
 
@@ -161,5 +209,5 @@
 		btVector3 supVec(0,0,0);
 
-		btScalar maxDot(btScalar(-1e30));
+		btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
 
 		btVector3 vec = vec0;
@@ -293,5 +341,5 @@
 	return btScalar(0.0f);
 }
-
+#ifndef __SPU__
 void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
 {
@@ -361,5 +409,5 @@
 	case CONVEX_HULL_SHAPE_PROXYTYPE:
 	{
-		btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
+		btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this;
 		btScalar margin = convexHullShape->getMarginNonVirtual();
 		convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin);
@@ -378,2 +426,4 @@
 	btAssert (0);
 }
+
+#endif //__SPU__
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 #include "btConvexTriangleMeshShape.h"
 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
@@ -21,5 +22,5 @@
 
 btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb)
-: btPolyhedralConvexShape(), m_stridingMesh(meshInterface)
+: btPolyhedralConvexAabbCachingShape(), m_stridingMesh(meshInterface)
 {
 	m_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE;
@@ -44,5 +45,5 @@
 	LocalSupportVertexCallback(const btVector3& supportVecLocal)
 		: m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)),
-		m_maxDot(btScalar(-1e30)),
+		m_maxDot(btScalar(-BT_LARGE_FLOAT)),
                 m_supportVecLocal(supportVecLocal)
 	{
@@ -92,5 +93,5 @@
 
 	LocalSupportVertexCallback	supportCallback(vec);
-	btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 	m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
 	supVec = supportCallback.GetSupportVertexLocal();
@@ -105,5 +106,5 @@
 		for (int i=0;i<numVectors;i++)
 		{
-			supportVerticesOut[i][3] = btScalar(-1e30);
+			supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
 		}
 	}
@@ -116,5 +117,5 @@
 		const btVector3& vec = vectors[j];
 		LocalSupportVertexCallback	supportCallback(vec);
-		btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+		btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 		m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
 		supportVerticesOut[j] = supportCallback.GetSupportVertexLocal();
@@ -298,5 +299,5 @@
 
    CenterCallback centerCallback;
-   btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+   btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
    m_stridingMesh->InternalProcessAllTriangles(&centerCallback, -aabbMax, aabbMax);
    btVector3 center = centerCallback.getCenter();
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h	(revision 8284)
@@ -1,2 +1,16 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2009 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 CONVEX_TRIANGLEMESH_SHAPE_H
 #define CONVEX_TRIANGLEMESH_SHAPE_H
@@ -9,5 +23,5 @@
 /// The btConvexTriangleMeshShape is a convex hull of a triangle mesh, but the performance is not as good as btConvexHullShape.
 /// A small benefit of this class is that it uses the btStridingMeshInterface, so you can avoid the duplication of the triangle mesh data. Nevertheless, most users should use the much better performing btConvexHullShape instead.
-class btConvexTriangleMeshShape : public btPolyhedralConvexShape
+class btConvexTriangleMeshShape : public btPolyhedralConvexAabbCachingShape
 {
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,12 +13,14 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 #include "btCylinderShape.h"
 
 btCylinderShape::btCylinderShape (const btVector3& halfExtents)
-:btBoxShape(halfExtents),
+:btConvexInternalShape(),
 m_upAxis(1)
 {
+	btVector3 margin(getMargin(),getMargin(),getMargin());
+	m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin;
 	m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
-	recalcLocalAabb();
 }
 
@@ -28,5 +30,5 @@
 {
 	m_upAxis = 0;
-	recalcLocalAabb();
+
 }
 
@@ -36,11 +38,25 @@
 {
 	m_upAxis = 2;
-	recalcLocalAabb();
+
 }
 
 void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
 {
-	//skip the box 'getAabb'
-	btPolyhedralConvexShape::getAabb(t,aabbMin,aabbMax);
+	btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax);
+}
+
+void	btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	//approximation of box shape, todo: implement cylinder shape inertia before people notice ;-)
+	btVector3 halfExtents = getHalfExtentsWithMargin();
+
+	btScalar lx=btScalar(2.)*(halfExtents.x());
+	btScalar ly=btScalar(2.)*(halfExtents.y());
+	btScalar lz=btScalar(2.)*(halfExtents.z());
+
+	inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
+					mass/(btScalar(12.0)) * (lx*lx + lz*lz),
+					mass/(btScalar(12.0)) * (lx*lx + ly*ly));
+
 }
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -22,5 +22,5 @@
 
 /// The btCylinderShape class implements a cylinder shape primitive, centered around the origin. Its central axis aligned with the Y axis. btCylinderShapeX is aligned with the X axis and btCylinderShapeZ around the Z axis.
-class btCylinderShape : public btBoxShape
+class btCylinderShape : public btConvexInternalShape
 
 {
@@ -31,12 +31,39 @@
 
 public:
+
+	btVector3 getHalfExtentsWithMargin() const
+	{
+		btVector3 halfExtents = getHalfExtentsWithoutMargin();
+		btVector3 margin(getMargin(),getMargin(),getMargin());
+		halfExtents += margin;
+		return halfExtents;
+	}
+	
+	const btVector3& getHalfExtentsWithoutMargin() const
+	{
+		return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
+	}
+
 	btCylinderShape (const btVector3& halfExtents);
 	
-	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
 	void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
 
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
 	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
 
 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
+	virtual void setMargin(btScalar collisionMargin)
+	{
+		//correct the m_implicitShapeDimensions for the margin
+		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
+		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
+		
+		btConvexInternalShape::setMargin(collisionMargin);
+		btVector3 newMargin(getMargin(),getMargin(),getMargin());
+		m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;
+
+	}
 
 	virtual btVector3	localGetSupportingVertex(const btVector3& vec) const
@@ -74,4 +101,16 @@
 	}
 
+	virtual void	setLocalScaling(const btVector3& scaling)
+	{
+		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
+		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
+		btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;
+
+		btConvexInternalShape::setLocalScaling(scaling);
+
+		m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;
+
+	}
+
 	//debugging
 	virtual const char*	getName()const
@@ -80,5 +119,8 @@
 	}
 
-
+	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;
 
 };
@@ -113,8 +155,4 @@
 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
 
-	virtual int	getUpAxis() const
-	{
-		return 2;
-	}
 		//debugging
 	virtual const char*	getName()const
@@ -130,4 +168,32 @@
 };
 
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btCylinderShapeData
+{
+	btConvexInternalShapeData	m_convexInternalShapeData;
+
+	int	m_upAxis;
+
+	char	m_padding[4];
+};
+
+SIMD_FORCE_INLINE	int	btCylinderShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btCylinderShapeData);
+}
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+SIMD_FORCE_INLINE	const char*	btCylinderShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btCylinderShapeData* shapeData = (btCylinderShapeData*) dataBuffer;
+	
+	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer);
+
+	shapeData->m_upAxis = m_upAxis;
+	
+	return "btCylinderShapeData";
+}
+
+
 
 #endif //CYLINDER_MINKOWSKI_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMaterial.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMaterial.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMaterial.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2008 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -33,2 +33,3 @@
 
 #endif // MATERIAL_H
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 
 #include "btMinkowskiSumShape.h"
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -14,27 +14,29 @@
 */
 
+
+
 #include "btMultiSphereShape.h"
 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
 #include "LinearMath/btQuaternion.h"
+#include "LinearMath/btSerializer.h"
 
-btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres)
-:btConvexInternalShape (), m_inertiaHalfExtents(inertiaHalfExtents)
+btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres)
+:btConvexInternalAabbCachingShape ()
 {
 	m_shapeType = MULTI_SPHERE_SHAPE_PROXYTYPE;
-	btScalar startMargin = btScalar(1e30);
+	//btScalar startMargin = btScalar(BT_LARGE_FLOAT);
 
-	m_numSpheres = numSpheres;
-	for (int i=0;i<m_numSpheres;i++)
+	m_localPositionArray.resize(numSpheres);
+	m_radiArray.resize(numSpheres);
+	for (int i=0;i<numSpheres;i++)
 	{
-		m_localPositions[i] = positions[i];
-		m_radi[i] = radi[i];
-		if (radi[i] < startMargin)
-			startMargin = radi[i];
+		m_localPositionArray[i] = positions[i];
+		m_radiArray[i] = radi[i];
+		
 	}
-	setMargin(startMargin);
+
+	recalcLocalAabb();
 
 }
-
-
 
  
@@ -44,5 +46,5 @@
 	btVector3 supVec(0,0,0);
 
-	btScalar maxDot(btScalar(-1e30));
+	btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
 
 
@@ -61,8 +63,9 @@
 	btScalar newDot;
 
-	const btVector3* pos = &m_localPositions[0];
-	const btScalar* rad = &m_radi[0];
+	const btVector3* pos = &m_localPositionArray[0];
+	const btScalar* rad = &m_radiArray[0];
+	int numSpheres = m_localPositionArray.size();
 
-	for (i=0;i<m_numSpheres;i++)
+	for (i=0;i<numSpheres;i++)
 	{
 		vtx = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
@@ -86,5 +89,5 @@
 	for (int j=0;j<numVectors;j++)
 	{
-		btScalar maxDot(btScalar(-1e30));
+		btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
 
 		const btVector3& vec = vectors[j];
@@ -93,8 +96,8 @@
 		btScalar newDot;
 
-		const btVector3* pos = &m_localPositions[0];
-		const btScalar* rad = &m_radi[0];
-
-		for (int i=0;i<m_numSpheres;i++)
+		const btVector3* pos = &m_localPositionArray[0];
+		const btScalar* rad = &m_radiArray[0];
+		int numSpheres = m_localPositionArray.size();
+		for (int i=0;i<numSpheres;i++)
 		{
 			vtx = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
@@ -122,28 +125,43 @@
 	//as an approximation, take the inertia of the box that bounds the spheres
 
-	btTransform ident;
-	ident.setIdentity();
-//	btVector3 aabbMin,aabbMax;
+	btVector3 localAabbMin,localAabbMax;
+	getCachedLocalAabb(localAabbMin,localAabbMax);
+	btVector3 halfExtents = (localAabbMax-localAabbMin)*btScalar(0.5);
 
-//	getAabb(ident,aabbMin,aabbMax);
+	btScalar lx=btScalar(2.)*(halfExtents.x());
+	btScalar ly=btScalar(2.)*(halfExtents.y());
+	btScalar lz=btScalar(2.)*(halfExtents.z());
 
-	btVector3 halfExtents = m_inertiaHalfExtents;//(aabbMax - aabbMin)* btScalar(0.5);
-
-	btScalar margin = CONVEX_DISTANCE_MARGIN;
-
-	btScalar lx=btScalar(2.)*(halfExtents[0]+margin);
-	btScalar ly=btScalar(2.)*(halfExtents[1]+margin);
-	btScalar lz=btScalar(2.)*(halfExtents[2]+margin);
-	const btScalar x2 = lx*lx;
-	const btScalar y2 = ly*ly;
-	const btScalar z2 = lz*lz;
-	const btScalar scaledmass = mass * btScalar(.08333333);
-
-	inertia[0] = scaledmass * (y2+z2);
-	inertia[1] = scaledmass * (x2+z2);
-	inertia[2] = scaledmass * (x2+y2);
+	inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz),
+					mass/(btScalar(12.0)) * (lx*lx + lz*lz),
+					mass/(btScalar(12.0)) * (lx*lx + ly*ly));
 
 }
 
 
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*	btMultiSphereShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btMultiSphereShapeData* shapeData = (btMultiSphereShapeData*) dataBuffer;
+	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer);
 
+	int numElem = m_localPositionArray.size();
+	shapeData->m_localPositionArrayPtr = numElem ? (btPositionAndRadius*)serializer->getUniquePointer((void*)&m_localPositionArray[0]):  0;
+	
+	shapeData->m_localPositionArraySize = numElem;
+	if (numElem)
+	{
+		btChunk* chunk = serializer->allocate(sizeof(btPositionAndRadius),numElem);
+		btPositionAndRadius* memPtr = (btPositionAndRadius*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			m_localPositionArray[i].serializeFloat(memPtr->m_pos);
+			memPtr->m_radius = float(m_radiArray[i]);
+		}
+		serializer->finalizeChunk(chunk,"btPositionAndRadius",BT_ARRAY_CODE,(void*)&m_localPositionArray[0]);
+	}
+	
+	return "btMultiSphereShapeData";
+}
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -19,24 +19,19 @@
 #include "btConvexInternalShape.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
-
-#define MAX_NUM_SPHERES 5
-
-///The btMultiSphereShape represents the convex hull of a collection of spheres. You can create special capsules or other smooth volumes.
-///It is possible to animate the spheres for deformation.
-class btMultiSphereShape : public btConvexInternalShape
-
-{
-	
-	btVector3 m_localPositions[MAX_NUM_SPHERES];
-	btScalar  m_radi[MAX_NUM_SPHERES];
-	btVector3	m_inertiaHalfExtents;
-
-	int m_numSpheres;
-	
+#include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btAabbUtil2.h"
 
 
 
+///The btMultiSphereShape represents the convex hull of a collection of spheres. You can create special capsules or other smooth volumes.
+///It is possible to animate the spheres for deformation, but call 'recalcLocalAabb' after changing any sphere position/radius
+class btMultiSphereShape : public btConvexInternalAabbCachingShape
+{
+	
+	btAlignedObjectArray<btVector3> m_localPositionArray;
+	btAlignedObjectArray<btScalar>  m_radiArray;
+	
 public:
-	btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres);
+	btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres);
 
 	///CollisionShape Interface
@@ -50,15 +45,15 @@
 	int	getSphereCount() const
 	{
-		return m_numSpheres;
+		return m_localPositionArray.size();
 	}
 
 	const btVector3&	getSpherePosition(int index) const
 	{
-		return m_localPositions[index];
+		return m_localPositionArray[index];
 	}
 
 	btScalar	getSphereRadius(int index) const
 	{
-		return m_radi[index];
+		return m_radiArray[index];
 	}
 
@@ -69,6 +64,36 @@
 	}
 
+	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;
+
+
 };
 
 
+struct	btPositionAndRadius
+{
+	btVector3FloatData	m_pos;
+	float		m_radius;
+};
+
+struct	btMultiSphereShapeData
+{
+	btConvexInternalShapeData	m_convexInternalShapeData;
+
+	btPositionAndRadius	*m_localPositionArrayPtr;
+	int				m_localPositionArraySize;
+	char	m_padding[4];
+};
+
+
+
+SIMD_FORCE_INLINE	int	btMultiSphereShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btMultiSphereShapeData);
+}
+
+
+
 #endif //MULTI_SPHERE_MINKOWSKI_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2008 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2008 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -38,5 +38,4 @@
             m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
 
-            btVector3 m_triangle[3];
             const unsigned char *vertexbase;
             int numverts;
@@ -72,5 +71,4 @@
             m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
 
-            btVector3 m_triangle[3];
             const unsigned char *vertexbase;
             int numverts;
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -14,4 +14,5 @@
 */
 
+
 #include "btOptimizedBvh.h"
 #include "btStridingMeshInterface.h"
@@ -56,6 +57,6 @@
 			btOptimizedBvhNode node;
 			btVector3	aabbMin,aabbMax;
-			aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
-			aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); 
+			aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+			aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); 
 			aabbMin.setMin(triangle[0]);
 			aabbMax.setMax(triangle[0]);
@@ -104,6 +105,6 @@
 			btQuantizedBvhNode node;
 			btVector3	aabbMin,aabbMax;
-			aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
-			aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); 
+			aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+			aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); 
 			aabbMin.setMin(triangle[0]);
 			aabbMax.setMax(triangle[0]);
@@ -168,6 +169,6 @@
 		NodeTriangleCallback	callback(m_leafNodes);
 
-		btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
-		btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+		btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
+		btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 
 		triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax);
@@ -337,6 +338,6 @@
 
 				
-				aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
-				aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); 
+				aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+				aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); 
 				aabbMin.setMin(triangleVerts[0]);
 				aabbMax.setMax(triangleVerts[0]);
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,6 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
+///Contains contributions from Disney Studio's
 
 #ifndef OPTIMIZED_BVH_H
@@ -46,5 +48,5 @@
 
 	/// Data buffer MUST be 16 byte aligned
-	virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian)
+	virtual bool serializeInPlace(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const
 	{
 		return btQuantizedBvh::serialize(o_alignedDataBuffer,i_dataBufferSize,i_swapEndian);
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -16,9 +16,5 @@
 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
 
-btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(),
-m_localAabbMin(1,1,1),
-m_localAabbMax(-1,-1,-1),
-m_isLocalAabbValid(false),
-m_optionalHull(0)
+btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape()
 {
 
@@ -28,8 +24,10 @@
 btVector3	btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
 {
+
+
+	btVector3 supVec(0,0,0);
+#ifndef __SPU__
 	int i;
-	btVector3 supVec(0,0,0);
-
-	btScalar maxDot(btScalar(-1e30));
+	btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
 
 	btVector3 vec = vec0;
@@ -58,10 +56,14 @@
 	}
 
+	
+#endif //__SPU__
 	return supVec;
+}
 
-}
+
 
 void	btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
 {
+#ifndef __SPU__
 	int i;
 
@@ -71,5 +73,5 @@
 	for (i=0;i<numVectors;i++)
 	{
-		supportVerticesOut[i][3] = btScalar(-1e30);
+		supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
 	}
 
@@ -91,4 +93,5 @@
 		}
 	}
+#endif //__SPU__
 }
 
@@ -97,4 +100,5 @@
 void	btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
 {
+#ifndef __SPU__
 	//not yet, return box inertia
 
@@ -116,17 +120,10 @@
 
 	inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
-
+#endif //__SPU__
 }
 
 
 
-void btPolyhedralConvexShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
-{
-	getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin());
-}
-
-
-
-void	btPolyhedralConvexShape::setLocalScaling(const btVector3& scaling)
+void	btPolyhedralConvexAabbCachingShape::setLocalScaling(const btVector3& scaling)
 {
 	btConvexInternalShape::setLocalScaling(scaling);
@@ -134,5 +131,18 @@
 }
 
-void	btPolyhedralConvexShape::recalcLocalAabb()
+btPolyhedralConvexAabbCachingShape::btPolyhedralConvexAabbCachingShape()
+:btPolyhedralConvexShape(),
+m_localAabbMin(1,1,1),
+m_localAabbMax(-1,-1,-1),
+m_isLocalAabbValid(false)
+{
+}
+
+void btPolyhedralConvexAabbCachingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin());
+}
+
+void	btPolyhedralConvexAabbCachingShape::recalcLocalAabb()
 {
 	m_isLocalAabbValid = true;
@@ -182,4 +192,2 @@
 }
 
-
-
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -18,5 +18,4 @@
 
 #include "LinearMath/btMatrix3x3.h"
-#include "LinearMath/btAabbUtil2.h"
 #include "btConvexInternalShape.h"
 
@@ -27,8 +26,5 @@
 
 protected:
-	btVector3	m_localAabbMin;
-	btVector3	m_localAabbMax;
-	bool		m_isLocalAabbValid;
-
+	
 public:
 
@@ -39,8 +35,30 @@
 	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
-
 	
 	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+	
+	
+	virtual int	getNumVertices() const = 0 ;
+	virtual int getNumEdges() const = 0;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0;
+	virtual void getVertex(int i,btVector3& vtx) const = 0;
+	virtual int	getNumPlanes() const = 0;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0;
+//	virtual int getIndex(int i) const = 0 ; 
 
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const = 0;
+	
+};
+
+
+///The btPolyhedralConvexAabbCachingShape adds aabb caching to the btPolyhedralConvexShape
+class btPolyhedralConvexAabbCachingShape : public btPolyhedralConvexShape
+{
+
+	btVector3	m_localAabbMin;
+	btVector3	m_localAabbMax;
+	bool		m_isLocalAabbValid;
+		
+protected:
 
 	void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax)
@@ -58,4 +76,8 @@
 	}
 
+public:
+
+	btPolyhedralConvexAabbCachingShape();
+	
 	inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const
 	{
@@ -66,23 +88,9 @@
 	}
 
-	
+	virtual void	setLocalScaling(const btVector3& scaling);
+
 	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
 
-	virtual void	setLocalScaling(const btVector3& scaling);
-
 	void	recalcLocalAabb();
-
-	virtual int	getNumVertices() const = 0 ;
-	virtual int getNumEdges() const = 0;
-	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0;
-	virtual void getVertex(int i,btVector3& vtx) const = 0;
-	virtual int	getNumPlanes() const = 0;
-	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0;
-//	virtual int getIndex(int i) const = 0 ; 
-
-	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const = 0;
-	
-	/// optional Hull is for optional Separating Axis Test Hull collision detection, see Hull.cpp
-	class	Hull*	m_optionalHull;
 
 };
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2008 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 
 #include "btScaledBvhTriangleMeshShape.h"
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2008 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.cpp	(revision 8284)
@@ -1,12 +1,10 @@
 /*
-btbtShapeHull implemented by John McCutchan.
-
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
+Copyright (c) 2003-2009 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,
+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:
 
@@ -16,54 +14,11 @@
 */
 
+//btShapeHull was implemented by John McCutchan.
+
+
 #include "btShapeHull.h"
 #include "LinearMath/btConvexHull.h"
 
 #define NUM_UNITSPHERE_POINTS 42
-
-static btVector3 btUnitSpherePoints[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = 
-{
-	btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)),
-	btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)),
-	btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)),
-	btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)),
-	btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)),
-	btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)),
-	btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)),
-	btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)),
-	btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)),
-	btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)),
-	btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)),
-	btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)),
-	btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)),
-	btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)),
-	btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)),
-	btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)),
-	btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)),
-	btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)),
-	btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)),
-	btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)),
-	btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)),
-	btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)),
-	btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)),
-	btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)),
-	btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)),
-	btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)),
-	btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)),
-	btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)),
-	btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)),
-	btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)),
-	btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)),
-	btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)),
-	btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)),
-	btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)),
-	btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)),
-	btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)),
-	btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)),
-	btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)),
-	btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)),
-	btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)),
-	btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)),
-	btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
-};
 
 btShapeHull::btShapeHull (const btConvexShape* shape)
@@ -93,5 +48,5 @@
 				btVector3 norm;
 				m_shape->getPreferredPenetrationDirection(i,norm);
-				btUnitSpherePoints[numSampleDirections] = norm;
+				getUnitSpherePoints()[numSampleDirections] = norm;
 				numSampleDirections++;
 			}
@@ -103,5 +58,5 @@
 	for (i = 0; i < numSampleDirections; i++)
 	{
-		supportPoints[i] = m_shape->localGetSupportingVertex(btUnitSpherePoints[i]);
+		supportPoints[i] = m_shape->localGetSupportingVertex(getUnitSpherePoints()[i]);
 	}
 
@@ -163,2 +118,53 @@
 }
 
+
+btVector3* btShapeHull::getUnitSpherePoints()
+{
+	static btVector3 sUnitSpherePoints[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = 
+	{
+		btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)),
+		btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)),
+		btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)),
+		btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)),
+		btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)),
+		btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)),
+		btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)),
+		btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)),
+		btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)),
+		btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)),
+		btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)),
+		btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)),
+		btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)),
+		btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)),
+		btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)),
+		btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)),
+		btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)),
+		btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)),
+		btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)),
+		btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)),
+		btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)),
+		btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)),
+		btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)),
+		btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)),
+		btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)),
+		btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)),
+		btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)),
+		btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)),
+		btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)),
+		btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)),
+		btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)),
+		btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)),
+		btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)),
+		btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)),
+		btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)),
+		btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)),
+		btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)),
+		btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)),
+		btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)),
+		btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)),
+		btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)),
+		btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
+	};
+	return sUnitSpherePoints;
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.h	(revision 8284)
@@ -1,12 +1,10 @@
 /*
-btShapeHull implemented by John McCutchan.
-
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2008 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 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,
+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:
 
@@ -15,4 +13,6 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
+///btShapeHull implemented by John McCutchan.
 
 #ifndef _SHAPE_HULL_H
@@ -28,4 +28,13 @@
 class btShapeHull
 {
+protected:
+
+	btAlignedObjectArray<btVector3> m_vertices;
+	btAlignedObjectArray<unsigned int> m_indices;
+	unsigned int m_numIndices;
+	const btConvexShape* m_shape;
+
+	static btVector3* getUnitSpherePoints();
+
 public:
 	btShapeHull (const btConvexShape* shape);
@@ -46,10 +55,4 @@
 		return &m_indices[0];
 	}
-
-protected:
-	btAlignedObjectArray<btVector3> m_vertices;
-	btAlignedObjectArray<unsigned int> m_indices;
-	unsigned int m_numIndices;
-	const btConvexShape* m_shape;
 };
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,5 +13,4 @@
 3. This notice may not be removed or altered from any source distribution.
 */
-
 #ifndef SPHERE_MINKOWSKI_H
 #define SPHERE_MINKOWSKI_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -39,5 +39,5 @@
 	(void)t;
 	/*
-	btVector3 infvec (btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	btVector3 infvec (btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 
 	btVector3 center = m_planeNormal*m_planeConstant;
@@ -48,6 +48,6 @@
 	*/
 
-	aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
-	aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
+	aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 
 }
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -21,5 +21,5 @@
 
 ///The btStaticPlaneShape simulates an infinite non-moving (static) collision plane.
-class btStaticPlaneShape : public btConcaveShape
+ATTRIBUTE_ALIGNED16(class) btStaticPlaneShape : public btConcaveShape
 {
 protected:
@@ -59,6 +59,45 @@
 	virtual const char*	getName()const {return "STATICPLANE";}
 
+	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	btStaticPlaneShapeData
+{
+	btCollisionShapeData	m_collisionShapeData;
+
+	btVector3FloatData	m_localScaling;
+	btVector3FloatData	m_planeNormal;
+	float			m_planeConstant;
+	char	m_pad[4];
+};
+
+
+SIMD_FORCE_INLINE	int	btStaticPlaneShape::calculateSerializeBufferSize() const
+{
+	return sizeof(btStaticPlaneShapeData);
+}
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+SIMD_FORCE_INLINE	const char*	btStaticPlaneShape::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) dataBuffer;
+	btCollisionShape::serialize(&planeData->m_collisionShapeData,serializer);
+
+	m_localScaling.serializeFloat(planeData->m_localScaling);
+	m_planeNormal.serializeFloat(planeData->m_planeNormal);
+	planeData->m_planeConstant = float(m_planeConstant);
+		
+	return "btStaticPlaneShapeData";
+}
+
+
 #endif //STATIC_PLANE_SHAPE_H
+
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -15,4 +15,5 @@
 
 #include "btStridingMeshInterface.h"
+#include "LinearMath/btSerializer.h"
 
 btStridingMeshInterface::~btStridingMeshInterface()
@@ -36,5 +37,4 @@
 	int gfxindex;
 	btVector3 triangle[3];
-	btScalar* graphicsbase;
 
 	btVector3 meshScaling = getScaling();
@@ -46,38 +46,96 @@
 		numtotalphysicsverts+=numtriangles*3; //upper bound
 
-		switch (gfxindextype)
+		///unlike that developers want to pass in double-precision meshes in single-precision Bullet build
+		///so disable this feature by default
+		///see patch http://code.google.com/p/bullet/issues/detail?id=213
+
+		switch (type)
 		{
-		case PHY_INTEGER:
+		case PHY_FLOAT:
+		 {
+
+			 float* graphicsbase;
+
+			 switch (gfxindextype)
+			 {
+			 case PHY_INTEGER:
+				 {
+					 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
+					 {
+						 unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
+						 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
+						 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
+						 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
+						 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
+						 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
+						 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
+						 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
+					 }
+					 break;
+				 }
+			 case PHY_SHORT:
+				 {
+					 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
+					 {
+						 unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
+						 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
+						 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
+						 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
+						 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
+						 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
+						 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
+						 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
+					 }
+					 break;
+				 }
+			 default:
+				 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
+			 }
+			 break;
+		 }
+
+		case PHY_DOUBLE:
 			{
-				for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
-				{
-					unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
-					graphicsbase = (btScalar*)(vertexbase+tri_indices[0]*stride);
-					triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
-					graphicsbase = (btScalar*)(vertexbase+tri_indices[1]*stride);
-					triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
-					graphicsbase = (btScalar*)(vertexbase+tri_indices[2]*stride);
-					triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
-					callback->internalProcessTriangleIndex(triangle,part,gfxindex);
-				}
-				break;
-			}
-		case PHY_SHORT:
-			{
-				for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
-				{
-					unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
-					graphicsbase = (btScalar*)(vertexbase+tri_indices[0]*stride);
-					triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
-					graphicsbase = (btScalar*)(vertexbase+tri_indices[1]*stride);
-					triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
-					graphicsbase = (btScalar*)(vertexbase+tri_indices[2]*stride);
-					triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
-					callback->internalProcessTriangleIndex(triangle,part,gfxindex);
+				double* graphicsbase;
+
+				switch (gfxindextype)
+				{
+				case PHY_INTEGER:
+					{
+						for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
+						{
+							unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
+							graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
+							triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
+							graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
+							triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
+							graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
+							triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
+							callback->internalProcessTriangleIndex(triangle,part,gfxindex);
+						}
+						break;
+					}
+				case PHY_SHORT:
+					{
+						for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
+						{
+							unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
+							graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
+							triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
+							graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
+							triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
+							graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
+							triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
+							callback->internalProcessTriangleIndex(triangle,part,gfxindex);
+						}
+						break;
+					}
+				default:
+					btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
 				}
 				break;
 			}
 		default:
-			btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
+			btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
 		}
 
@@ -96,6 +154,6 @@
 		AabbCalculationCallback()
 		{
-			m_aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
-			m_aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+			m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+			m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
 		}
 
@@ -114,8 +172,8 @@
 	};
 
-		//first calculate the total aabb for all triangles
+	//first calculate the total aabb for all triangles
 	AabbCalculationCallback	aabbCallback;
-	aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
-	aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
+	aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 	InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
 
@@ -123,2 +181,151 @@
 	aabbMax = aabbCallback.m_aabbMax;
 }
+
+
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*	btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer;
+
+	trimeshData->m_numMeshParts = getNumSubParts();
+
+	//void* uniquePtr = 0;
+
+	trimeshData->m_meshPartsPtr = 0;
+
+	if (trimeshData->m_numMeshParts)
+	{
+		btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts);
+		btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr;
+		trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr);
+
+
+	//	int numtotalphysicsverts = 0;
+		int part,graphicssubparts = getNumSubParts();
+		const unsigned char * vertexbase;
+		const unsigned char * indexbase;
+		int indexstride;
+		PHY_ScalarType type;
+		PHY_ScalarType gfxindextype;
+		int stride,numverts,numtriangles;
+		int gfxindex;
+	//	btVector3 triangle[3];
+
+		btVector3 meshScaling = getScaling();
+
+		///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
+		for (part=0;part<graphicssubparts ;part++,memPtr++)
+		{
+			getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
+			memPtr->m_numTriangles = numtriangles;//indices = 3*numtriangles
+			memPtr->m_numVertices = numverts;
+			memPtr->m_indices16 = 0;
+			memPtr->m_indices32 = 0;
+			memPtr->m_3indices16 = 0;
+			memPtr->m_vertices3f = 0;
+			memPtr->m_vertices3d = 0;
+
+			switch (gfxindextype)
+			{
+			case PHY_INTEGER:
+				{
+					int numindices = numtriangles*3;
+				
+					if (numindices)
+					{
+						btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices);
+						btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr;
+						memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices);
+						for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
+						{
+							unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
+							tmpIndices[gfxindex*3].m_value = tri_indices[0];
+							tmpIndices[gfxindex*3+1].m_value = tri_indices[1];
+							tmpIndices[gfxindex*3+2].m_value = tri_indices[2];
+						}
+						serializer->finalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
+					}
+					break;
+				}
+			case PHY_SHORT:
+				{
+					if (numtriangles)
+					{
+						btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles);
+						btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr;
+						memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices);
+						for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
+						{
+							unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
+							tmpIndices[gfxindex].m_values[0] = tri_indices[0];
+							tmpIndices[gfxindex].m_values[1] = tri_indices[1];
+							tmpIndices[gfxindex].m_values[2] = tri_indices[2];
+						}
+						serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
+					}
+					break;
+				}
+			default:
+				{
+					btAssert(0);
+					//unknown index type
+				}
+			}
+
+			switch (type)
+			{
+			case PHY_FLOAT:
+			 {
+				 float* graphicsbase;
+
+				 if (numverts)
+				 {
+					 btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts);
+					 btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr;
+					 memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices);
+					 for (int i=0;i<numverts;i++)
+					 {
+						 graphicsbase = (float*)(vertexbase+i*stride);
+						 tmpVertices[i].m_floats[0] = graphicsbase[0];
+						 tmpVertices[i].m_floats[1] = graphicsbase[1];
+						 tmpVertices[i].m_floats[2] = graphicsbase[2];
+					 }
+					 serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
+				 }
+				 break;
+				}
+
+			case PHY_DOUBLE:
+				{
+					if (numverts)
+					{
+						btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts);
+						btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr;
+						memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices);
+						for (int i=0;i<numverts;i++)
+					 {
+						 double* graphicsbase = (double*)(vertexbase+i*stride);//for now convert to float, might leave it at double
+						 tmpVertices[i].m_floats[0] = graphicsbase[0];
+						 tmpVertices[i].m_floats[1] = graphicsbase[1];
+						 tmpVertices[i].m_floats[2] = graphicsbase[2];
+					 }
+						serializer->finalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr);
+					}
+					break;
+				}
+
+			default:
+				btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
+			}
+
+			unLockReadOnlyVertexBase(part);
+		}
+
+		serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr);
+	}
+
+
+	m_scaling.serializeFloat(trimeshData->m_scaling);
+	return "btStridingMeshInterfaceData";
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -20,4 +20,6 @@
 #include "btTriangleCallback.h"
 #include "btConcaveShape.h"
+
+
 
 
@@ -90,7 +92,63 @@
 		}
 
-	
+		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;
+
 
 };
 
+struct	btIntIndexData
+{
+	int	m_value;
+};
+
+struct	btShortIntIndexData
+{
+	short m_value;
+	char m_pad[2];
+};
+
+struct	btShortIntIndexTripletData
+{
+	short	m_values[3];
+	char	m_pad[2];
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btMeshPartData
+{
+	btVector3FloatData			*m_vertices3f;
+	btVector3DoubleData			*m_vertices3d;
+
+	btIntIndexData				*m_indices32;
+	btShortIntIndexTripletData	*m_3indices16;
+
+	btShortIntIndexData			*m_indices16;//backwards compatibility
+
+	int                     m_numTriangles;//length of m_indices = m_numTriangles
+	int                     m_numVertices;
+};
+
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btStridingMeshInterfaceData
+{
+	btMeshPartData	*m_meshPartsPtr;
+	btVector3FloatData	m_scaling;
+	int	m_numMeshParts;
+	char m_padding[4];
+};
+
+
+
+
+SIMD_FORCE_INLINE	int	btStridingMeshInterface::calculateSerializeBufferSize() const
+{
+	return sizeof(btStridingMeshInterfaceData);
+}
+
+
+
 #endif //STRIDING_MESHINTERFACE_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp	(revision 8284)
@@ -1,6 +1,5 @@
-
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -14,21 +13,22 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 #include "btTetrahedronShape.h"
 #include "LinearMath/btMatrix3x3.h"
 
-btBU_Simplex1to4::btBU_Simplex1to4() : btPolyhedralConvexShape (),
-m_numVertices(0)
-{
-	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
-}
-
-btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0) : btPolyhedralConvexShape (),
-m_numVertices(0)
-{
-	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
-	addVertex(pt0);
-}
-
-btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1) : btPolyhedralConvexShape (),
+btBU_Simplex1to4::btBU_Simplex1to4() : btPolyhedralConvexAabbCachingShape (),
+m_numVertices(0)
+{
+	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
+}
+
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0) : btPolyhedralConvexAabbCachingShape (),
+m_numVertices(0)
+{
+	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
+	addVertex(pt0);
+}
+
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1) : btPolyhedralConvexAabbCachingShape (),
 m_numVertices(0)
 {
@@ -38,5 +38,5 @@
 }
 
-btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2) : btPolyhedralConvexShape (),
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2) : btPolyhedralConvexAabbCachingShape (),
 m_numVertices(0)
 {
@@ -47,5 +47,5 @@
 }
 
-btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3) : btPolyhedralConvexShape (),
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3) : btPolyhedralConvexAabbCachingShape (),
 m_numVertices(0)
 {
@@ -58,4 +58,23 @@
 
 
+void btBU_Simplex1to4::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+#if 1
+	btPolyhedralConvexAabbCachingShape::getAabb(t,aabbMin,aabbMax);
+#else
+	aabbMin.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT);
+	aabbMax.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT);
+
+	//just transform the vertices in worldspace, and take their AABB
+	for (int i=0;i<m_numVertices;i++)
+	{
+		btVector3 worldVertex = t(m_vertices[i]);
+		aabbMin.setMin(worldVertex);
+		aabbMax.setMax(worldVertex);
+	}
+#endif
+}
+
+
 
 
@@ -64,5 +83,4 @@
 {
 	m_vertices[m_numVertices++] = pt;
-
 	recalcLocalAabb();
 }
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -23,5 +23,5 @@
 
 ///The btBU_Simplex1to4 implements tetrahedron, triangle, line, vertex collision shapes. In most cases it is better to use btConvexHullShape instead.
-class btBU_Simplex1to4 : public btPolyhedralConvexShape
+class btBU_Simplex1to4 : public btPolyhedralConvexAabbCachingShape
 {
 protected:
@@ -44,5 +44,5 @@
 	}
 	
-
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
 
 	void addVertex(const btVector3& pt);
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp	(revision 8284)
@@ -1,10 +1,10 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 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,
+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:
 
@@ -45,9 +45,7 @@
 	numverts = mesh.m_numVertices;
 	(*vertexbase) = (unsigned char *) mesh.m_vertexBase;
-	#ifdef BT_USE_DOUBLE_PRECISION
-	type = PHY_DOUBLE;
-	#else
-	type = PHY_FLOAT;
-	#endif
+
+   type = mesh.m_vertexType;
+
 	vertexStride = mesh.m_vertexStride;
 
@@ -65,9 +63,7 @@
 	numverts = mesh.m_numVertices;
 	(*vertexbase) = (const unsigned char *)mesh.m_vertexBase;
-	#ifdef BT_USE_DOUBLE_PRECISION
-	type = PHY_DOUBLE;
-	#else
-	type = PHY_FLOAT;
-	#endif
+
+   type = mesh.m_vertexType;
+   
 	vertexStride = mesh.m_vertexStride;
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -28,14 +28,30 @@
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 
-	int			m_numTriangles;
-	const unsigned char *		m_triangleIndexBase;
-	int			m_triangleIndexStride;
-	int			m_numVertices;
-	const unsigned char *		m_vertexBase;
-	int			m_vertexStride;
-	// The index type is set when adding an indexed mesh to the
-	// btTriangleIndexVertexArray, do not set it manually
-	PHY_ScalarType		m_indexType;
-	int			pad;
+   int                     m_numTriangles;
+   const unsigned char *   m_triangleIndexBase;
+   int                     m_triangleIndexStride;
+   int                     m_numVertices;
+   const unsigned char *   m_vertexBase;
+   int                     m_vertexStride;
+
+   // The index type is set when adding an indexed mesh to the
+   // btTriangleIndexVertexArray, do not set it manually
+   PHY_ScalarType m_indexType;
+
+   // The vertex type has a default type similar to Bullet's precision mode (float or double)
+   // but can be set manually if you for example run Bullet with double precision but have
+   // mesh data in single precision..
+   PHY_ScalarType m_vertexType;
+
+
+   btIndexedMesh()
+	   :m_indexType(PHY_INTEGER),
+#ifdef BT_USE_DOUBLE_PRECISION
+      m_vertexType(PHY_DOUBLE)
+#else // BT_USE_DOUBLE_PRECISION
+      m_vertexType(PHY_FLOAT)
+#endif // BT_USE_DOUBLE_PRECISION
+      {
+      }
 }
 ;
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp	(revision 8284)
@@ -1,11 +1,10 @@
-
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 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,
+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:
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleInfoMap.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleInfoMap.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleInfoMap.h	(revision 8284)
@@ -0,0 +1,238 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2010 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_TRIANGLE_INFO_MAP_H
+#define _BT_TRIANGLE_INFO_MAP_H
+
+
+#include "LinearMath/btHashMap.h"
+#include "LinearMath/btSerializer.h"
+
+
+///for btTriangleInfo m_flags
+#define TRI_INFO_V0V1_CONVEX 1
+#define TRI_INFO_V1V2_CONVEX 2
+#define TRI_INFO_V2V0_CONVEX 4
+
+#define TRI_INFO_V0V1_SWAP_NORMALB 8
+#define TRI_INFO_V1V2_SWAP_NORMALB 16
+#define TRI_INFO_V2V0_SWAP_NORMALB 32
+
+
+///The btTriangleInfo structure stores information to adjust collision normals to avoid collisions against internal edges
+///it can be generated using 
+struct	btTriangleInfo
+{
+	btTriangleInfo()
+	{
+		m_edgeV0V1Angle = SIMD_2_PI;
+		m_edgeV1V2Angle = SIMD_2_PI;
+		m_edgeV2V0Angle = SIMD_2_PI;
+		m_flags=0;
+	}
+
+	int			m_flags;
+
+	btScalar	m_edgeV0V1Angle;
+	btScalar	m_edgeV1V2Angle;
+	btScalar	m_edgeV2V0Angle;
+
+};
+
+typedef btHashMap<btHashInt,btTriangleInfo> btInternalTriangleInfoMap;
+
+
+///The btTriangleInfoMap stores edge angle information for some triangles. You can compute this information yourself or using btGenerateInternalEdgeInfo.
+struct	btTriangleInfoMap : public btInternalTriangleInfoMap
+{
+	btScalar	m_convexEpsilon;///used to determine if an edge or contact normal is convex, using the dot product
+	btScalar	m_planarEpsilon; ///used to determine if a triangle edge is planar with zero angle
+	btScalar	m_equalVertexThreshold; ///used to compute connectivity: if the distance between two vertices is smaller than m_equalVertexThreshold, they are considered to be 'shared'
+	btScalar	m_edgeDistanceThreshold; ///used to determine edge contacts: if the closest distance between a contact point and an edge is smaller than this distance threshold it is considered to "hit the edge"
+	btScalar	m_zeroAreaThreshold; ///used to determine if a triangle is degenerate (length squared of cross product of 2 triangle edges < threshold)
+	
+	
+	btTriangleInfoMap()
+	{
+		m_convexEpsilon = 0.00f;
+		m_planarEpsilon = 0.0001f;
+		m_equalVertexThreshold = btScalar(0.0001)*btScalar(0.0001);
+		m_edgeDistanceThreshold = btScalar(0.1);
+		m_zeroAreaThreshold = btScalar(0.0001)*btScalar(0.0001);
+	}
+	virtual ~btTriangleInfoMap() {}
+
+	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;
+
+	void	deSerialize(struct btTriangleInfoMapData& data);
+
+};
+
+struct	btTriangleInfoData
+{
+	int			m_flags;
+	float	m_edgeV0V1Angle;
+	float	m_edgeV1V2Angle;
+	float	m_edgeV2V0Angle;
+};
+
+struct	btTriangleInfoMapData
+{
+	int					*m_hashTablePtr;
+	int					*m_nextPtr;
+	btTriangleInfoData	*m_valueArrayPtr;
+	int					*m_keyArrayPtr;
+
+	float	m_convexEpsilon;
+	float	m_planarEpsilon;
+	float	m_equalVertexThreshold; 
+	float	m_edgeDistanceThreshold;
+	float	m_zeroAreaThreshold;
+
+	int		m_nextSize;
+	int		m_hashTableSize;
+	int		m_numValues;
+	int		m_numKeys;
+	char	m_padding[4];
+};
+
+SIMD_FORCE_INLINE	int	btTriangleInfoMap::calculateSerializeBufferSize() const
+{
+	return sizeof(btTriangleInfoMapData);
+}
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+SIMD_FORCE_INLINE	const char*	btTriangleInfoMap::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btTriangleInfoMapData* tmapData = (btTriangleInfoMapData*) dataBuffer;
+	tmapData->m_convexEpsilon = m_convexEpsilon;
+	tmapData->m_planarEpsilon = m_planarEpsilon;
+	tmapData->m_equalVertexThreshold = m_equalVertexThreshold;
+	tmapData->m_edgeDistanceThreshold = m_edgeDistanceThreshold;
+	tmapData->m_zeroAreaThreshold = m_zeroAreaThreshold;
+	
+	tmapData->m_hashTableSize = m_hashTable.size();
+
+	tmapData->m_hashTablePtr = tmapData->m_hashTableSize ? (int*)serializer->getUniquePointer((void*)&m_hashTable[0]) : 0;
+	if (tmapData->m_hashTablePtr)
+	{ 
+		//serialize an int buffer
+		int sz = sizeof(int);
+		int numElem = tmapData->m_hashTableSize;
+		btChunk* chunk = serializer->allocate(sz,numElem);
+		int* memPtr = (int*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			*memPtr = m_hashTable[i];
+		}
+		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_hashTable[0]);
+
+	}
+
+	tmapData->m_nextSize = m_next.size();
+	tmapData->m_nextPtr = tmapData->m_nextSize? (int*)serializer->getUniquePointer((void*)&m_next[0]): 0;
+	if (tmapData->m_nextPtr)
+	{
+		int sz = sizeof(int);
+		int numElem = tmapData->m_nextSize;
+		btChunk* chunk = serializer->allocate(sz,numElem);
+		int* memPtr = (int*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			*memPtr = m_next[i];
+		}
+		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_next[0]);
+	}
+	
+	tmapData->m_numValues = m_valueArray.size();
+	tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)serializer->getUniquePointer((void*)&m_valueArray[0]): 0;
+	if (tmapData->m_valueArrayPtr)
+	{
+		int sz = sizeof(btTriangleInfoData);
+		int numElem = tmapData->m_numValues;
+		btChunk* chunk = serializer->allocate(sz,numElem);
+		btTriangleInfoData* memPtr = (btTriangleInfoData*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			memPtr->m_edgeV0V1Angle = m_valueArray[i].m_edgeV0V1Angle;
+			memPtr->m_edgeV1V2Angle = m_valueArray[i].m_edgeV1V2Angle;
+			memPtr->m_edgeV2V0Angle = m_valueArray[i].m_edgeV2V0Angle;
+			memPtr->m_flags = m_valueArray[i].m_flags;
+		}
+		serializer->finalizeChunk(chunk,"btTriangleInfoData",BT_ARRAY_CODE,(void*) &m_valueArray[0]);
+	}
+	
+	tmapData->m_numKeys = m_keyArray.size();
+	tmapData->m_keyArrayPtr = tmapData->m_numKeys ? (int*)serializer->getUniquePointer((void*)&m_keyArray[0]) : 0;
+	if (tmapData->m_keyArrayPtr)
+	{
+		int sz = sizeof(int);
+		int numElem = tmapData->m_numValues;
+		btChunk* chunk = serializer->allocate(sz,numElem);
+		int* memPtr = (int*)chunk->m_oldPtr;
+		for (int i=0;i<numElem;i++,memPtr++)
+		{
+			*memPtr = m_keyArray[i].getUid1();
+		}
+		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*) &m_keyArray[0]);
+
+	}
+	return "btTriangleInfoMapData";
+}
+
+
+
+///fills the dataBuffer and returns the struct name (and 0 on failure)
+SIMD_FORCE_INLINE	void	btTriangleInfoMap::deSerialize(btTriangleInfoMapData& tmapData )
+{
+
+
+	m_convexEpsilon = tmapData.m_convexEpsilon;
+	m_planarEpsilon = tmapData.m_planarEpsilon;
+	m_equalVertexThreshold = tmapData.m_equalVertexThreshold;
+	m_edgeDistanceThreshold = tmapData.m_edgeDistanceThreshold;
+	m_zeroAreaThreshold = tmapData.m_zeroAreaThreshold;
+	m_hashTable.resize(tmapData.m_hashTableSize);
+	int i =0;
+	for (i=0;i<tmapData.m_hashTableSize;i++)
+	{
+		m_hashTable[i] = tmapData.m_hashTablePtr[i];
+	}
+	m_next.resize(tmapData.m_nextSize);
+	for (i=0;i<tmapData.m_nextSize;i++)
+	{
+		m_next[i] = tmapData.m_nextPtr[i];
+	}
+	m_valueArray.resize(tmapData.m_numValues);
+	for (i=0;i<tmapData.m_numValues;i++)
+	{
+		m_valueArray[i].m_edgeV0V1Angle = tmapData.m_valueArrayPtr[i].m_edgeV0V1Angle;
+		m_valueArray[i].m_edgeV1V2Angle = tmapData.m_valueArrayPtr[i].m_edgeV1V2Angle;
+		m_valueArray[i].m_edgeV2V0Angle = tmapData.m_valueArrayPtr[i].m_edgeV2V0Angle;
+		m_valueArray[i].m_flags = tmapData.m_valueArrayPtr[i].m_flags;
+	}
+	
+	m_keyArray.resize(tmapData.m_numKeys,btHashInt(0));
+	for (i=0;i<tmapData.m_numKeys;i++)
+	{
+		m_keyArray[i].setUid1(tmapData.m_keyArrayPtr[i]);
+	}
+}
+
+
+#endif //_BT_TRIANGLE_INFO_MAP_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 
 #include "btTriangleMesh.h"
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,5 +13,4 @@
 3. This notice may not be removed or altered from any source distribution.
 */
-
 
 #ifndef TRIANGLE_MESH_H
@@ -42,7 +41,4 @@
 		btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true);
 
-		int		findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices);
-		void	addIndex(int index);
-
 		bool	getUse32bitIndices() const
 		{
@@ -63,4 +59,8 @@
 		virtual void	preallocateIndices(int numindices){(void) numindices;}
 
+		///findOrAddVertex is an internal method, use addTriangle instead
+		int		findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices);
+		///addIndex is an internal method, use addTriangle instead
+		void	addIndex(int index);
 		
 };
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -92,5 +92,5 @@
 
 	SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans)
-		: m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-1e30))
+		: m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-BT_LARGE_FLOAT))
 		
 	{
@@ -200,5 +200,5 @@
 	SupportVertexCallback supportCallback(vec,ident);
 
-	btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 	
 	processAllTriangles(&supportCallback,-aabbMax,aabbMax);
@@ -208,2 +208,4 @@
 	return supportVertex;
 }
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -80,6 +80,10 @@
 	virtual const char*	getName()const {return "TRIANGLEMESH";}
 
+	
 
 };
 
+
+
+
 #endif //TRIANGLE_MESH_SHAPE_H
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -20,5 +20,5 @@
 #include "btBoxShape.h"
 
-class btTriangleShape : public btPolyhedralConvexShape
+ATTRIBUTE_ALIGNED16(class) btTriangleShape : public btPolyhedralConvexShape
 {
 
@@ -31,4 +31,9 @@
 	{
 		return 3;
+	}
+
+	btVector3& getVertexPtr(int index)
+	{
+		return m_vertices1[index];
 	}
 
@@ -78,5 +83,8 @@
 	}
 
-
+	btTriangleShape() : btPolyhedralConvexShape ()
+    {
+		m_shapeType = TRIANGLE_SHAPE_PROXYTYPE;
+	}
 
 	btTriangleShape(const btVector3& p0,const btVector3& p1,const btVector3& p2) : btPolyhedralConvexShape ()
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2007 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp	(revision 8284)
@@ -97,5 +97,5 @@
 	{
 		
-		btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);		
+		btGjkPairDetector gjk(m_convexA,m_convexB,m_convexA->getShapeType(),m_convexB->getShapeType(),m_convexA->getMargin(),m_convexB->getMargin(),m_simplexSolver,m_penetrationDepthSolver);		
 		btGjkPairDetector::ClosestPointInput input;
 	
@@ -122,4 +122,8 @@
 		while (dist > radius)
 		{
+			if (result.m_debugDrawer)
+			{
+				result.m_debugDrawer->drawSphere(c,0.2f,btVector3(1,1,1));
+			}
 			numIter++;
 			if (numIter > maxIter)
@@ -170,4 +174,9 @@
 			btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB);
 			relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA);
+
+			if (result.m_debugDrawer)
+			{
+				result.m_debugDrawer->drawSphere(interpolatedTransA.getOrigin(),0.2f,btVector3(1,0,0));
+			}
 
 			result.DebugDraw( lambda );
@@ -198,4 +207,5 @@
 				return false;
 			}
+			
 
 		}
@@ -225,3 +235,2 @@
 
 }
-
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h	(revision 8284)
@@ -42,5 +42,5 @@
 
 		CastResult()
-			:m_fraction(btScalar(1e30)),
+			:m_fraction(btScalar(BT_LARGE_FLOAT)),
 			m_debugDrawer(0),
 			m_allowedPenetration(btScalar(0))
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h	(revision 8284)
@@ -15,6 +15,6 @@
 
 
-#ifndef CONVEX_PENETRATION_DEPTH_H
-#define CONVEX_PENETRATION_DEPTH_H
+#ifndef __CONVEX_PENETRATION_DEPTH_H
+#define __CONVEX_PENETRATION_DEPTH_H
 
 class btStackAlloc;
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h	(revision 8284)
@@ -34,6 +34,7 @@
 		virtual ~Result(){}	
 
-		///setShapeIdentifiers provides experimental support for per-triangle material / custom material combiner
-		virtual void setShapeIdentifiers(int partId0,int index0,	int partId1,int index1)=0;
+		///setShapeIdentifiersA/B provides experimental support for per-triangle material / custom material combiner
+		virtual void setShapeIdentifiersA(int partId0,int index0)=0;
+		virtual void setShapeIdentifiersB(int partId1,int index1)=0;
 		virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)=0;
 	};
@@ -42,5 +43,5 @@
 	{
 		ClosestPointInput()
-			:m_maximumDistanceSquared(btScalar(1e30)),
+			:m_maximumDistanceSquared(btScalar(BT_LARGE_FLOAT)),
 			m_stackAlloc(0)
 		{
@@ -69,5 +70,5 @@
 		btScalar	m_distance; //negative means penetration !
 
-		btStorageResult() : m_distance(btScalar(1e30))
+		btStorageResult() : m_distance(btScalar(BT_LARGE_FLOAT))
 		{
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp	(revision 8284)
@@ -69,5 +69,41 @@
 		btMatrix3x3				m_toshape1;
 		btTransform				m_toshape0;
+#ifdef __SPU__
+		bool					m_enableMargin;
+#else
 		btVector3				(btConvexShape::*Ls)(const btVector3&) const;
+#endif//__SPU__
+		
+
+		MinkowskiDiff()
+		{
+
+		}
+#ifdef __SPU__
+			void					EnableMargin(bool enable)
+		{
+			m_enableMargin = enable;
+		}	
+		inline btVector3		Support0(const btVector3& d) const
+		{
+			if (m_enableMargin)
+			{
+				return m_shapes[0]->localGetSupportVertexNonVirtual(d);
+			} else
+			{
+				return m_shapes[0]->localGetSupportVertexWithoutMarginNonVirtual(d);
+			}
+		}
+		inline btVector3		Support1(const btVector3& d) const
+		{
+			if (m_enableMargin)
+			{
+				return m_toshape0*(m_shapes[1]->localGetSupportVertexNonVirtual(m_toshape1*d));
+			} else
+			{
+				return m_toshape0*(m_shapes[1]->localGetSupportVertexWithoutMarginNonVirtual(m_toshape1*d));
+			}
+		}
+#else
 		void					EnableMargin(bool enable)
 		{
@@ -85,4 +121,6 @@
 			return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d));
 		}
+#endif //__SPU__
+
 		inline btVector3		Support(const btVector3& d) const
 		{
@@ -203,5 +241,5 @@
 					}
 					/* Check for termination				*/ 
-					const btScalar	omega=dot(m_ray,w)/rl;
+					const btScalar	omega=btDot(m_ray,w)/rl;
 					alpha=btMax(omega,alpha);
 					if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
@@ -260,4 +298,7 @@
 				case	eStatus::Valid:		m_distance=m_ray.length();break;
 				case	eStatus::Inside:	m_distance=0;break;
+				default:
+					{
+					}
 				}	
 				return(m_status);
@@ -289,5 +330,5 @@
 							btVector3		axis=btVector3(0,0,0);
 							axis[i]=1;
-							const btVector3	p=cross(d,axis);
+							const btVector3	p=btCross(d,axis);
 							if(p.length2()>0)
 							{
@@ -304,5 +345,5 @@
 				case	3:
 					{
-						const btVector3	n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w,
+						const btVector3	n=btCross(m_simplex->c[1]->w-m_simplex->c[0]->w,
 							m_simplex->c[2]->w-m_simplex->c[0]->w);
 						if(n.length2()>0)
@@ -358,5 +399,5 @@
 				if(l>GJK_SIMPLEX2_EPS)
 				{
-					const btScalar	t(l>0?-dot(a,d)/l:0);
+					const btScalar	t(l>0?-btDot(a,d)/l:0);
 					if(t>=1)		{ w[0]=0;w[1]=1;m=2;return(b.length2()); }
 					else if(t<=0)	{ w[0]=1;w[1]=0;m=1;return(a.length2()); }
@@ -373,14 +414,14 @@
 				const btVector3*	vt[]={&a,&b,&c};
 				const btVector3		dl[]={a-b,b-c,c-a};
-				const btVector3		n=cross(dl[0],dl[1]);
+				const btVector3		n=btCross(dl[0],dl[1]);
 				const btScalar		l=n.length2();
 				if(l>GJK_SIMPLEX3_EPS)
 				{
 					btScalar	mindist=-1;
-					btScalar	subw[2];
-					U			subm;
+					btScalar	subw[2]={0.f,0.f};
+					U			subm(0);
 					for(U i=0;i<3;++i)
 					{
-						if(dot(*vt[i],cross(dl[i],n))>0)
+						if(btDot(*vt[i],btCross(dl[i],n))>0)
 						{
 							const U			j=imd3[i];
@@ -398,11 +439,11 @@
 					if(mindist<0)
 					{
-						const btScalar	d=dot(a,n);	
+						const btScalar	d=btDot(a,n);	
 						const btScalar	s=btSqrt(l);
 						const btVector3	p=n*(d/l);
 						mindist	=	p.length2();
 						m		=	7;
-						w[0]	=	(cross(dl[1],b-p)).length()/s;
-						w[1]	=	(cross(dl[2],c-p)).length()/s;
+						w[0]	=	(btCross(dl[1],b-p)).length()/s;
+						w[1]	=	(btCross(dl[2],c-p)).length()/s;
 						w[2]	=	1-(w[0]+w[1]);
 					}
@@ -421,14 +462,14 @@
 				const btVector3		dl[]={a-d,b-d,c-d};
 				const btScalar		vl=det(dl[0],dl[1],dl[2]);
-				const bool			ng=(vl*dot(a,cross(b-c,a-b)))<=0;
+				const bool			ng=(vl*btDot(a,btCross(b-c,a-b)))<=0;
 				if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS))
 				{
 					btScalar	mindist=-1;
-					btScalar	subw[3];
-					U			subm;
+					btScalar	subw[3]={0.f,0.f,0.f};
+					U			subm(0);
 					for(U i=0;i<3;++i)
 					{
 						const U			j=imd3[i];
-						const btScalar	s=vl*dot(d,cross(dl[i],dl[j]));
+						const btScalar	s=vl*btDot(d,btCross(dl[i],dl[j]));
 						if(s>0)
 						{
@@ -602,5 +643,5 @@
 								best->pass	=	(U1)(++pass);
 								gjk.getsupport(best->n,*w);
-								const btScalar	wdist=dot(best->n,w->w)-best->d;
+								const btScalar	wdist=btDot(best->n,w->w)-best->d;
 								if(wdist>EPA_ACCURACY)
 								{
@@ -629,9 +670,9 @@
 						m_result.c[1]	=	outer.c[1];
 						m_result.c[2]	=	outer.c[2];
-						m_result.p[0]	=	cross(	outer.c[1]->w-projection,
+						m_result.p[0]	=	btCross(	outer.c[1]->w-projection,
 							outer.c[2]->w-projection).length();
-						m_result.p[1]	=	cross(	outer.c[2]->w-projection,
+						m_result.p[1]	=	btCross(	outer.c[2]->w-projection,
 							outer.c[0]->w-projection).length();
-						m_result.p[2]	=	cross(	outer.c[0]->w-projection,
+						m_result.p[2]	=	btCross(	outer.c[0]->w-projection,
 							outer.c[1]->w-projection).length();
 						const btScalar	sum=m_result.p[0]+m_result.p[1]+m_result.p[2];
@@ -667,16 +708,16 @@
 					face->c[1]	=	b;
 					face->c[2]	=	c;
-					face->n		=	cross(b->w-a->w,c->w-a->w);
+					face->n		=	btCross(b->w-a->w,c->w-a->w);
 					const btScalar	l=face->n.length();
 					const bool		v=l>EPA_ACCURACY;
 					face->p		=	btMin(btMin(
-						dot(a->w,cross(face->n,a->w-b->w)),
-						dot(b->w,cross(face->n,b->w-c->w))),
-						dot(c->w,cross(face->n,c->w-a->w)))	/
+						btDot(a->w,btCross(face->n,a->w-b->w)),
+						btDot(b->w,btCross(face->n,b->w-c->w))),
+						btDot(c->w,btCross(face->n,c->w-a->w)))	/
 						(v?l:1);
 					face->p		=	face->p>=-EPA_INSIDE_EPS?0:face->p;
 					if(v)
 					{
-						face->d		=	dot(a->w,face->n)/l;
+						face->d		=	btDot(a->w,face->n)/l;
 						face->n		/=	l;
 						if(forced||(face->d>=-EPA_PLANE_EPS))
@@ -716,5 +757,5 @@
 				{
 					const U	e1=i1m3[e];
-					if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
+					if((btDot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
 					{
 						sFace*	nf=newface(f->c[e1],f->c[e],w,false);
@@ -855,8 +896,12 @@
 		results.status=sResults::GJK_Failed;
 		break;
+		default:
+					{
+					}
 	}
 	return(false);
 }
 
+#ifndef __SPU__
 //
 btScalar	btGjkEpaSolver2::SignedDistance(const btVector3& position,
@@ -924,4 +969,5 @@
 		return(true);
 }
+#endif //__SPU__
 
 /* Symbols cleanup		*/ 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h	(revision 8284)
@@ -56,5 +56,5 @@
 							sResults& results,
 							bool usemargins=true);
-
+#ifndef __SPU__
 static btScalar	SignedDistance(	const btVector3& position,
 								btScalar margin,
@@ -67,4 +67,6 @@
 								const btVector3& guess,
 								sResults& results);
+#endif //__SPU__
+
 };
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp	(revision 8284)
@@ -33,8 +33,10 @@
 	(void)simplexSolver;
 
-	const btScalar				radialmargin(btScalar(0.));
+//	const btScalar				radialmargin(btScalar(0.));
 	
 	btVector3	guessVector(transformA.getOrigin()-transformB.getOrigin());
 	btGjkEpaSolver2::sResults	results;
+	
+
 	if(btGjkEpaSolver2::Penetration(pConvexA,transformA,
 								pConvexB,transformB,
@@ -46,6 +48,16 @@
 		wWitnessOnA = results.witnesses[0];
 		wWitnessOnB = results.witnesses[1];
+		v = results.normal;
 		return true;		
+		} else
+	{
+		if(btGjkEpaSolver2::Distance(pConvexA,transformA,pConvexB,transformB,guessVector,results))
+		{
+			wWitnessOnA = results.witnesses[0];
+			wWitnessOnB = results.witnesses[1];
+			v = results.normal;
+			return false;
 		}
+	}
 
 	return false;
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h	(revision 8284)
@@ -26,4 +26,8 @@
 	public :
 
+		btGjkEpaPenetrationDepthSolver()
+		{
+		}
+
 		bool			calcPenDepth( btSimplexSolverInterface& simplexSolver,
 									  const btConvexShape* pConvexA, const btConvexShape* pConvexB,
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp	(revision 8284)
@@ -39,11 +39,14 @@
 
 
-
 btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver*	penetrationDepthSolver)
-:m_cachedSeparatingAxis(btScalar(0.),btScalar(0.),btScalar(1.)),
+:m_cachedSeparatingAxis(btScalar(0.),btScalar(1.),btScalar(0.)),
 m_penetrationDepthSolver(penetrationDepthSolver),
 m_simplexSolver(simplexSolver),
 m_minkowskiA(objectA),
 m_minkowskiB(objectB),
+m_shapeTypeA(objectA->getShapeType()),
+m_shapeTypeB(objectB->getShapeType()),
+m_marginA(objectA->getMargin()),
+m_marginB(objectB->getMargin()),
 m_ignoreMargin(false),
 m_lastUsedMethod(-1),
@@ -51,6 +54,32 @@
 {
 }
-
-void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
+btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver*	penetrationDepthSolver)
+:m_cachedSeparatingAxis(btScalar(0.),btScalar(1.),btScalar(0.)),
+m_penetrationDepthSolver(penetrationDepthSolver),
+m_simplexSolver(simplexSolver),
+m_minkowskiA(objectA),
+m_minkowskiB(objectB),
+m_shapeTypeA(shapeTypeA),
+m_shapeTypeB(shapeTypeB),
+m_marginA(marginA),
+m_marginB(marginB),
+m_ignoreMargin(false),
+m_lastUsedMethod(-1),
+m_catchDegeneracies(1)
+{
+}
+
+void	btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
+{
+	(void)swapResults;
+
+	getClosestPointsNonVirtual(input,output,debugDraw);
+}
+
+#ifdef __SPU__
+void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
+#else
+void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw)
+#endif
 {
 	m_cachedSeparatingDistance = 0.f;
@@ -65,19 +94,8 @@
 	localTransB.getOrigin() -= positionOffset;
 
-#ifdef __SPU__
-	btScalar marginA = m_minkowskiA->getMarginNonVirtual();
-	btScalar marginB = m_minkowskiB->getMarginNonVirtual();
-#else
-	btScalar marginA = m_minkowskiA->getMargin();
-	btScalar marginB = m_minkowskiB->getMargin();
-#ifdef TEST_NON_VIRTUAL
-	btScalar marginAv = m_minkowskiA->getMarginNonVirtual();
-	btScalar marginBv = m_minkowskiB->getMarginNonVirtual();
-	btAssert(marginA == marginAv);
-	btAssert(marginB == marginBv);
-#endif //TEST_NON_VIRTUAL
-#endif
-	
-
+	bool check2d = m_minkowskiA->isConvex2d() && m_minkowskiB->isConvex2d();
+
+	btScalar marginA = m_marginA;
+	btScalar marginB = m_marginB;
 
 	gNumGjkChecks++;
@@ -108,5 +126,5 @@
 
 	{
-		btScalar squaredDistance = SIMD_INFINITY;
+		btScalar squaredDistance = BT_LARGE_FLOAT;
 		btScalar delta = btScalar(0.);
 		
@@ -124,4 +142,13 @@
 			btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis();
 
+#if 1
+
+			btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
+			btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
+
+//			btVector3 pInA  = localGetSupportingVertexWithoutMargin(m_shapeTypeA, m_minkowskiA, seperatingAxisInA,input.m_convexVertexData[0]);//, &featureIndexA);
+//			btVector3 qInB  = localGetSupportingVertexWithoutMargin(m_shapeTypeB, m_minkowskiB, seperatingAxisInB,input.m_convexVertexData[1]);//, &featureIndexB);
+
+#else
 #ifdef __SPU__
 			btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
@@ -137,4 +164,6 @@
 #endif //
 #endif //__SPU__
+#endif
+
 
 			btVector3  pWorld = localTransA(pInA);	
@@ -145,4 +174,10 @@
 #endif
 
+			if (check2d)
+			{
+				pWorld[2] = 0.f;
+				qWorld[2] = 0.f;
+			}
+
 			btVector3 w	= pWorld - qWorld;
 			delta = m_cachedSeparatingAxis.dot(w);
@@ -151,4 +186,5 @@
 			if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared)) 
 			{
+				m_degenerateSimplex = 10;
 				checkSimplex=true;
 				//checkPenetration = false;
@@ -172,4 +208,7 @@
 				{
 					m_degenerateSimplex = 2;
+				} else
+				{
+					m_degenerateSimplex = 11;
 				}
 				checkSimplex = true;
@@ -185,6 +224,8 @@
 		spu_printf("addVertex 2\n");
 #endif
+			btVector3 newCachedSeparatingAxis;
+
 			//calculate the closest point to the origin (update vector v)
-			if (!m_simplexSolver->closest(m_cachedSeparatingAxis))
+			if (!m_simplexSolver->closest(newCachedSeparatingAxis))
 			{
 				m_degenerateSimplex = 3;
@@ -193,6 +234,7 @@
 			}
 
-			if(m_cachedSeparatingAxis.length2()<REL_ERROR2)
+			if(newCachedSeparatingAxis.length2()<REL_ERROR2)
             {
+				m_cachedSeparatingAxis = newCachedSeparatingAxis;
                 m_degenerateSimplex = 6;
                 checkSimplex = true;
@@ -201,6 +243,18 @@
 
 			btScalar previousSquaredDistance = squaredDistance;
-			squaredDistance = m_cachedSeparatingAxis.length2();
+			squaredDistance = newCachedSeparatingAxis.length2();
+#if 0
+///warning: this termination condition leads to some problems in 2d test case see Bullet/Demos/Box2dDemo
+			if (squaredDistance>previousSquaredDistance)
+			{
+				m_degenerateSimplex = 7;
+				squaredDistance = previousSquaredDistance;
+                checkSimplex = false;
+                break;
+			}
+#endif //
 			
+			m_cachedSeparatingAxis = newCachedSeparatingAxis;
+
 			//redundant m_simplexSolver->compute_points(pointOnA, pointOnB);
 
@@ -210,4 +264,6 @@
 				m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
 				checkSimplex = true;
+				m_degenerateSimplex = 12;
+				
 				break;
 			}
@@ -240,4 +296,5 @@
 				//do we need this backup_closest here ?
 				m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
+				m_degenerateSimplex = 13;
 				break;
 			}
@@ -248,5 +305,6 @@
 			m_simplexSolver->compute_points(pointOnA, pointOnB);
 			normalInB = pointOnA-pointOnB;
-			btScalar lenSqr = m_cachedSeparatingAxis.length2();
+			btScalar lenSqr =m_cachedSeparatingAxis.length2();
+			
 			//valid normal
 			if (lenSqr < 0.0001)
@@ -280,5 +338,5 @@
 		{
 			//penetration case
-		
+
 			//if there is no way to handle penetrations, bail out
 			if (m_penetrationDepthSolver)
@@ -288,4 +346,5 @@
 				
 				gNumDeepPenetrationChecks++;
+				m_cachedSeparatingAxis.setZero();
 
 				bool isValid2 = m_penetrationDepthSolver->calcPenDepth( 
@@ -297,8 +356,15 @@
 					);
 
+
 				if (isValid2)
 				{
 					btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA;
 					btScalar lenSqr = tmpNormalInB.length2();
+					if (lenSqr <= (SIMD_EPSILON*SIMD_EPSILON))
+					{
+						tmpNormalInB = m_cachedSeparatingAxis;
+						lenSqr = m_cachedSeparatingAxis.length2();
+					}
+
 					if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
 					{
@@ -316,30 +382,60 @@
 						} else
 						{
-							
+							m_lastUsedMethod = 8;
 						}
 					} else
 					{
-						//isValid = false;
-						m_lastUsedMethod = 4;
+						m_lastUsedMethod = 9;
 					}
 				} else
+
 				{
-					m_lastUsedMethod = 5;
+					///this is another degenerate case, where the initial GJK calculation reports a degenerate case
+					///EPA reports no penetration, and the second GJK (using the supporting vector without margin)
+					///reports a valid positive distance. Use the results of the second GJK instead of failing.
+					///thanks to Jacob.Langford for the reproduction case
+					///http://code.google.com/p/bullet/issues/detail?id=250
+
+				
+					if (m_cachedSeparatingAxis.length2() > btScalar(0.))
+					{
+						btScalar distance2 = (tmpPointOnA-tmpPointOnB).length()-margin;
+						//only replace valid distances when the distance is less
+						if (!isValid || (distance2 < distance))
+						{
+							distance = distance2;
+							pointOnA = tmpPointOnA;
+							pointOnB = tmpPointOnB;
+							pointOnA -= m_cachedSeparatingAxis * marginA ;
+							pointOnB += m_cachedSeparatingAxis * marginB ;
+							normalInB = m_cachedSeparatingAxis;
+							normalInB.normalize();
+							isValid = true;
+							m_lastUsedMethod = 6;
+						} else
+						{
+							m_lastUsedMethod = 5;
+						}
+					}
 				}
 				
 			}
+
 		}
 	}
 
-	if (isValid)
+	
+
+	if (isValid && ((distance < 0) || (distance*distance < input.m_maximumDistanceSquared)))
 	{
-#ifdef __SPU__
-		//spu_printf("distance\n");
-#endif //__CELLOS_LV2__
-
-
-#ifdef DEBUG_SPU_COLLISION_DETECTION
-		spu_printf("output 1\n");
-#endif
+#if 0
+///some debugging
+//		if (check2d)
+		{
+			printf("n = %2.3f,%2.3f,%2.3f. ",normalInB[0],normalInB[1],normalInB[2]);
+			printf("distance = %2.3f exit=%d deg=%d\n",distance,m_lastUsedMethod,m_degenerateSimplex);
+		}
+#endif 
+
 		m_cachedSeparatingAxis = normalInB;
 		m_cachedSeparatingDistance = distance;
@@ -350,8 +446,4 @@
 			distance);
 
-#ifdef DEBUG_SPU_COLLISION_DETECTION
-		spu_printf("output 2\n");
-#endif
-		//printf("gjk add:%f",distance);
 	}
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h	(revision 8284)
@@ -37,4 +37,9 @@
 	const btConvexShape* m_minkowskiA;
 	const btConvexShape* m_minkowskiB;
+	int	m_shapeTypeA;
+	int m_shapeTypeB;
+	btScalar	m_marginA;
+	btScalar	m_marginB;
+
 	bool		m_ignoreMargin;
 	btScalar	m_cachedSeparatingDistance;
@@ -51,7 +56,11 @@
 
 	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);
 	virtual ~btGjkPairDetector() {};
 
 	virtual void	getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
+
+	void	getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw);
+	
 
 	void setMinkowskiA(btConvexShape* minkA)
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h	(revision 8284)
@@ -20,4 +20,13 @@
 #include "LinearMath/btTransformUtil.h"
 
+// Don't change following order of parameters
+ATTRIBUTE_ALIGNED16(struct) PfxConstraintRow {
+	btScalar mNormal[3];
+	btScalar mRhs;
+	btScalar mJacDiagInv;
+	btScalar mLowerLimit;
+	btScalar mUpperLimit;
+	btScalar mAccumImpulse;
+};
 
 
@@ -35,4 +44,8 @@
 				m_appliedImpulseLateral1(0.f),
 				m_appliedImpulseLateral2(0.f),
+				m_contactMotion1(0.f),
+				m_contactMotion2(0.f),
+				m_contactCFM1(0.f),
+				m_contactCFM2(0.f),
 				m_lifeTime(0)
 			{
@@ -53,8 +66,13 @@
 					m_appliedImpulseLateral1(0.f),
 					m_appliedImpulseLateral2(0.f),
+					m_contactMotion1(0.f),
+					m_contactMotion2(0.f),
+					m_contactCFM1(0.f),
+					m_contactCFM2(0.f),
 					m_lifeTime(0)
 			{
-				
-					
+				mConstraintRow[0].mAccumImpulse = 0.f;
+				mConstraintRow[1].mAccumImpulse = 0.f;
+				mConstraintRow[2].mAccumImpulse = 0.f;
 			}
 
@@ -84,8 +102,18 @@
 			btScalar		m_appliedImpulseLateral1;
 			btScalar		m_appliedImpulseLateral2;
+			btScalar		m_contactMotion1;
+			btScalar		m_contactMotion2;
+			btScalar		m_contactCFM1;
+			btScalar		m_contactCFM2;
+
 			int				m_lifeTime;//lifetime of the contactpoint in frames
 			
 			btVector3		m_lateralFrictionDir1;
 			btVector3		m_lateralFrictionDir2;
+
+
+
+			PfxConstraintRow mConstraintRow[3];
+
 
 			btScalar getDistance() const
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp	(revision 8284)
@@ -21,49 +21,4 @@
 
 #define NUM_UNITSPHERE_POINTS 42
-static btVector3	sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = 
-{
-btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)),
-btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)),
-btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)),
-btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)),
-btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)),
-btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)),
-btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)),
-btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)),
-btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)),
-btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)),
-btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)),
-btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)),
-btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)),
-btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)),
-btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)),
-btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)),
-btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)),
-btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)),
-btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)),
-btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)),
-btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)),
-btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)),
-btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)),
-btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)),
-btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)),
-btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)),
-btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)),
-btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)),
-btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)),
-btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)),
-btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)),
-btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)),
-btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)),
-btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)),
-btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)),
-btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)),
-btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)),
-btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)),
-btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)),
-btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)),
-btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)),
-btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
-};
 
 
@@ -79,4 +34,5 @@
 	(void)v;
 	
+	bool check2d= convexA->isConvex2d() && convexB->isConvex2d();
 
 	struct btIntermediateResult : public btDiscreteCollisionDetectorInterface::Result
@@ -92,8 +48,11 @@
 		bool	m_hasResult;
 
-		virtual void setShapeIdentifiers(int partId0,int index0,	int partId1,int index1)
+		virtual void setShapeIdentifiersA(int partId0,int index0)
 		{
 			(void)partId0;
 			(void)index0;
+		}
+		virtual void setShapeIdentifiersB(int partId1,int index1)
+		{
 			(void)partId1;
 			(void)index1;
@@ -109,5 +68,5 @@
 
 	//just take fixed number of orientation, and sample the penetration depth in that direction
-	btScalar minProj = btScalar(1e30);
+	btScalar minProj = btScalar(BT_LARGE_FLOAT);
 	btVector3 minNorm(btScalar(0.), btScalar(0.), btScalar(0.));
 	btVector3 minA,minB;
@@ -130,5 +89,5 @@
 	for (i=0;i<numSampleDirections;i++)
 	{
-		const btVector3& norm = sPenetrationDirections[i];
+		btVector3 norm = getPenetrationDirections()[i];
 		seperatingAxisInABatch[i] =  (-norm) * transA.getBasis() ;
 		seperatingAxisInBBatch[i] =  norm   * transB.getBasis() ;
@@ -144,5 +103,5 @@
 				convexA->getPreferredPenetrationDirection(i,norm);
 				norm  = transA.getBasis() * norm;
-				sPenetrationDirections[numSampleDirections] = norm;
+				getPenetrationDirections()[numSampleDirections] = norm;
 				seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis();
 				seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis();
@@ -161,5 +120,5 @@
 				convexB->getPreferredPenetrationDirection(i,norm);
 				norm  = transB.getBasis() * norm;
-				sPenetrationDirections[numSampleDirections] = norm;
+				getPenetrationDirections()[numSampleDirections] = norm;
 				seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis();
 				seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis();
@@ -171,4 +130,5 @@
 
 
+
 	convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch,supportVerticesABatch,numSampleDirections);
 	convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch,supportVerticesBBatch,numSampleDirections);
@@ -176,22 +136,36 @@
 	for (i=0;i<numSampleDirections;i++)
 	{
-		const btVector3& norm = sPenetrationDirections[i];
-		seperatingAxisInA = seperatingAxisInABatch[i];
-		seperatingAxisInB = seperatingAxisInBBatch[i];
-
-		pInA = supportVerticesABatch[i];
-		qInB = supportVerticesBBatch[i];
-
-		pWorld = transA(pInA);	
-		qWorld = transB(qInB);
-		w	= qWorld - pWorld;
-		btScalar delta = norm.dot(w);
-		//find smallest delta
-		if (delta < minProj)
-		{
-			minProj = delta;
-			minNorm = norm;
-			minA = pWorld;
-			minB = qWorld;
+		btVector3 norm = getPenetrationDirections()[i];
+		if (check2d)
+		{
+			norm[2] = 0.f;
+		}
+		if (norm.length2()>0.01)
+		{
+
+			seperatingAxisInA = seperatingAxisInABatch[i];
+			seperatingAxisInB = seperatingAxisInBBatch[i];
+
+			pInA = supportVerticesABatch[i];
+			qInB = supportVerticesBBatch[i];
+
+			pWorld = transA(pInA);	
+			qWorld = transB(qInB);
+			if (check2d)
+			{
+				pWorld[2] = 0.f;
+				qWorld[2] = 0.f;
+			}
+
+			w	= qWorld - pWorld;
+			btScalar delta = norm.dot(w);
+			//find smallest delta
+			if (delta < minProj)
+			{
+				minProj = delta;
+				minNorm = norm;
+				minA = pWorld;
+				minB = qWorld;
+			}
 		}
 	}	
@@ -210,5 +184,5 @@
 				convexA->getPreferredPenetrationDirection(i,norm);
 				norm  = transA.getBasis() * norm;
-				sPenetrationDirections[numSampleDirections] = norm;
+				getPenetrationDirections()[numSampleDirections] = norm;
 				numSampleDirections++;
 			}
@@ -225,5 +199,5 @@
 				convexB->getPreferredPenetrationDirection(i,norm);
 				norm  = transB.getBasis() * norm;
-				sPenetrationDirections[numSampleDirections] = norm;
+				getPenetrationDirections()[numSampleDirections] = norm;
 				numSampleDirections++;
 			}
@@ -234,5 +208,5 @@
 	for (int i=0;i<numSampleDirections;i++)
 	{
-		const btVector3& norm = sPenetrationDirections[i];
+		const btVector3& norm = getPenetrationDirections()[i];
 		seperatingAxisInA = (-norm)* transA.getBasis();
 		seperatingAxisInB = norm* transB.getBasis();
@@ -262,5 +236,6 @@
 		return false;
 
-	minProj += (convexA->getMarginNonVirtual() + convexB->getMarginNonVirtual());
+	btScalar extraSeparation = 0.5f;///scale dependent
+	minProj += extraSeparation+(convexA->getMarginNonVirtual() + convexB->getMarginNonVirtual());
 
 
@@ -300,7 +275,8 @@
 	input.m_transformA = displacedTrans;
 	input.m_transformB = transB;
-	input.m_maximumDistanceSquared = btScalar(1e30);//minProj;
+	input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);//minProj;
 	
 	btIntermediateResult res;
+	gjkdet.setCachedSeperatingAxis(-minNorm);
 	gjkdet.getClosestPoints(input,res,debugDraw);
 
@@ -311,4 +287,5 @@
 	btScalar penetration_relaxation= btScalar(1.);
 	minNorm*=penetration_relaxation;
+	
 
 	if (res.m_hasResult)
@@ -317,4 +294,5 @@
 		pa = res.m_pointInWorld - minNorm * correctedMinNorm;
 		pb = res.m_pointInWorld;
+		v = minNorm;
 		
 #ifdef DEBUG_DRAW
@@ -331,4 +309,54 @@
 }
 
-
-
+btVector3*	btMinkowskiPenetrationDepthSolver::getPenetrationDirections()
+{
+	static btVector3	sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = 
+	{
+	btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)),
+	btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)),
+	btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)),
+	btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)),
+	btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)),
+	btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)),
+	btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)),
+	btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)),
+	btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)),
+	btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)),
+	btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)),
+	btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)),
+	btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)),
+	btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)),
+	btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)),
+	btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)),
+	btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)),
+	btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)),
+	btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)),
+	btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)),
+	btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)),
+	btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)),
+	btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)),
+	btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)),
+	btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)),
+	btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)),
+	btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)),
+	btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)),
+	btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)),
+	btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)),
+	btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)),
+	btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)),
+	btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)),
+	btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)),
+	btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)),
+	btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)),
+	btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)),
+	btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)),
+	btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)),
+	btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)),
+	btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)),
+	btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
+	};
+
+	return sPenetrationDirections;
+}
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h	(revision 8284)
@@ -23,4 +23,8 @@
 class btMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver
 {
+protected:
+
+	static btVector3*	getPenetrationDirections();
+
 public:
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp	(revision 8284)
@@ -26,5 +26,6 @@
 
 btPersistentManifold::btPersistentManifold()
-:m_body0(0),
+:btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
+m_body0(0),
 m_body1(0),
 m_cachedPoints (0),
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h	(revision 8284)
@@ -31,7 +31,12 @@
 typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1);
 extern ContactDestroyedCallback	gContactDestroyedCallback;
-
-
-
+extern ContactProcessedCallback gContactProcessedCallback;
+
+
+enum btContactManifoldTypes
+{
+	BT_PERSISTENT_MANIFOLD_TYPE = 1,
+	MAX_CONTACT_MANIFOLD_TYPE
+};
 
 #define MANIFOLD_CACHE_SIZE 4
@@ -44,5 +49,8 @@
 ///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points
 ///note that some pairs of objects might have more then one contact manifold.
-ATTRIBUTE_ALIGNED16( class) btPersistentManifold 
+
+
+ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject
+//ATTRIBUTE_ALIGNED16( class) btPersistentManifold : public btTypedObject
 {
 
@@ -53,4 +61,5 @@
 	void* m_body0;
 	void* m_body1;
+
 	int	m_cachedPoints;
 
@@ -68,4 +77,7 @@
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 
+	int	m_companionIdA;
+	int	m_companionIdB;
+
 	int m_index1a;
 
@@ -73,9 +85,9 @@
 
 	btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
-		: m_body0(body0),m_body1(body1),m_cachedPoints(0),
+		: btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
+	m_body0(body0),m_body1(body1),m_cachedPoints(0),
 		m_contactBreakingThreshold(contactBreakingThreshold),
 		m_contactProcessingThreshold(contactProcessingThreshold)
 	{
-		
 	}
 
@@ -135,4 +147,8 @@
 			//get rid of duplicated userPersistentData pointer
 			m_pointCache[lastUsedIndex].m_userPersistentData = 0;
+			m_pointCache[lastUsedIndex].mConstraintRow[0].mAccumImpulse = 0.f;
+			m_pointCache[lastUsedIndex].mConstraintRow[1].mAccumImpulse = 0.f;
+			m_pointCache[lastUsedIndex].mConstraintRow[2].mAccumImpulse = 0.f;
+
 			m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
 			m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false;
@@ -152,8 +168,11 @@
 #ifdef MAINTAIN_PERSISTENCY
 		int	lifeTime = m_pointCache[insertIndex].getLifeTime();
-		btScalar	appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
-		btScalar	appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
-		btScalar	appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
-				
+		btScalar	appliedImpulse = m_pointCache[insertIndex].mConstraintRow[0].mAccumImpulse;
+		btScalar	appliedLateralImpulse1 = m_pointCache[insertIndex].mConstraintRow[1].mAccumImpulse;
+		btScalar	appliedLateralImpulse2 = m_pointCache[insertIndex].mConstraintRow[2].mAccumImpulse;
+//		bool isLateralFrictionInitialized = m_pointCache[insertIndex].m_lateralFrictionInitialized;
+		
+		
+			
 		btAssert(lifeTime>=0);
 		void* cache = m_pointCache[insertIndex].m_userPersistentData;
@@ -166,4 +185,9 @@
 		m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
 		
+		m_pointCache[insertIndex].mConstraintRow[0].mAccumImpulse =  appliedImpulse;
+		m_pointCache[insertIndex].mConstraintRow[1].mAccumImpulse = appliedLateralImpulse1;
+		m_pointCache[insertIndex].mConstraintRow[2].mAccumImpulse = appliedLateralImpulse2;
+
+
 		m_pointCache[insertIndex].m_lifeTime = lifeTime;
 #else
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPointCollector.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPointCollector.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPointCollector.h	(revision 8284)
@@ -32,15 +32,18 @@
 
 	btPointCollector () 
-		: m_distance(btScalar(1e30)),m_hasResult(false)
+		: m_distance(btScalar(BT_LARGE_FLOAT)),m_hasResult(false)
 	{
 	}
 
-	virtual void setShapeIdentifiers(int partId0,int index0,	int partId1,int index1)
+	virtual void setShapeIdentifiersA(int partId0,int index0)
 	{
 		(void)partId0;
 		(void)index0;
+			
+	}
+	virtual void setShapeIdentifiersB(int partId1,int index1)
+	{
 		(void)partId1;
 		(void)index1;
-		//??
 	}
 
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp	(revision 8284)
@@ -115,5 +115,8 @@
 			}
 		} 
-		m_simplexSolver->addVertex( w, supVertexA , supVertexB);
+		///Just like regular GJK only add the vertex if it isn't already (close) to current vertex, it would lead to divisions by zero and NaN etc.
+		if (!m_simplexSolver->inSimplex(w))
+			m_simplexSolver->addVertex( w, supVertexA , supVertexB);
+
 		if (m_simplexSolver->closest(v))
 		{
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp	(revision 8284)
@@ -69,5 +69,5 @@
 	m_numVertices = 0;
 	m_needsUpdate = true;
-	m_lastW = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	m_lastW = btVector3(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
 	m_cachedBC.reset();
 }
@@ -290,5 +290,9 @@
 	for (i=0;i<numverts;i++)
 	{
+#ifdef BT_USE_EQUAL_VERTEX_THRESHOLD
+		if ( m_simplexVectorW[i].distance2(w) <= m_equalVertexThreshold)
+#else
 		if (m_simplexVectorW[i] == w)
+#endif
 			found = true;
 	}
Index: /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h	(revision 8284)
@@ -24,4 +24,9 @@
 
 #define VORONOI_SIMPLEX_MAX_VERTS 5
+
+///disable next define, or use defaultCollisionConfiguration->getSimplexSolver()->setEqualVertexThreshold(0.f) to disable/configure
+#define BT_USE_EQUAL_VERTEX_THRESHOLD
+#define VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD 0.0001f
+
 
 struct btUsageBitfield{
@@ -107,5 +112,8 @@
 	btVector3	m_cachedV;
 	btVector3	m_lastW;
+	
+	btScalar	m_equalVertexThreshold;
 	bool		m_cachedValidClosest;
+
 
 	btSubSimplexClosestResult m_cachedBC;
@@ -123,8 +131,21 @@
 public:
 
+	btVoronoiSimplexSolver()
+		:  m_equalVertexThreshold(VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD)
+	{
+	}
 	 void reset();
 
 	 void addVertex(const btVector3& w, const btVector3& p, const btVector3& q);
 
+	 void	setEqualVertexThreshold(btScalar threshold)
+	 {
+		 m_equalVertexThreshold = threshold;
+	 }
+
+	 btScalar	getEqualVertexThreshold() const
+	 {
+		 return m_equalVertexThreshold;
+	 }
 
 	 bool closest(btVector3& v);
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/CMakeLists.txt	(revision 8284)
@@ -3,7 +3,11 @@
 COMPILATION_BEGIN BulletDynamicsCompilation.cpp
 
+	Character/btKinematicCharacterController.cpp
+
+	ConstraintSolver/btConeTwistConstraint.cpp
 	ConstraintSolver/btContactConstraint.cpp
-	ConstraintSolver/btConeTwistConstraint.cpp
 	ConstraintSolver/btGeneric6DofConstraint.cpp
+	ConstraintSolver/btGeneric6DofSpringConstraint.cpp
+	ConstraintSolver/btHinge2Constraint.cpp
 	ConstraintSolver/btHingeConstraint.cpp
 	ConstraintSolver/btPoint2PointConstraint.cpp
@@ -12,23 +16,24 @@
 	ConstraintSolver/btSolve2LinearConstraint.cpp
 	ConstraintSolver/btTypedConstraint.cpp
+	ConstraintSolver/btUniversalConstraint.cpp
 
+	Dynamics/btContinuousDynamicsWorld.cpp
+	Dynamics/btDiscreteDynamicsWorld.cpp
+	Dynamics/btRigidBody.cpp
+	Dynamics/btSimpleDynamicsWorld.cpp
 	Dynamics/Bullet-C-API.cpp
-	Dynamics/btDiscreteDynamicsWorld.cpp
-	Dynamics/btSimpleDynamicsWorld.cpp
-	Dynamics/btRigidBody.cpp
-
 	Vehicle/btRaycastVehicle.cpp
 	Vehicle/btWheelInfo.cpp
-
-	Character/btKinematicCharacterController.cpp
 
 COMPILATION_END
 
 	# Headers
+	ConstraintSolver/btConeTwistConstraint.h
 	ConstraintSolver/btConstraintSolver.h
 	ConstraintSolver/btContactConstraint.h
 	ConstraintSolver/btContactSolverInfo.h
-	ConstraintSolver/btConeTwistConstraint.h
 	ConstraintSolver/btGeneric6DofConstraint.h
+	ConstraintSolver/btGeneric6DofSpringConstraint.h
+	ConstraintSolver/btHinge2Constraint.h
 	ConstraintSolver/btHingeConstraint.h
 	ConstraintSolver/btJacobianEntry.h
@@ -40,5 +45,5 @@
 	ConstraintSolver/btSolverConstraint.h
 	ConstraintSolver/btTypedConstraint.h
-
+	ConstraintSolver/btUniversalConstraint.h
 	Dynamics/btActionInterface.h
 	Dynamics/btContinuousDynamicsWorld.h
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btCharacterControllerInterface.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btCharacterControllerInterface.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btCharacterControllerInterface.h	(revision 8284)
@@ -31,4 +31,5 @@
 	
 	virtual void	setWalkDirection(const btVector3& walkDirection) = 0;
+	virtual void	setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0;
 	virtual void	reset () = 0;
 	virtual void	warp (const btVector3& origin) = 0;
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp	(revision 8284)
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 
 #include "LinearMath/btIDebugDraw.h"
@@ -23,5 +24,16 @@
 #include "btKinematicCharacterController.h"
 
-static btVector3 upAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) };
+
+// static helper method
+static btVector3
+getNormalizedVector(const btVector3& v)
+{
+	btVector3 n = v.normalized();
+	if (n.length() < SIMD_EPSILON) {
+		n.setValue(0, 0, 0);
+	}
+	return n;
+}
+
 
 ///@todo Interact with dynamic objects,
@@ -53,7 +65,10 @@
 {
 public:
-	btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
-	{
-		m_me = me;
+	btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me, const btVector3& up, btScalar minSlopeDot)
+	: btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
+	, m_me(me)
+	, m_up(up)
+	, m_minSlopeDot(minSlopeDot)
+	{
 	}
 
@@ -61,5 +76,20 @@
 	{
 		if (convexResult.m_hitCollisionObject == m_me)
-			return 1.0;
+			return btScalar(1.0);
+
+		btVector3 hitNormalWorld;
+		if (normalInWorldSpace)
+		{
+			hitNormalWorld = convexResult.m_hitNormalLocal;
+		} else
+		{
+			///need to transform normal into worldspace
+			hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
+		}
+
+		btScalar dotUp = m_up.dot(hitNormalWorld);
+		if (dotUp < m_minSlopeDot) {
+			return btScalar(1.0);
+		}
 
 		return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
@@ -67,4 +97,6 @@
 protected:
 	btCollisionObject* m_me;
+	const btVector3 m_up;
+	btScalar m_minSlopeDot;
 };
 
@@ -99,5 +131,5 @@
 {
 	m_upAxis = upAxis;
-	m_addedMargin = 0.02f;
+	m_addedMargin = 0.02;
 	m_walkDirection.setValue(0,0,0);
 	m_useGhostObjectSweepTest = true;
@@ -106,4 +138,14 @@
 	m_turnAngle = btScalar(0.0);
 	m_convexShape=convexShape;	
+	m_useWalkDirection = true;	// use walk direction by default, legacy behavior
+	m_velocityTimeInterval = 0.0;
+	m_verticalVelocity = 0.0;
+	m_verticalOffset = 0.0;
+	m_gravity = 9.8 * 3 ; // 3G acceleration.
+	m_fallSpeed = 55.0; // Terminal velocity of a sky diver in m/s.
+	m_jumpSpeed = 10.0; // ?
+	m_wasOnGround = false;
+	m_wasJumping = false;
+	setMaxSlope(btRadians(45.0));
 }
 
@@ -145,16 +187,18 @@
 				const btManifoldPoint&pt = manifold->getContactPoint(p);
 
-				if (pt.getDistance() < 0.0)
+				btScalar dist = pt.getDistance();
+
+				if (dist < 0.0)
 				{
-					if (pt.getDistance() < maxPen)
+					if (dist < maxPen)
 					{
-						maxPen = pt.getDistance();
+						maxPen = dist;
 						m_touchingNormal = pt.m_normalWorldOnB * directionSign;//??
 
 					}
-					m_currentPosition += pt.m_normalWorldOnB * directionSign * pt.getDistance() * btScalar(0.2);
+					m_currentPosition += pt.m_normalWorldOnB * directionSign * dist * btScalar(0.2);
 					penetration = true;
 				} else {
-					//printf("touching %f\n", pt.getDistance());
+					//printf("touching %f\n", dist);
 				}
 			}
@@ -174,5 +218,5 @@
 	// phase 1: up
 	btTransform start, end;
-	m_targetPosition = m_currentPosition + upAxisDirection[m_upAxis] * m_stepHeight;
+	m_targetPosition = m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0.f?m_verticalOffset:0.f));
 
 	start.setIdentity ();
@@ -180,8 +224,8 @@
 
 	/* FIXME: Handle penetration properly */
-	start.setOrigin (m_currentPosition + upAxisDirection[m_upAxis] * btScalar(0.1f));
+	start.setOrigin (m_currentPosition + getUpAxisDirections()[m_upAxis] * (m_convexShape->getMargin() + m_addedMargin));
 	end.setOrigin (m_targetPosition);
 
-	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, -getUpAxisDirections()[m_upAxis], btScalar(0.7071));
 	callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
 	callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
@@ -198,7 +242,13 @@
 	if (callback.hasHit())
 	{
-		// 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);
+		// Only modify the position if the hit was a slope and not a wall or ceiling.
+		if(callback.m_hitNormalWorld.dot(getUpAxisDirections()[m_upAxis]) > 0.0)
+		{
+			// 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);
+		}
+		m_verticalVelocity = 0.0;
+		m_verticalOffset = 0.0;
 	} else {
 		m_currentStepOffset = m_stepHeight;
@@ -245,14 +295,10 @@
 void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove)
 {
-
-	btVector3 originalDir = walkMove.normalized();
-	if (walkMove.length() < SIMD_EPSILON)
-	{
-		originalDir.setValue(0.f,0.f,0.f);
-	}
-//	printf("originalDir=%f,%f,%f\n",originalDir[0],originalDir[1],originalDir[2]);
+	// printf("m_normalizedDirection=%f,%f,%f\n",
+	// 	m_normalizedDirection[0],m_normalizedDirection[1],m_normalizedDirection[2]);
 	// phase 2: forward and strafe
 	btTransform start, end;
 	m_targetPosition = m_currentPosition + walkMove;
+
 	start.setIdentity ();
 	end.setIdentity ();
@@ -264,6 +310,8 @@
 	if (m_touchingContact)
 	{
-		if (originalDir.dot(m_touchingNormal) > btScalar(0.0))
+		if (m_normalizedDirection.dot(m_touchingNormal) > btScalar(0.0))
+		{
 			updateTargetPositionBasedOnCollision (m_touchingNormal);
+		}
 	}
 
@@ -274,6 +322,7 @@
 		start.setOrigin (m_currentPosition);
 		end.setOrigin (m_targetPosition);
-
-		btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+		btVector3 sweepDirNegative(m_currentPosition - m_targetPosition);
+
+		btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, sweepDirNegative, btScalar(0.0));
 		callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
 		callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
@@ -300,16 +349,8 @@
 		{	
 			// we moved only a fraction
-			btScalar hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
-			if (hitDistance<0.f)
-			{
-//				printf("neg dist?\n");
-			}
-
-			/* If the distance is farther than the collision margin, move */
-			if (hitDistance > m_addedMargin)
-			{
-//				printf("callback.m_closestHitFraction=%f\n",callback.m_closestHitFraction);
-				m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
-			}
+			btScalar hitDistance;
+			hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
+
+//			m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
 
 			updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld);
@@ -320,5 +361,5 @@
 				currentDir.normalize();
 				/* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
-				if (currentDir.dot(originalDir) <= btScalar(0.0))
+				if (currentDir.dot(m_normalizedDirection) <= btScalar(0.0))
 				{
 					break;
@@ -329,4 +370,5 @@
 				break;
 			}
+
 		} else {
 			// we moved whole way
@@ -345,7 +387,19 @@
 
 	// phase 3: down
-	btVector3 step_drop = upAxisDirection[m_upAxis] * m_currentStepOffset;
-	btVector3 gravity_drop = upAxisDirection[m_upAxis] * m_stepHeight; 
-	m_targetPosition -= (step_drop + gravity_drop);
+	/*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
+	btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + additionalDownStep);
+	btScalar downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt;
+	btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity; 
+	m_targetPosition -= (step_drop + gravity_drop);*/
+
+	btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt;
+	if(downVelocity > 0.0 && downVelocity < m_stepHeight
+		&& (m_wasOnGround || !m_wasJumping))
+	{
+		downVelocity = m_stepHeight;
+	}
+
+	btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + downVelocity);
+	m_targetPosition -= step_drop;
 
 	start.setIdentity ();
@@ -355,5 +409,5 @@
 	end.setOrigin (m_targetPosition);
 
-	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, getUpAxisDirections()[m_upAxis], m_maxSlopeCosine);
 	callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
 	callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
@@ -371,4 +425,7 @@
 		// we dropped a fraction of the height -> hit floor
 		m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
+		m_verticalVelocity = 0.0;
+		m_verticalOffset = 0.0;
+		m_wasJumping = false;
 	} else {
 		// we dropped the full height
@@ -378,4 +435,37 @@
 }
 
+
+
+void btKinematicCharacterController::setWalkDirection
+(
+const btVector3& walkDirection
+)
+{
+	m_useWalkDirection = true;
+	m_walkDirection = walkDirection;
+	m_normalizedDirection = getNormalizedVector(m_walkDirection);
+}
+
+
+
+void btKinematicCharacterController::setVelocityForTimeInterval
+(
+const btVector3& velocity,
+btScalar timeInterval
+)
+{
+//	printf("setVelocity!\n");
+//	printf("  interval: %f\n", timeInterval);
+//	printf("  velocity: (%f, %f, %f)\n",
+//		 velocity.x(), velocity.y(), velocity.z());
+
+	m_useWalkDirection = false;
+	m_walkDirection = velocity;
+	m_normalizedDirection = getNormalizedVector(m_walkDirection);
+	m_velocityTimeInterval = timeInterval;
+}
+
+
+
 void btKinematicCharacterController::reset ()
 {
@@ -402,5 +492,5 @@
 		if (numPenetrationLoops > 4)
 		{
-//			printf("character could not recover from penetration = %d\n", numPenetrationLoops);
+			//printf("character could not recover from penetration = %d\n", numPenetrationLoops);
 			break;
 		}
@@ -414,6 +504,32 @@
 }
 
+#include <stdio.h>
+
 void btKinematicCharacterController::playerStep (  btCollisionWorld* collisionWorld, btScalar dt)
 {
+//	printf("playerStep(): ");
+//	printf("  dt = %f", dt);
+
+	// quick check...
+	if (!m_useWalkDirection && m_velocityTimeInterval <= 0.0) {
+//		printf("\n");
+		return;		// no motion
+	}
+
+	m_wasOnGround = onGround();
+
+	// Update fall velocity.
+	m_verticalVelocity -= m_gravity * dt;
+	if(m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed)
+	{
+		m_verticalVelocity = m_jumpSpeed;
+	}
+	if(m_verticalVelocity < 0.0 && btFabs(m_verticalVelocity) > btFabs(m_fallSpeed))
+	{
+		m_verticalVelocity = -btFabs(m_fallSpeed);
+	}
+	m_verticalOffset = m_verticalVelocity * dt;
+
+
 	btTransform xform;
 	xform = m_ghostObject->getWorldTransform ();
@@ -423,6 +539,24 @@
 
 	stepUp (collisionWorld);
-	stepForwardAndStrafe (collisionWorld, m_walkDirection);
+	if (m_useWalkDirection) {
+		stepForwardAndStrafe (collisionWorld, m_walkDirection);
+	} else {
+		//printf("  time: %f", m_velocityTimeInterval);
+		// still have some time left for moving!
+		btScalar dtMoving =
+			(dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval;
+		m_velocityTimeInterval -= dt;
+
+		// how far will we move while we are moving?
+		btVector3 move = m_walkDirection * dtMoving;
+
+		//printf("  dtMoving: %f", dtMoving);
+
+		// okay, step
+		stepForwardAndStrafe(collisionWorld, move);
+	}
 	stepDown (collisionWorld, dt);
+
+	// printf("\n");
 
 	xform.setOrigin (m_currentPosition);
@@ -454,4 +588,7 @@
 	if (!canJump())
 		return;
+
+	m_verticalVelocity = m_jumpSpeed;
+	m_wasJumping = true;
 
 #if 0
@@ -466,11 +603,39 @@
 }
 
+void btKinematicCharacterController::setGravity(btScalar gravity)
+{
+	m_gravity = gravity;
+}
+
+btScalar btKinematicCharacterController::getGravity() const
+{
+	return m_gravity;
+}
+
+void btKinematicCharacterController::setMaxSlope(btScalar slopeRadians)
+{
+	m_maxSlopeRadians = slopeRadians;
+	m_maxSlopeCosine = btCos(slopeRadians);
+}
+
+btScalar btKinematicCharacterController::getMaxSlope() const
+{
+	return m_maxSlopeRadians;
+}
+
 bool btKinematicCharacterController::onGround () const
 {
-	return true;
-}
-
-
-void	btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
-{
-}
+	return m_verticalVelocity == 0.0 && m_verticalOffset == 0.0;
+}
+
+
+btVector3* btKinematicCharacterController::getUpAxisDirections()
+{
+	static btVector3 sUpAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) };
+	
+	return sUpAxisDirection;
+}
+
+void btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
+{
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.h	(revision 8284)
@@ -14,4 +14,5 @@
 */
 
+
 #ifndef KINEMATIC_CHARACTER_CONTROLLER_H
 #define KINEMATIC_CHARACTER_CONTROLLER_H
@@ -20,4 +21,7 @@
 
 #include "btCharacterControllerInterface.h"
+
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+
 
 class btCollisionShape;
@@ -33,4 +37,5 @@
 {
 protected:
+
 	btScalar m_halfHeight;
 	
@@ -38,7 +43,12 @@
 	btConvexShape*	m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast
 	
+	btScalar m_verticalVelocity;
+	btScalar m_verticalOffset;
 	btScalar m_fallSpeed;
 	btScalar m_jumpSpeed;
 	btScalar m_maxJumpHeight;
+	btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value)
+	btScalar m_maxSlopeCosine;  // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization)
+	btScalar m_gravity;
 
 	btScalar m_turnAngle;
@@ -50,4 +60,5 @@
 	///this is the desired walk direction, set by the user
 	btVector3	m_walkDirection;
+	btVector3	m_normalizedDirection;
 
 	//some internal variables
@@ -62,8 +73,13 @@
 	btVector3 m_touchingNormal;
 
+	bool  m_wasOnGround;
+	bool  m_wasJumping;
 	bool	m_useGhostObjectSweepTest;
+	bool	m_useWalkDirection;
+	btScalar	m_velocityTimeInterval;
+	int m_upAxis;
 
-	int m_upAxis;
-	
+	static btVector3* getUpAxisDirections();
+
 	btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
 	btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
@@ -99,8 +115,18 @@
 	}
 
-	virtual void	setWalkDirection(const btVector3& walkDirection)
-	{
-		m_walkDirection = walkDirection;
-	}
+	/// This should probably be called setPositionIncrementPerSimulatorStep.
+	/// This is neither a direction nor a velocity, but the amount to
+	///	increment the position each simulation iteration, regardless
+	///	of dt.
+	/// This call will reset any velocity set by setVelocityForTimeInterval().
+	virtual void	setWalkDirection(const btVector3& walkDirection);
+
+	/// Caller provides a velocity with which the character should move for
+	///	the given time period.  After the time period, velocity is reset
+	///	to zero.
+	/// This call will reset any walk direction set by setWalkDirection().
+	/// Negative time intervals will result in no motion.
+	virtual void setVelocityForTimeInterval(const btVector3& velocity,
+				btScalar timeInterval);
 
 	void reset ();
@@ -114,5 +140,14 @@
 	void setMaxJumpHeight (btScalar maxJumpHeight);
 	bool canJump () const;
+
 	void jump ();
+
+	void setGravity(btScalar gravity);
+	btScalar getGravity() const;
+
+	/// The max slope determines the maximum angle that the controller can walk up.
+	/// The slope angle is measured in radians.
+	void setMaxSlope(btScalar slopeRadians);
+	btScalar getMaxSlope() const;
 
 	btPairCachingGhostObject* getGhostObject();
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp	(revision 8284)
@@ -23,16 +23,18 @@
 #include <new>
 
-//-----------------------------------------------------------------------------
-
+
+
+//#define CONETWIST_USE_OBSOLETE_SOLVER true
 #define CONETWIST_USE_OBSOLETE_SOLVER false
 #define CONETWIST_DEF_FIX_THRESH btScalar(.05f)
 
-//-----------------------------------------------------------------------------
-
-btConeTwistConstraint::btConeTwistConstraint()
-:btTypedConstraint(CONETWIST_CONSTRAINT_TYPE),
-m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER)
-{
-}
+
+SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis, const btMatrix3x3& invInertiaWorld)
+{
+	btVector3 vec = axis * invInertiaWorld;
+	return axis.dot(vec);
+}
+
+
 
 
@@ -64,11 +66,13 @@
 	m_maxMotorImpulse = btScalar(-1);
 
-	setLimit(btScalar(1e30), btScalar(1e30), btScalar(1e30));
+	setLimit(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT));
 	m_damping = btScalar(0.01);
 	m_fixThresh = CONETWIST_DEF_FIX_THRESH;
-}
-
-
-//-----------------------------------------------------------------------------
+	m_flags = 0;
+	m_linCFM = btScalar(0.f);
+	m_linERP = btScalar(0.7f);
+	m_angCFM = btScalar(0.f);
+}
+
 
 void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info)
@@ -83,5 +87,5 @@
 		info->m_numConstraintRows = 3;
 		info->nub = 3;
-		calcAngleInfo2();
+		calcAngleInfo2(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld());
 		if(m_solveSwingLimit)
 		{
@@ -100,21 +104,30 @@
 		}
 	}
-} // btConeTwistConstraint::getInfo1()
+}
+
+void btConeTwistConstraint::getInfo1NonVirtual (btConstraintInfo1* info)
+{
+	//always reserve 6 rows: object transform is not available on SPU
+	info->m_numConstraintRows = 6;
+	info->nub = 0;
+		
+}
 	
-//-----------------------------------------------------------------------------
 
 void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info)
 {
+	getInfo2NonVirtual(info,m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld());
+}
+
+void btConeTwistConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB)
+{
+	calcAngleInfo2(transA,transB,invInertiaWorldA,invInertiaWorldB);
+	
 	btAssert(!m_useSolveConstraintObsolete);
-	//retrieve matrices
-	btTransform body0_trans;
-	body0_trans = m_rbA.getCenterOfMassTransform();
-    btTransform body1_trans;
-	body1_trans = m_rbB.getCenterOfMassTransform();
     // set jacobian
     info->m_J1linearAxis[0] = 1;
     info->m_J1linearAxis[info->rowskip+1] = 1;
     info->m_J1linearAxis[2*info->rowskip+2] = 1;
-	btVector3 a1 = body0_trans.getBasis() * m_rbAFrame.getOrigin();
+	btVector3 a1 = transA.getBasis() * m_rbAFrame.getOrigin();
 	{
 		btVector3* angular0 = (btVector3*)(info->m_J1angularAxis);
@@ -124,5 +137,5 @@
 		a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
 	}
-	btVector3 a2 = body1_trans.getBasis() * m_rbBFrame.getOrigin();
+	btVector3 a2 = transB.getBasis() * m_rbBFrame.getOrigin();
 	{
 		btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
@@ -132,11 +145,16 @@
 	}
     // set right hand side
-    btScalar k = info->fps * info->erp;
+	btScalar linERP = (m_flags & BT_CONETWIST_FLAGS_LIN_ERP) ? m_linERP : info->erp;
+    btScalar k = info->fps * linERP;
     int j;
 	for (j=0; j<3; j++)
     {
-        info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]);
+        info->m_constraintError[j*info->rowskip] = k * (a2[j] + transB.getOrigin()[j] - a1[j] - transA.getOrigin()[j]);
 		info->m_lowerLimit[j*info->rowskip] = -SIMD_INFINITY;
 		info->m_upperLimit[j*info->rowskip] = SIMD_INFINITY;
+		if(m_flags & BT_CONETWIST_FLAGS_LIN_CFM)
+		{
+			info->cfm[j*info->rowskip] = m_linCFM;
+		}
     }
 	int row = 3;
@@ -150,5 +168,5 @@
 		if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh))
 		{
-			btTransform trA = m_rbA.getCenterOfMassTransform()*m_rbAFrame;
+			btTransform trA = transA*m_rbAFrame;
 			btVector3 p = trA.getBasis().getColumn(1);
 			btVector3 q = trA.getBasis().getColumn(2);
@@ -187,5 +205,8 @@
 
 			info->m_constraintError[srow] = k * m_swingCorrection;
-			info->cfm[srow] = 0.0f;
+			if(m_flags & BT_CONETWIST_FLAGS_ANG_CFM)
+			{
+				info->cfm[srow] = m_angCFM;
+			}
 			// m_swingCorrection is always positive or 0
 			info->m_lowerLimit[srow] = 0;
@@ -207,5 +228,8 @@
 		btScalar k = info->fps * m_biasFactor;
 		info->m_constraintError[srow] = k * m_twistCorrection;
-		info->cfm[srow] = 0.0f;
+		if(m_flags & BT_CONETWIST_FLAGS_ANG_CFM)
+		{
+			info->cfm[srow] = m_angCFM;
+		}
 		if(m_twistSpan > 0.0f)
 		{
@@ -231,5 +255,5 @@
 }
 	
-//-----------------------------------------------------------------------------
+
 
 void	btConeTwistConstraint::buildJacobian()
@@ -240,4 +264,5 @@
 		m_accTwistLimitImpulse = btScalar(0.);
 		m_accSwingLimitImpulse = btScalar(0.);
+		m_accMotorImpulse = btVector3(0.,0.,0.);
 
 		if (!m_angularOnly)
@@ -274,12 +299,13 @@
 		}
 
-		calcAngleInfo2();
-	}
-}
-
-//-----------------------------------------------------------------------------
-
-void	btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep)
-{
+		calcAngleInfo2(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld());
+	}
+}
+
+
+
+void	btConeTwistConstraint::solveConstraintObsolete(btRigidBody& bodyA,btRigidBody& bodyB,btScalar	timeStep)
+{
+	#ifndef __SPU__
 	if (m_useSolveConstraintObsolete)
 	{
@@ -296,7 +322,7 @@
 
 			btVector3 vel1;
-			bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
+			bodyA.internalGetVelocityInLocalPointObsolete(rel_pos1,vel1);
 			btVector3 vel2;
-			bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
+			bodyB.internalGetVelocityInLocalPointObsolete(rel_pos2,vel2);
 			btVector3 vel = vel1 - vel2;
 
@@ -315,6 +341,6 @@
 				btVector3 ftorqueAxis1 = rel_pos1.cross(normal);
 				btVector3 ftorqueAxis2 = rel_pos2.cross(normal);
-				bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse);
-				bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse);
+				bodyA.internalApplyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse);
+				bodyB.internalApplyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse);
 		
 			}
@@ -327,6 +353,6 @@
 			btTransform trACur = m_rbA.getCenterOfMassTransform();
 			btTransform trBCur = m_rbB.getCenterOfMassTransform();
-			btVector3 omegaA; bodyA.getAngularVelocity(omegaA);
-			btVector3 omegaB; bodyB.getAngularVelocity(omegaB);
+			btVector3 omegaA; bodyA.internalGetAngularVelocity(omegaA);
+			btVector3 omegaB; bodyB.internalGetAngularVelocity(omegaB);
 			btTransform trAPred; trAPred.setIdentity(); 
 			btVector3 zerovec(0,0,0);
@@ -402,13 +428,13 @@
 				btVector3 impulseAxis =  impulse / impulseMag;
 
-				bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag);
-				bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag);
-
-			}
-		}
-		else // no motor: do a little damping
-		{
-			const btVector3& angVelA = getRigidBodyA().getAngularVelocity();
-			const btVector3& angVelB = getRigidBodyB().getAngularVelocity();
+				bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag);
+				bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag);
+
+			}
+		}
+		else if (m_damping > SIMD_EPSILON) // no motor: do a little damping
+		{
+			btVector3 angVelA; bodyA.internalGetAngularVelocity(angVelA);
+			btVector3 angVelB; bodyB.internalGetAngularVelocity(angVelB);
 			btVector3 relVel = angVelB - angVelA;
 			if (relVel.length2() > SIMD_EPSILON)
@@ -422,6 +448,6 @@
 				btScalar  impulseMag  = impulse.length();
 				btVector3 impulseAxis = impulse / impulseMag;
-				bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag);
-				bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag);
+				bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag);
+				bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag);
 			}
 		}
@@ -431,7 +457,7 @@
 			///solve angular part
 			btVector3 angVelA;
-			bodyA.getAngularVelocity(angVelA);
+			bodyA.internalGetAngularVelocity(angVelA);
 			btVector3 angVelB;
-			bodyB.getAngularVelocity(angVelB);
+			bodyB.internalGetAngularVelocity(angVelB);
 
 			// solve swing limit
@@ -462,6 +488,6 @@
 				btVector3 noTwistSwingAxis = impulse / impulseMag;
 
-				bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*noTwistSwingAxis, impulseMag);
-				bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*noTwistSwingAxis, -impulseMag);
+				bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*noTwistSwingAxis, impulseMag);
+				bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*noTwistSwingAxis, -impulseMag);
 			}
 
@@ -483,13 +509,16 @@
 				btVector3 impulse = m_twistAxis * impulseMag;
 
-				bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*m_twistAxis,impulseMag);
-				bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*m_twistAxis,-impulseMag);
+				bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*m_twistAxis,impulseMag);
+				bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*m_twistAxis,-impulseMag);
 			}		
 		}
 	}
-
-}
-
-//-----------------------------------------------------------------------------
+#else
+btAssert(0);
+#endif //__SPU__
+}
+
+
+
 
 void	btConeTwistConstraint::updateRHS(btScalar	timeStep)
@@ -499,6 +528,6 @@
 }
 
-//-----------------------------------------------------------------------------
-
+
+#ifndef __SPU__
 void btConeTwistConstraint::calcAngleInfo()
 {
@@ -585,12 +614,12 @@
 		}
 	}
-} // btConeTwistConstraint::calcAngleInfo()
-
+}
+#endif //__SPU__
 
 static btVector3 vTwist(1,0,0); // twist axis in constraint's space
 
-//-----------------------------------------------------------------------------
-
-void btConeTwistConstraint::calcAngleInfo2()
+
+
+void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTransform& transB, const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB)
 {
 	m_swingCorrection = btScalar(0.);
@@ -598,11 +627,32 @@
 	m_solveTwistLimit = false;
 	m_solveSwingLimit = false;
+	// compute rotation of A wrt B (in constraint space)
+	if (m_bMotorEnabled && (!m_useSolveConstraintObsolete))
+	{	// it is assumed that setMotorTarget() was alredy called 
+		// and motor target m_qTarget is within constraint limits
+		// TODO : split rotation to pure swing and pure twist
+		// compute desired transforms in world
+		btTransform trPose(m_qTarget);
+		btTransform trA = transA * m_rbAFrame;
+		btTransform trB = transB * m_rbBFrame;
+		btTransform trDeltaAB = trB * trPose * trA.inverse();
+		btQuaternion qDeltaAB = trDeltaAB.getRotation();
+		btVector3 swingAxis = 	btVector3(qDeltaAB.x(), qDeltaAB.y(), qDeltaAB.z());
+		m_swingAxis = swingAxis;
+		m_swingAxis.normalize();
+		m_swingCorrection = qDeltaAB.getAngle();
+		if(!btFuzzyZero(m_swingCorrection))
+		{
+			m_solveSwingLimit = true;
+		}
+		return;
+	}
+
 
 	{
 		// compute rotation of A wrt B (in constraint space)
-		btQuaternion qA = getRigidBodyA().getCenterOfMassTransform().getRotation() * m_rbAFrame.getRotation();
-		btQuaternion qB = getRigidBodyB().getCenterOfMassTransform().getRotation() * m_rbBFrame.getRotation();
+		btQuaternion qA = transA.getRotation() * m_rbAFrame.getRotation();
+		btQuaternion qB = transB.getRotation() * m_rbBFrame.getRotation();
 		btQuaternion qAB = qB.inverse() * qA;
-
 		// split rotation into cone and twist
 		// (all this is done from B's perspective. Maybe I should be averaging axes...)
@@ -642,6 +692,6 @@
 
 				m_kSwing =  btScalar(1.) /
-					(getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) +
-					 getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis));
+					(computeAngularImpulseDenominator(m_swingAxis,invInertiaWorldA) +
+					 computeAngularImpulseDenominator(m_swingAxis,invInertiaWorldB));
 			}
 		}
@@ -651,8 +701,8 @@
 			// or you're trying to set at least one of the swing limits too small. (if so, do you really want a conetwist constraint?)
 			// anyway, we have either hinge or fixed joint
-			btVector3 ivA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(0);
-			btVector3 jvA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(1);
-			btVector3 kvA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
-			btVector3 ivB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(0);
+			btVector3 ivA = transA.getBasis() * m_rbAFrame.getBasis().getColumn(0);
+			btVector3 jvA = transA.getBasis() * m_rbAFrame.getBasis().getColumn(1);
+			btVector3 kvA = transA.getBasis() * m_rbAFrame.getBasis().getColumn(2);
+			btVector3 ivB = transB.getBasis() * m_rbBFrame.getBasis().getColumn(0);
 			btVector3 target;
 			btScalar x = ivB.dot(ivA);
@@ -745,6 +795,6 @@
 
 				m_kTwist = btScalar(1.) /
-					(getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) +
-					 getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis));
+					(computeAngularImpulseDenominator(m_twistAxis,invInertiaWorldA) +
+					 computeAngularImpulseDenominator(m_twistAxis,invInertiaWorldB));
 			}
 
@@ -757,5 +807,5 @@
 		}
 	}
-} // btConeTwistConstraint::calcAngleInfo2()
+}
 
 
@@ -982,8 +1032,86 @@
 }
 
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-
+///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+///If no axis is provided, it uses the default axis for this constraint.
+void btConeTwistConstraint::setParam(int num, btScalar value, int axis)
+{
+	switch(num)
+	{
+		case BT_CONSTRAINT_ERP :
+		case BT_CONSTRAINT_STOP_ERP :
+			if((axis >= 0) && (axis < 3)) 
+			{
+				m_linERP = value;
+				m_flags |= BT_CONETWIST_FLAGS_LIN_ERP;
+			}
+			else
+			{
+				m_biasFactor = value;
+			}
+			break;
+		case BT_CONSTRAINT_CFM :
+		case BT_CONSTRAINT_STOP_CFM :
+			if((axis >= 0) && (axis < 3)) 
+			{
+				m_linCFM = value;
+				m_flags |= BT_CONETWIST_FLAGS_LIN_CFM;
+			}
+			else
+			{
+				m_angCFM = value;
+				m_flags |= BT_CONETWIST_FLAGS_ANG_CFM;
+			}
+			break;
+		default:
+			btAssertConstrParams(0);
+			break;
+	}
+}
+
+///return the local value of parameter
+btScalar btConeTwistConstraint::getParam(int num, int axis) const 
+{
+	btScalar retVal = 0;
+	switch(num)
+	{
+		case BT_CONSTRAINT_ERP :
+		case BT_CONSTRAINT_STOP_ERP :
+			if((axis >= 0) && (axis < 3)) 
+			{
+				btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_LIN_ERP);
+				retVal = m_linERP;
+			}
+			else if((axis >= 3) && (axis < 6)) 
+			{
+				retVal = m_biasFactor;
+			}
+			else
+			{
+				btAssertConstrParams(0);
+			}
+			break;
+		case BT_CONSTRAINT_CFM :
+		case BT_CONSTRAINT_STOP_CFM :
+			if((axis >= 0) && (axis < 3)) 
+			{
+				btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_LIN_CFM);
+				retVal = m_linCFM;
+			}
+			else if((axis >= 3) && (axis < 6)) 
+			{
+				btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_ANG_CFM);
+				retVal = m_angCFM;
+			}
+			else
+			{
+				btAssertConstrParams(0);
+			}
+			break;
+		default : 
+			btAssertConstrParams(0);
+	}
+	return retVal;
+}
+
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h	(revision 8284)
@@ -18,4 +18,20 @@
 
 
+/*
+Overview:
+
+btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc).
+It is a fixed translation, 3 degree-of-freedom (DOF) rotational "joint".
+It divides the 3 rotational DOFs into swing (movement within a cone) and twist.
+Swing is divided into swing1 and swing2 which can have different limits, giving an elliptical shape.
+(Note: the cone's base isn't flat, so this ellipse is "embedded" on the surface of a sphere.)
+
+In the contraint's frame of reference:
+twist is along the x-axis,
+and swing 1 and 2 are along the z and y axes respectively.
+*/
+
+
+
 #ifndef CONETWISTCONSTRAINT_H
 #define CONETWISTCONSTRAINT_H
@@ -27,4 +43,10 @@
 class btRigidBody;
 
+enum btConeTwistFlags
+{
+	BT_CONETWIST_FLAGS_LIN_CFM = 1,
+	BT_CONETWIST_FLAGS_LIN_ERP = 2,
+	BT_CONETWIST_FLAGS_ANG_CFM = 4
+};
 
 ///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc)
@@ -84,4 +106,23 @@
 	btVector3	 m_accMotorImpulse;
 	
+	// parameters
+	int			m_flags;
+	btScalar	m_linCFM;
+	btScalar	m_linERP;
+	btScalar	m_angCFM;
+	
+protected:
+
+	void init();
+
+	void computeConeLimitInfo(const btQuaternion& qCone, // in
+		btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs
+
+	void computeTwistLimitInfo(const btQuaternion& qTwist, // in
+		btScalar& twistAngle, btVector3& vTwistAxis); // all outs
+
+	void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const;
+
+
 public:
 
@@ -90,14 +131,15 @@
 	btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
 
-	btConeTwistConstraint();
-
 	virtual void	buildJacobian();
 
 	virtual void getInfo1 (btConstraintInfo1* info);
+
+	void	getInfo1NonVirtual(btConstraintInfo1* info);
 	
 	virtual void getInfo2 (btConstraintInfo2* info);
 	
-
-	virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+	void	getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);
+
+	virtual	void	solveConstraintObsolete(btRigidBody& bodyA,btRigidBody& bodyB,btScalar	timeStep);
 
 	void	updateRHS(btScalar	timeStep);
@@ -142,5 +184,16 @@
 	}
 
-	void	setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan,  btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
+	// setLimit(), a few notes:
+	// _softness:
+	//		0->1, recommend ~0.8->1.
+	//		describes % of limits where movement is free.
+	//		beyond this softness %, the limit is gradually enforced until the "hard" (1.0) limit is reached.
+	// _biasFactor:
+	//		0->1?, recommend 0.3 +/-0.3 or so.
+	//		strength with which constraint resists zeroth order (angular, not angular velocity) limit violation.
+	// __relaxationFactor:
+	//		0->1, recommend to stay near 1.
+	//		the lower the value, the less the constraint will fight velocities which violate the angular limits.
+	void	setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
 	{
 		m_swingSpan1 = _swingSpan1;
@@ -172,5 +225,5 @@
 
 	void calcAngleInfo();
-	void calcAngleInfo2();
+	void calcAngleInfo2(const btTransform& transA, const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);
 
 	inline btScalar getSwingSpan1()
@@ -213,17 +266,67 @@
 	btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const;
 
-
-
-protected:
-	void init();
-
-	void computeConeLimitInfo(const btQuaternion& qCone, // in
-		btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs
-
-	void computeTwistLimitInfo(const btQuaternion& qTwist, // in
-		btScalar& twistAngle, btVector3& vTwistAxis); // all outs
-
-	void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const;
+	///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+	///If no axis is provided, it uses the default axis for this constraint.
+	virtual	void setParam(int num, btScalar value, int axis = -1);
+	///return the local value of parameter
+	virtual	btScalar getParam(int num, int axis = -1) const;
+
+	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	btConeTwistConstraintData
+{
+	btTypedConstraintData	m_typeConstraintData;
+	btTransformFloatData m_rbAFrame;
+	btTransformFloatData m_rbBFrame;
+
+	//limits
+	float	m_swingSpan1;
+	float	m_swingSpan2;
+	float	m_twistSpan;
+	float	m_limitSoftness;
+	float	m_biasFactor;
+	float	m_relaxationFactor;
+
+	float	m_damping;
+		
+	char m_pad[4];
+
+};
+	
+
+
+SIMD_FORCE_INLINE int	btConeTwistConstraint::calculateSerializeBufferSize() const
+{
+	return sizeof(btConeTwistConstraintData);
+
+}
+
+
+	///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;
+	btTypedConstraint::serialize(&cone->m_typeConstraintData,serializer);
+
+	m_rbAFrame.serializeFloat(cone->m_rbAFrame);
+	m_rbBFrame.serializeFloat(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);
+
+	return "btConeTwistConstraintData";
+}
+
+
 #endif //CONETWISTCONSTRAINT_H
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp	(revision 8284)
@@ -13,4 +13,50 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
+
+#include "btContactConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+#include "btContactSolverInfo.h"
+#include "LinearMath/btMinMax.h"
+#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
+
+
+
+btContactConstraint::btContactConstraint(btPersistentManifold* contactManifold,btRigidBody& rbA,btRigidBody& rbB)
+:btTypedConstraint(CONTACT_CONSTRAINT_TYPE,rbA,rbB),
+	m_contactManifold(*contactManifold)
+{
+
+}
+
+btContactConstraint::~btContactConstraint()
+{
+
+}
+
+void	btContactConstraint::setContactManifold(btPersistentManifold* contactManifold)
+{
+	m_contactManifold = *contactManifold;
+}
+
+void btContactConstraint::getInfo1 (btConstraintInfo1* info)
+{
+
+}
+
+void btContactConstraint::getInfo2 (btConstraintInfo2* info)
+{
+
+}
+
+void	btContactConstraint::buildJacobian()
+{
+
+}
+
+
+
 
 
@@ -86,344 +132,3 @@
 
 
-//response  between two dynamic objects with friction
-btScalar resolveSingleCollision(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo)
-{
 
-	const btVector3& pos1_ = contactPoint.getPositionWorldOnA();
-	const btVector3& pos2_ = contactPoint.getPositionWorldOnB();
-   	const btVector3& normal = contactPoint.m_normalWorldOnB;
-
-	//constant over all iterations
-	btVector3 rel_pos1 = pos1_ - body1.getCenterOfMassPosition(); 
-	btVector3 rel_pos2 = pos2_ - body2.getCenterOfMassPosition();
-	
-	btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
-	btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
-	btVector3 vel = vel1 - vel2;
-	btScalar rel_vel;
-	rel_vel = normal.dot(vel);
-	
-	btScalar Kfps = btScalar(1.) / solverInfo.m_timeStep ;
-
-	// btScalar damping = solverInfo.m_damping ;
-	btScalar Kerp = solverInfo.m_erp;
-	btScalar Kcor = Kerp *Kfps;
-
-	btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
-	btAssert(cpd);
-	btScalar distance = cpd->m_penetration;
-	btScalar positionalError = Kcor *-distance;
-	btScalar velocityError = cpd->m_restitution - rel_vel;// * damping;
-
-	btScalar penetrationImpulse = positionalError * cpd->m_jacDiagABInv;
-
-	btScalar	velocityImpulse = velocityError * cpd->m_jacDiagABInv;
-
-	btScalar normalImpulse = penetrationImpulse+velocityImpulse;
-	
-	// See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
-	btScalar oldNormalImpulse = cpd->m_appliedImpulse;
-	btScalar sum = oldNormalImpulse + normalImpulse;
-	cpd->m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
-
-	normalImpulse = cpd->m_appliedImpulse - oldNormalImpulse;
-
-#ifdef USE_INTERNAL_APPLY_IMPULSE
-	if (body1.getInvMass())
-	{
-		body1.internalApplyImpulse(contactPoint.m_normalWorldOnB*body1.getInvMass(),cpd->m_angularComponentA,normalImpulse);
-	}
-	if (body2.getInvMass())
-	{
-		body2.internalApplyImpulse(contactPoint.m_normalWorldOnB*body2.getInvMass(),cpd->m_angularComponentB,-normalImpulse);
-	}
-#else //USE_INTERNAL_APPLY_IMPULSE
-	body1.applyImpulse(normal*(normalImpulse), rel_pos1);
-	body2.applyImpulse(-normal*(normalImpulse), rel_pos2);
-#endif //USE_INTERNAL_APPLY_IMPULSE
-
-	return normalImpulse;
-}
-
-
-btScalar resolveSingleFriction(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo)
-{
-
-	(void)solverInfo;
-
-	const btVector3& pos1 = contactPoint.getPositionWorldOnA();
-	const btVector3& pos2 = contactPoint.getPositionWorldOnB();
-
-	btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); 
-	btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
-	
-	btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
-	btAssert(cpd);
-
-	btScalar combinedFriction = cpd->m_friction;
-	
-	btScalar limit = cpd->m_appliedImpulse * combinedFriction;
-	
-	if (cpd->m_appliedImpulse>btScalar(0.))
-	//friction
-	{
-		//apply friction in the 2 tangential directions
-		
-		// 1st tangent
-		btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
-		btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
-		btVector3 vel = vel1 - vel2;
-	
-		btScalar j1,j2;
-
-		{
-				
-			btScalar vrel = cpd->m_frictionWorldTangential0.dot(vel);
-
-			// calculate j that moves us to zero relative velocity
-			j1 = -vrel * cpd->m_jacDiagABInvTangent0;
-			btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse0;
-			cpd->m_accumulatedTangentImpulse0 = oldTangentImpulse + j1;
-			btSetMin(cpd->m_accumulatedTangentImpulse0, limit);
-			btSetMax(cpd->m_accumulatedTangentImpulse0, -limit);
-			j1 = cpd->m_accumulatedTangentImpulse0 - oldTangentImpulse;
-
-		}
-		{
-			// 2nd tangent
-
-			btScalar vrel = cpd->m_frictionWorldTangential1.dot(vel);
-			
-			// calculate j that moves us to zero relative velocity
-			j2 = -vrel * cpd->m_jacDiagABInvTangent1;
-			btScalar oldTangentImpulse = cpd->m_accumulatedTangentImpulse1;
-			cpd->m_accumulatedTangentImpulse1 = oldTangentImpulse + j2;
-			btSetMin(cpd->m_accumulatedTangentImpulse1, limit);
-			btSetMax(cpd->m_accumulatedTangentImpulse1, -limit);
-			j2 = cpd->m_accumulatedTangentImpulse1 - oldTangentImpulse;
-		}
-
-#ifdef USE_INTERNAL_APPLY_IMPULSE
-	if (body1.getInvMass())
-	{
-		body1.internalApplyImpulse(cpd->m_frictionWorldTangential0*body1.getInvMass(),cpd->m_frictionAngularComponent0A,j1);
-		body1.internalApplyImpulse(cpd->m_frictionWorldTangential1*body1.getInvMass(),cpd->m_frictionAngularComponent1A,j2);
-	}
-	if (body2.getInvMass())
-	{
-		body2.internalApplyImpulse(cpd->m_frictionWorldTangential0*body2.getInvMass(),cpd->m_frictionAngularComponent0B,-j1);
-		body2.internalApplyImpulse(cpd->m_frictionWorldTangential1*body2.getInvMass(),cpd->m_frictionAngularComponent1B,-j2);	
-	}
-#else //USE_INTERNAL_APPLY_IMPULSE
-	body1.applyImpulse((j1 * cpd->m_frictionWorldTangential0)+(j2 * cpd->m_frictionWorldTangential1), rel_pos1);
-	body2.applyImpulse((j1 * -cpd->m_frictionWorldTangential0)+(j2 * -cpd->m_frictionWorldTangential1), rel_pos2);
-#endif //USE_INTERNAL_APPLY_IMPULSE
-
-
-	} 
-	return cpd->m_appliedImpulse;
-}
-
-
-btScalar resolveSingleFrictionOriginal(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo);
-
-btScalar resolveSingleFrictionOriginal(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo)
-{
-
-	(void)solverInfo;
-
-	const btVector3& pos1 = contactPoint.getPositionWorldOnA();
-	const btVector3& pos2 = contactPoint.getPositionWorldOnB();
-
-	btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); 
-	btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
-	
-	btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
-	btAssert(cpd);
-
-	btScalar combinedFriction = cpd->m_friction;
-	
-	btScalar limit = cpd->m_appliedImpulse * combinedFriction;
-	//if (contactPoint.m_appliedImpulse>btScalar(0.))
-	//friction
-	{
-		//apply friction in the 2 tangential directions
-		
-		{
-			// 1st tangent
-			btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
-			btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
-			btVector3 vel = vel1 - vel2;
-			
-			btScalar vrel = cpd->m_frictionWorldTangential0.dot(vel);
-
-			// calculate j that moves us to zero relative velocity
-			btScalar j = -vrel * cpd->m_jacDiagABInvTangent0;
-			btScalar total = cpd->m_accumulatedTangentImpulse0 + j;
-			btSetMin(total, limit);
-			btSetMax(total, -limit);
-			j = total - cpd->m_accumulatedTangentImpulse0;
-			cpd->m_accumulatedTangentImpulse0 = total;
-			body1.applyImpulse(j * cpd->m_frictionWorldTangential0, rel_pos1);
-			body2.applyImpulse(j * -cpd->m_frictionWorldTangential0, rel_pos2);
-		}
-
-				
-		{
-			// 2nd tangent
-			btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
-			btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
-			btVector3 vel = vel1 - vel2;
-
-			btScalar vrel = cpd->m_frictionWorldTangential1.dot(vel);
-			
-			// calculate j that moves us to zero relative velocity
-			btScalar j = -vrel * cpd->m_jacDiagABInvTangent1;
-			btScalar total = cpd->m_accumulatedTangentImpulse1 + j;
-			btSetMin(total, limit);
-			btSetMax(total, -limit);
-			j = total - cpd->m_accumulatedTangentImpulse1;
-			cpd->m_accumulatedTangentImpulse1 = total;
-			body1.applyImpulse(j * cpd->m_frictionWorldTangential1, rel_pos1);
-			body2.applyImpulse(j * -cpd->m_frictionWorldTangential1, rel_pos2);
-		}
-	} 
-	return cpd->m_appliedImpulse;
-}
-
-
-//velocity + friction
-//response  between two dynamic objects with friction
-btScalar resolveSingleCollisionCombined(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo)
-{
-
-	const btVector3& pos1 = contactPoint.getPositionWorldOnA();
-	const btVector3& pos2 = contactPoint.getPositionWorldOnB();
-   	const btVector3& normal = contactPoint.m_normalWorldOnB;
-
-	btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); 
-	btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
-	
-	btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
-	btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
-	btVector3 vel = vel1 - vel2;
-	btScalar rel_vel;
-	rel_vel = normal.dot(vel);
-	
-	btScalar Kfps = btScalar(1.) / solverInfo.m_timeStep ;
-
-	//btScalar damping = solverInfo.m_damping ;
-	btScalar Kerp = solverInfo.m_erp;
-	btScalar Kcor = Kerp *Kfps;
-
-	btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
-	btAssert(cpd);
-	btScalar distance = cpd->m_penetration;
-	btScalar positionalError = Kcor *-distance;
-	btScalar velocityError = cpd->m_restitution - rel_vel;// * damping;
-
-	btScalar penetrationImpulse = positionalError * cpd->m_jacDiagABInv;
-
-	btScalar	velocityImpulse = velocityError * cpd->m_jacDiagABInv;
-
-	btScalar normalImpulse = penetrationImpulse+velocityImpulse;
-	
-	// See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
-	btScalar oldNormalImpulse = cpd->m_appliedImpulse;
-	btScalar sum = oldNormalImpulse + normalImpulse;
-	cpd->m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
-
-	normalImpulse = cpd->m_appliedImpulse - oldNormalImpulse;
-
-
-#ifdef USE_INTERNAL_APPLY_IMPULSE
-	if (body1.getInvMass())
-	{
-		body1.internalApplyImpulse(contactPoint.m_normalWorldOnB*body1.getInvMass(),cpd->m_angularComponentA,normalImpulse);
-	}
-	if (body2.getInvMass())
-	{
-		body2.internalApplyImpulse(contactPoint.m_normalWorldOnB*body2.getInvMass(),cpd->m_angularComponentB,-normalImpulse);
-	}
-#else //USE_INTERNAL_APPLY_IMPULSE
-	body1.applyImpulse(normal*(normalImpulse), rel_pos1);
-	body2.applyImpulse(-normal*(normalImpulse), rel_pos2);
-#endif //USE_INTERNAL_APPLY_IMPULSE
-
-	{
-		//friction
-		btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
-		btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
-		btVector3 vel = vel1 - vel2;
-	  
-		rel_vel = normal.dot(vel);
-
-
-		btVector3 lat_vel = vel - normal * rel_vel;
-		btScalar lat_rel_vel = lat_vel.length();
-
-		btScalar combinedFriction = cpd->m_friction;
-
-		if (cpd->m_appliedImpulse > 0)
-		if (lat_rel_vel > SIMD_EPSILON)
-		{
-			lat_vel /= lat_rel_vel;
-			btVector3 temp1 = body1.getInvInertiaTensorWorld() * rel_pos1.cross(lat_vel);
-			btVector3 temp2 = body2.getInvInertiaTensorWorld() * rel_pos2.cross(lat_vel);
-			btScalar friction_impulse = lat_rel_vel /
-				(body1.getInvMass() + body2.getInvMass() + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
-			btScalar normal_impulse = cpd->m_appliedImpulse * combinedFriction;
-
-			btSetMin(friction_impulse, normal_impulse);
-			btSetMax(friction_impulse, -normal_impulse);
-			body1.applyImpulse(lat_vel * -friction_impulse, rel_pos1);
-			body2.applyImpulse(lat_vel * friction_impulse, rel_pos2);
-		}
-	}
-
-
-
-	return normalImpulse;
-}
-
-btScalar resolveSingleFrictionEmpty(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo);
-
-btScalar resolveSingleFrictionEmpty(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo)
-{
-	(void)contactPoint;
-	(void)body1;
-	(void)body2;
-	(void)solverInfo;
-
-
-	return btScalar(0.);
-}
-
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h	(revision 8284)
@@ -17,77 +17,47 @@
 #define CONTACT_CONSTRAINT_H
 
-///@todo: make into a proper class working with the iterative constraint solver
+#include "LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+#include "btTypedConstraint.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
 
-class btRigidBody;
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btScalar.h"
-struct btContactSolverInfo;
-class btManifoldPoint;
+///btContactConstraint can be automatically created to solve contact constraints using the unified btTypedConstraint interface
+ATTRIBUTE_ALIGNED16(class) btContactConstraint : public btTypedConstraint
+{
+protected:
 
-enum {
-	DEFAULT_CONTACT_SOLVER_TYPE=0,
-	CONTACT_SOLVER_TYPE1,
-	CONTACT_SOLVER_TYPE2,
-	USER_CONTACT_SOLVER_TYPE1,
-	MAX_CONTACT_SOLVER_TYPES
+	btPersistentManifold m_contactManifold;
+
+public:
+
+
+	btContactConstraint(btPersistentManifold* contactManifold,btRigidBody& rbA,btRigidBody& rbB);
+
+	void	setContactManifold(btPersistentManifold* contactManifold);
+
+	btPersistentManifold* getContactManifold()
+	{
+		return &m_contactManifold;
+	}
+
+	const btPersistentManifold* getContactManifold() const
+	{
+		return &m_contactManifold;
+	}
+
+	virtual ~btContactConstraint();
+
+	virtual void getInfo1 (btConstraintInfo1* info);
+
+	virtual void getInfo2 (btConstraintInfo2* info);
+
+	///obsolete methods
+	virtual void	buildJacobian();
+
+
 };
 
 
-typedef btScalar (*ContactSolverFunc)(btRigidBody& body1,
-									 btRigidBody& body2,
-									 class btManifoldPoint& contactPoint,
-									 const btContactSolverInfo& info);
-
-///stores some extra information to each contact point. It is not in the contact point, because that want to keep the collision detection independent from the constraint solver.
-struct btConstraintPersistentData
-{
-	inline btConstraintPersistentData()
-	:m_appliedImpulse(btScalar(0.)),
-	m_prevAppliedImpulse(btScalar(0.)),
-	m_accumulatedTangentImpulse0(btScalar(0.)),
-	m_accumulatedTangentImpulse1(btScalar(0.)),
-	m_jacDiagABInv(btScalar(0.)),
-	m_persistentLifeTime(0),
-	m_restitution(btScalar(0.)),
-	m_friction(btScalar(0.)),
-	m_penetration(btScalar(0.)),
-	m_contactSolverFunc(0),
-	m_frictionSolverFunc(0)
-	{
-	}
-	
-					
-				/// total applied impulse during most recent frame
-			btScalar	m_appliedImpulse;
-			btScalar	m_prevAppliedImpulse;
-			btScalar	m_accumulatedTangentImpulse0;
-			btScalar	m_accumulatedTangentImpulse1;
-			
-			btScalar	m_jacDiagABInv;
-			btScalar	m_jacDiagABInvTangent0;
-			btScalar	m_jacDiagABInvTangent1;
-			int		m_persistentLifeTime;
-			btScalar	m_restitution;
-			btScalar	m_friction;
-			btScalar	m_penetration;
-			btVector3	m_frictionWorldTangential0;
-			btVector3	m_frictionWorldTangential1;
-
-			btVector3	m_frictionAngularComponent0A;
-			btVector3	m_frictionAngularComponent0B;
-			btVector3	m_frictionAngularComponent1A;
-			btVector3	m_frictionAngularComponent1B;
-
-			//some data doesn't need to be persistent over frames: todo: clean/reuse this
-			btVector3	m_angularComponentA;
-			btVector3	m_angularComponentB;
-		
-			ContactSolverFunc	m_contactSolverFunc;
-			ContactSolverFunc	m_frictionSolverFunc;
-
-};
-
-///bilateral constraint between two dynamic objects
-///positive distance = separation, negative distance = penetration
+///resolveSingleBilateral is an obsolete methods used for vehicle friction between two dynamic objects
 void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
                       btRigidBody& body2, const btVector3& pos2,
@@ -95,28 +65,4 @@
 
 
-///contact constraint resolution:
-///calculate and apply impulse to satisfy non-penetration and non-negative relative velocity constraint
-///positive distance = separation, negative distance = penetration
-btScalar resolveSingleCollision(
-	btRigidBody& body1,
-	btRigidBody& body2,
-		btManifoldPoint& contactPoint,
-		 const btContactSolverInfo& info);
-
-btScalar resolveSingleFriction(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo
-		);
-
-
-
-btScalar resolveSingleCollisionCombined(
-	btRigidBody& body1,
-	btRigidBody& body2,
-	btManifoldPoint& contactPoint,
-	const btContactSolverInfo& solverInfo
-		);
 
 #endif //CONTACT_CONSTRAINT_H
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h	(revision 8284)
@@ -36,5 +36,5 @@
 
 	btScalar	m_tau;
-	btScalar	m_damping;
+	btScalar	m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'.
 	btScalar	m_friction;
 	btScalar	m_timeStep;
@@ -53,4 +53,5 @@
 	int			m_solverMode;
 	int	m_restingContactRestitutionThreshold;
+	int			m_minimumSolverBatchSize;
 
 
@@ -78,6 +79,7 @@
 		m_linearSlop = btScalar(0.0);
 		m_warmstartingFactor=btScalar(0.85);
-		m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD ;//SOLVER_RANDMIZE_ORDER
+		m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD;// | SOLVER_RANDMIZE_ORDER;
 		m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution
+		m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit
 	}
 };
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp	(revision 8284)
@@ -23,18 +23,16 @@
 #include "BulletDynamics/Dynamics/btRigidBody.h"
 #include "LinearMath/btTransformUtil.h"
+#include "LinearMath/btTransformUtil.h"
 #include <new>
 
 
+
 #define D6_USE_OBSOLETE_METHOD false
-//-----------------------------------------------------------------------------
-
-btGeneric6DofConstraint::btGeneric6DofConstraint()
-:btTypedConstraint(D6_CONSTRAINT_TYPE),
-m_useLinearReferenceFrameA(true),
-m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD)
-{
-}
-
-//-----------------------------------------------------------------------------
+#define D6_USE_FRAME_OFFSET true
+
+
+
+
+
 
 btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA)
@@ -43,14 +41,32 @@
 , m_frameInB(frameInB),
 m_useLinearReferenceFrameA(useLinearReferenceFrameA),
+m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET),
+m_flags(0),
 m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD)
 {
-
-}
-//-----------------------------------------------------------------------------
+	calculateTransforms();
+}
+
+
+
+btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB)
+        : btTypedConstraint(D6_CONSTRAINT_TYPE, getFixedBody(), rbB),
+		m_frameInB(frameInB),
+		m_useLinearReferenceFrameA(useLinearReferenceFrameB),
+		m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET),
+		m_flags(0),
+		m_useSolveConstraintObsolete(false)
+{
+	///not providing rigidbody A means implicitly using worldspace for body A
+	m_frameInA = rbB.getCenterOfMassTransform() * m_frameInB;
+	calculateTransforms();
+}
+
+
 
 
 #define GENERIC_D6_DISABLE_WARMSTARTING 1
 
-//-----------------------------------------------------------------------------
+
 
 btScalar btGetMatrixElem(const btMatrix3x3& mat, int index);
@@ -62,5 +78,5 @@
 }
 
-//-----------------------------------------------------------------------------
+
 
 ///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html
@@ -111,5 +127,4 @@
 		return 0;
 	}
-
 	if (test_value < m_loLimit)
 	{
@@ -130,9 +145,9 @@
 }
 
-//-----------------------------------------------------------------------------
+
 
 btScalar btRotationalLimitMotor::solveAngularLimits(
 	btScalar timeStep,btVector3& axis,btScalar jacDiagABInv,
-	btRigidBody * body0, btSolverBody& bodyA, btRigidBody * body1, btSolverBody& bodyB)
+	btRigidBody * body0, btRigidBody * body1 )
 {
 	if (needApplyTorques()==false) return 0.0f;
@@ -144,5 +159,5 @@
 	if (m_currentLimit!=0)
 	{
-		target_velocity = -m_ERP*m_currentLimitError/(timeStep);
+		target_velocity = -m_stopERP*m_currentLimitError/(timeStep);
 		maxMotorForce = m_maxLimitForce;
 	}
@@ -153,7 +168,7 @@
 
 	btVector3 angVelA;
-	bodyA.getAngularVelocity(angVelA);
+	body0->internalGetAngularVelocity(angVelA);
 	btVector3 angVelB;
-	bodyB.getAngularVelocity(angVelB);
+	body1->internalGetAngularVelocity(angVelB);
 
 	btVector3 vel_diff;
@@ -192,6 +207,6 @@
 
 	// sort with accumulated impulses
-	btScalar	lo = btScalar(-1e30);
-	btScalar	hi = btScalar(1e30);
+	btScalar	lo = btScalar(-BT_LARGE_FLOAT);
+	btScalar	hi = btScalar(BT_LARGE_FLOAT);
 
 	btScalar oldaccumImpulse = m_accumulatedImpulse;
@@ -206,6 +221,6 @@
 	//body1->applyTorqueImpulse(-motorImp);
 
-	bodyA.applyImpulse(btVector3(0,0,0), body0->getInvInertiaTensorWorld()*axis,clippedMotorImpulse);
-	bodyB.applyImpulse(btVector3(0,0,0), body1->getInvInertiaTensorWorld()*axis,-clippedMotorImpulse);
+	body0->internalApplyImpulse(btVector3(0,0,0), body0->getInvInertiaTensorWorld()*axis,clippedMotorImpulse);
+	body1->internalApplyImpulse(btVector3(0,0,0), body1->getInvInertiaTensorWorld()*axis,-clippedMotorImpulse);
 
 
@@ -250,13 +265,13 @@
 	m_currentLimitError[limitIndex] = btScalar(0.f);
 	return 0;
-} // btTranslationalLimitMotor::testLimitValue()
-
-//-----------------------------------------------------------------------------
+}
+
+
 
 btScalar btTranslationalLimitMotor::solveLinearAxis(
 	btScalar timeStep,
 	btScalar jacDiagABInv,
-	btRigidBody& body1,btSolverBody& bodyA,const btVector3 &pointInA,
-	btRigidBody& body2,btSolverBody& bodyB,const btVector3 &pointInB,
+	btRigidBody& body1,const btVector3 &pointInA,
+	btRigidBody& body2,const btVector3 &pointInB,
 	int limit_index,
 	const btVector3 & axis_normal_on_a,
@@ -271,7 +286,7 @@
 
 	btVector3 vel1;
-	bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
+	body1.internalGetVelocityInLocalPointObsolete(rel_pos1,vel1);
 	btVector3 vel2;
-	bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
+	body2.internalGetVelocityInLocalPointObsolete(rel_pos2,vel2);
 	btVector3 vel = vel1 - vel2;
 
@@ -284,6 +299,6 @@
 	//positional error (zeroth order error)
 	btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a);
-	btScalar	lo = btScalar(-1e30);
-	btScalar	hi = btScalar(1e30);
+	btScalar	lo = btScalar(-BT_LARGE_FLOAT);
+	btScalar	hi = btScalar(BT_LARGE_FLOAT);
 
 	btScalar minLimit = m_lowerLimit[limit_index];
@@ -331,6 +346,6 @@
 	btVector3 ftorqueAxis1 = rel_pos1.cross(axis_normal_on_a);
 	btVector3 ftorqueAxis2 = rel_pos2.cross(axis_normal_on_a);
-	bodyA.applyImpulse(axis_normal_on_a*body1.getInvMass(), body1.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse);
-	bodyB.applyImpulse(axis_normal_on_a*body2.getInvMass(), body2.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse);
+	body1.internalApplyImpulse(axis_normal_on_a*body1.getInvMass(), body1.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse);
+	body2.internalApplyImpulse(axis_normal_on_a*body2.getInvMass(), body2.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse);
 
 
@@ -373,15 +388,34 @@
 }
 
-//-----------------------------------------------------------------------------
-
 void btGeneric6DofConstraint::calculateTransforms()
 {
-	m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA;
-	m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB;
+	calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
+}
+
+void btGeneric6DofConstraint::calculateTransforms(const btTransform& transA,const btTransform& transB)
+{
+	m_calculatedTransformA = transA * m_frameInA;
+	m_calculatedTransformB = transB * m_frameInB;
 	calculateLinearInfo();
 	calculateAngleInfo();
-}
-
-//-----------------------------------------------------------------------------
+	if(m_useOffsetForConstraintFrame)
+	{	//  get weight factors depending on masses
+		btScalar miA = getRigidBodyA().getInvMass();
+		btScalar miB = getRigidBodyB().getInvMass();
+		m_hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON);
+		btScalar miS = miA + miB;
+		if(miS > btScalar(0.f))
+		{
+			m_factA = miB / miS;
+		}
+		else 
+		{
+			m_factA = btScalar(0.5f);
+		}
+		m_factB = btScalar(1.0f) - m_factA;
+	}
+}
+
+
 
 void btGeneric6DofConstraint::buildLinearJacobian(
@@ -401,5 +435,5 @@
 }
 
-//-----------------------------------------------------------------------------
+
 
 void btGeneric6DofConstraint::buildAngularJacobian(
@@ -414,9 +448,11 @@
 }
 
-//-----------------------------------------------------------------------------
+
 
 bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index)
 {
 	btScalar angle = m_calculatedAxisAngleDiff[axis_index];
+	angle = btAdjustAngleToLimits(angle, m_angularLimits[axis_index].m_loLimit, m_angularLimits[axis_index].m_hiLimit);
+	m_angularLimits[axis_index].m_currentPosition = angle;
 	//test limits
 	m_angularLimits[axis_index].testLimitValue(angle);
@@ -424,8 +460,9 @@
 }
 
-//-----------------------------------------------------------------------------
+
 
 void btGeneric6DofConstraint::buildJacobian()
 {
+#ifndef __SPU__
 	if (m_useSolveConstraintObsolete)
 	{
@@ -439,5 +476,5 @@
 		}
 		//calculates transform
-		calculateTransforms();
+		calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
 
 		//  const btVector3& pivotAInW = m_calculatedTransformA.getOrigin();
@@ -482,7 +519,8 @@
 
 	}
-}
-
-//-----------------------------------------------------------------------------
+#endif //__SPU__
+
+}
+
 
 void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info)
@@ -495,5 +533,5 @@
 	{
 		//prepare constraint
-		calculateTransforms();
+		calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
 		info->m_numConstraintRows = 0;
 		info->nub = 6;
@@ -520,19 +558,74 @@
 }
 
-//-----------------------------------------------------------------------------
+void btGeneric6DofConstraint::getInfo1NonVirtual (btConstraintInfo1* info)
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		info->m_numConstraintRows = 0;
+		info->nub = 0;
+	} else
+	{
+		//pre-allocate all 6
+		info->m_numConstraintRows = 6;
+		info->nub = 0;
+	}
+}
+
 
 void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info)
 {
 	btAssert(!m_useSolveConstraintObsolete);
-	int row = setLinearLimits(info);
-	setAngularLimits(info, row);
-}
-
-//-----------------------------------------------------------------------------
-
-int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info)
-{
-	btGeneric6DofConstraint * d6constraint = this;
-	int row = 0;
+
+	const btTransform& transA = m_rbA.getCenterOfMassTransform();
+	const btTransform& transB = m_rbB.getCenterOfMassTransform();
+	const btVector3& linVelA = m_rbA.getLinearVelocity();
+	const btVector3& linVelB = m_rbB.getLinearVelocity();
+	const btVector3& angVelA = m_rbA.getAngularVelocity();
+	const btVector3& angVelB = m_rbB.getAngularVelocity();
+
+	if(m_useOffsetForConstraintFrame)
+	{ // for stability better to solve angular limits first
+		int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB);
+		setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB);
+	}
+	else
+	{ // leave old version for compatibility
+		int row = setLinearLimits(info, 0, transA,transB,linVelA,linVelB,angVelA,angVelB);
+		setAngularLimits(info, row,transA,transB,linVelA,linVelB,angVelA,angVelB);
+	}
+
+}
+
+
+void btGeneric6DofConstraint::getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB)
+{
+	
+	btAssert(!m_useSolveConstraintObsolete);
+	//prepare constraint
+	calculateTransforms(transA,transB);
+
+	int i;
+	for (i=0;i<3 ;i++ )
+	{
+		testAngularLimitMotor(i);
+	}
+
+	if(m_useOffsetForConstraintFrame)
+	{ // for stability better to solve angular limits first
+		int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB);
+		setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB);
+	}
+	else
+	{ // leave old version for compatibility
+		int row = setLinearLimits(info, 0, transA,transB,linVelA,linVelB,angVelA,angVelB);
+		setAngularLimits(info, row,transA,transB,linVelA,linVelB,angVelA,angVelB);
+	}
+}
+
+
+
+int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB)
+{
+//	int row = 0;
 	//solve linear limits
 	btRotationalLimitMotor limot;
@@ -543,8 +636,8 @@
 			limot.m_bounce = btScalar(0.f);
 			limot.m_currentLimit = m_linearLimits.m_currentLimit[i];
+			limot.m_currentPosition = m_linearLimits.m_currentLinearDiff[i];
 			limot.m_currentLimitError  = m_linearLimits.m_currentLimitError[i];
 			limot.m_damping  = m_linearLimits.m_damping;
 			limot.m_enableMotor  = m_linearLimits.m_enableMotor[i];
-			limot.m_ERP  = m_linearLimits.m_restitution;
 			limot.m_hiLimit  = m_linearLimits.m_upperLimit[i];
 			limot.m_limitSoftness  = m_linearLimits.m_limitSoftness;
@@ -554,5 +647,23 @@
 			limot.m_targetVelocity  = m_linearLimits.m_targetVelocity[i];
 			btVector3 axis = m_calculatedTransformA.getBasis().getColumn(i);
-			row += get_limit_motor_info2(&limot, &m_rbA, &m_rbB, info, row, axis, 0);
+			int flags = m_flags >> (i * BT_6DOF_FLAGS_AXIS_SHIFT);
+			limot.m_normalCFM	= (flags & BT_6DOF_FLAGS_CFM_NORM) ? m_linearLimits.m_normalCFM[i] : info->cfm[0];
+			limot.m_stopCFM		= (flags & BT_6DOF_FLAGS_CFM_STOP) ? m_linearLimits.m_stopCFM[i] : info->cfm[0];
+			limot.m_stopERP		= (flags & BT_6DOF_FLAGS_ERP_STOP) ? m_linearLimits.m_stopERP[i] : info->erp;
+			if(m_useOffsetForConstraintFrame)
+			{
+				int indx1 = (i + 1) % 3;
+				int indx2 = (i + 2) % 3;
+				int rotAllowed = 1; // rotations around orthos to current axis
+				if(m_angularLimits[indx1].m_currentLimit && m_angularLimits[indx2].m_currentLimit)
+				{
+					rotAllowed = 0;
+				}
+				row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0, rotAllowed);
+			}
+			else
+			{
+				row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0);
+			}
 		}
 	}
@@ -560,7 +671,7 @@
 }
 
-//-----------------------------------------------------------------------------
-
-int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset)
+
+
+int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB)
 {
 	btGeneric6DofConstraint * d6constraint = this;
@@ -572,9 +683,19 @@
 		{
 			btVector3 axis = d6constraint->getAxis(i);
-			row += get_limit_motor_info2(
-				d6constraint->getRotationalLimitMotor(i),
-				&m_rbA,
-				&m_rbB,
-				info,row,axis,1);
+			int flags = m_flags >> ((i + 3) * BT_6DOF_FLAGS_AXIS_SHIFT);
+			if(!(flags & BT_6DOF_FLAGS_CFM_NORM))
+			{
+				m_angularLimits[i].m_normalCFM = info->cfm[0];
+			}
+			if(!(flags & BT_6DOF_FLAGS_CFM_STOP))
+			{
+				m_angularLimits[i].m_stopCFM = info->cfm[0];
+			}
+			if(!(flags & BT_6DOF_FLAGS_ERP_STOP))
+			{
+				m_angularLimits[i].m_stopERP = info->erp;
+			}
+			row += get_limit_motor_info2(d6constraint->getRotationalLimitMotor(i),
+												transA,transB,linVelA,linVelB,angVelA,angVelB, info,row,axis,1);
 		}
 	}
@@ -583,66 +704,6 @@
 }
 
-//-----------------------------------------------------------------------------
-
-void btGeneric6DofConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep)
-{
-	if (m_useSolveConstraintObsolete)
-	{
-
-
-		m_timeStep = timeStep;
-
-		//calculateTransforms();
-
-		int i;
-
-		// linear
-
-		btVector3 pointInA = m_calculatedTransformA.getOrigin();
-		btVector3 pointInB = m_calculatedTransformB.getOrigin();
-
-		btScalar jacDiagABInv;
-		btVector3 linear_axis;
-		for (i=0;i<3;i++)
-		{
-			if (m_linearLimits.isLimited(i))
-			{
-				jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal();
-
-				if (m_useLinearReferenceFrameA)
-					linear_axis = m_calculatedTransformA.getBasis().getColumn(i);
-				else
-					linear_axis = m_calculatedTransformB.getBasis().getColumn(i);
-
-				m_linearLimits.solveLinearAxis(
-					m_timeStep,
-					jacDiagABInv,
-					m_rbA,bodyA,pointInA,
-					m_rbB,bodyB,pointInB,
-					i,linear_axis, m_AnchorPos);
-
-			}
-		}
-
-		// angular
-		btVector3 angular_axis;
-		btScalar angularJacDiagABInv;
-		for (i=0;i<3;i++)
-		{
-			if (m_angularLimits[i].needApplyTorques())
-			{
-
-				// get axis
-				angular_axis = getAxis(i);
-
-				angularJacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal();
-
-				m_angularLimits[i].solveAngularLimits(m_timeStep,angular_axis,angularJacDiagABInv, &m_rbA,bodyA,&m_rbB,bodyB);
-			}
-		}
-	}
-}
-
-//-----------------------------------------------------------------------------
+
+
 
 void	btGeneric6DofConstraint::updateRHS(btScalar	timeStep)
@@ -652,5 +713,5 @@
 }
 
-//-----------------------------------------------------------------------------
+
 
 btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const
@@ -659,12 +720,17 @@
 }
 
-//-----------------------------------------------------------------------------
-
-btScalar btGeneric6DofConstraint::getAngle(int axis_index) const
-{
-	return m_calculatedAxisAngleDiff[axis_index];
-}
-
-//-----------------------------------------------------------------------------
+
+btScalar	btGeneric6DofConstraint::getRelativePivotPosition(int axisIndex) const
+{
+	return m_calculatedLinearDiff[axisIndex];
+}
+
+
+btScalar btGeneric6DofConstraint::getAngle(int axisIndex) const
+{
+	return m_calculatedAxisAngleDiff[axisIndex];
+}
+
+
 
 void btGeneric6DofConstraint::calcAnchorPos(void)
@@ -685,7 +751,7 @@
 	m_AnchorPos = pA * weight + pB * (btScalar(1.0) - weight);
 	return;
-} // btGeneric6DofConstraint::calcAnchorPos()
-
-//-----------------------------------------------------------------------------
+}
+
+
 
 void btGeneric6DofConstraint::calculateLinearInfo()
@@ -695,14 +761,15 @@
 	for(int i = 0; i < 3; i++)
 	{
+		m_linearLimits.m_currentLinearDiff[i] = m_calculatedLinearDiff[i];
 		m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]);
 	}
-} // btGeneric6DofConstraint::calculateLinearInfo()
-
-//-----------------------------------------------------------------------------
+}
+
+
 
 int btGeneric6DofConstraint::get_limit_motor_info2(
 	btRotationalLimitMotor * limot,
-	btRigidBody * body0, btRigidBody * body1,
-	btConstraintInfo2 *info, int row, btVector3& ax1, int rotational)
+	const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB,
+	btConstraintInfo2 *info, int row, btVector3& ax1, int rotational,int rotAllowed)
 {
     int srow = row * info->rowskip;
@@ -722,18 +789,51 @@
             J2[srow+2] = -ax1[2];
         }
-        if((!rotational) && limit)
+        if((!rotational))
         {
-			btVector3 ltd;	// Linear Torque Decoupling vector
-			btVector3 c = m_calculatedTransformB.getOrigin() - body0->getCenterOfMassPosition();
-			ltd = c.cross(ax1);
-            info->m_J1angularAxis[srow+0] = ltd[0];
-            info->m_J1angularAxis[srow+1] = ltd[1];
-            info->m_J1angularAxis[srow+2] = ltd[2];
-
-			c = m_calculatedTransformB.getOrigin() - body1->getCenterOfMassPosition();
-			ltd = -c.cross(ax1);
-			info->m_J2angularAxis[srow+0] = ltd[0];
-            info->m_J2angularAxis[srow+1] = ltd[1];
-            info->m_J2angularAxis[srow+2] = ltd[2];
+			if (m_useOffsetForConstraintFrame)
+			{
+				btVector3 tmpA, tmpB, relA, relB;
+				// get vector from bodyB to frameB in WCS
+				relB = m_calculatedTransformB.getOrigin() - transB.getOrigin();
+				// get its projection to constraint axis
+				btVector3 projB = ax1 * relB.dot(ax1);
+				// get vector directed from bodyB to constraint axis (and orthogonal to it)
+				btVector3 orthoB = relB - projB;
+				// same for bodyA
+				relA = m_calculatedTransformA.getOrigin() - transA.getOrigin();
+				btVector3 projA = ax1 * relA.dot(ax1);
+				btVector3 orthoA = relA - projA;
+				// get desired offset between frames A and B along constraint axis
+				btScalar desiredOffs = limot->m_currentPosition - limot->m_currentLimitError;
+				// desired vector from projection of center of bodyA to projection of center of bodyB to constraint axis
+				btVector3 totalDist = projA + ax1 * desiredOffs - projB;
+				// get offset vectors relA and relB
+				relA = orthoA + totalDist * m_factA;
+				relB = orthoB - totalDist * m_factB;
+				tmpA = relA.cross(ax1);
+				tmpB = relB.cross(ax1);
+				if(m_hasStaticBody && (!rotAllowed))
+				{
+					tmpA *= m_factA;
+					tmpB *= m_factB;
+				}
+				int i;
+				for (i=0; i<3; i++) info->m_J1angularAxis[srow+i] = tmpA[i];
+				for (i=0; i<3; i++) info->m_J2angularAxis[srow+i] = -tmpB[i];
+			} else
+			{
+				btVector3 ltd;	// Linear Torque Decoupling vector
+				btVector3 c = m_calculatedTransformB.getOrigin() - transA.getOrigin();
+				ltd = c.cross(ax1);
+				info->m_J1angularAxis[srow+0] = ltd[0];
+				info->m_J1angularAxis[srow+1] = ltd[1];
+				info->m_J1angularAxis[srow+2] = ltd[2];
+
+				c = m_calculatedTransformB.getOrigin() - transB.getOrigin();
+				ltd = -c.cross(ax1);
+				info->m_J2angularAxis[srow+0] = ltd[0];
+				info->m_J2angularAxis[srow+1] = ltd[1];
+				info->m_J2angularAxis[srow+2] = ltd[2];
+			}
         }
         // if we're limited low and high simultaneously, the joint motor is
@@ -743,8 +843,15 @@
         if (powered)
         {
-            info->cfm[srow] = 0.0f;
+			info->cfm[srow] = limot->m_normalCFM;
             if(!limit)
             {
-                info->m_constraintError[srow] += limot->m_targetVelocity;
+				btScalar tag_vel = rotational ? limot->m_targetVelocity : -limot->m_targetVelocity;
+
+				btScalar mot_fact = getMotorFactor(	limot->m_currentPosition, 
+													limot->m_loLimit,
+													limot->m_hiLimit, 
+													tag_vel, 
+													info->fps * limot->m_stopERP);
+				info->m_constraintError[srow] += mot_fact * limot->m_targetVelocity;
                 info->m_lowerLimit[srow] = -limot->m_maxMotorForce;
                 info->m_upperLimit[srow] = limot->m_maxMotorForce;
@@ -753,5 +860,5 @@
         if(limit)
         {
-            btScalar k = info->fps * limot->m_ERP;
+            btScalar k = info->fps * limot->m_stopERP;
 			if(!rotational)
 			{
@@ -762,5 +869,5 @@
 				info->m_constraintError[srow] += -k * limot->m_currentLimitError;
 			}
-            info->cfm[srow] = 0.0f;
+			info->cfm[srow] = limot->m_stopCFM;
             if (limot->m_loLimit == limot->m_hiLimit)
             {   // limited low and high simultaneously
@@ -787,13 +894,15 @@
                     if (rotational)
                     {
-                        vel = body0->getAngularVelocity().dot(ax1);
-                        if (body1)
-                            vel -= body1->getAngularVelocity().dot(ax1);
+                        vel = angVelA.dot(ax1);
+//make sure that if no body -> angVelB == zero vec
+//                        if (body1)
+                            vel -= angVelB.dot(ax1);
                     }
                     else
                     {
-                        vel = body0->getLinearVelocity().dot(ax1);
-                        if (body1)
-                            vel -= body1->getLinearVelocity().dot(ax1);
+                        vel = linVelA.dot(ax1);
+//make sure that if no body -> angVelB == zero vec
+//                        if (body1)
+                            vel -= linVelB.dot(ax1);
                     }
                     // only apply bounce if the velocity is incoming, and if the
@@ -825,5 +934,107 @@
 }
 
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+
+
+
+
+
+	///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+	///If no axis is provided, it uses the default axis for this constraint.
+void btGeneric6DofConstraint::setParam(int num, btScalar value, int axis)
+{
+	if((axis >= 0) && (axis < 3))
+	{
+		switch(num)
+		{
+			case BT_CONSTRAINT_STOP_ERP : 
+				m_linearLimits.m_stopERP[axis] = value;
+				m_flags |= BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT);
+				break;
+			case BT_CONSTRAINT_STOP_CFM : 
+				m_linearLimits.m_stopCFM[axis] = value;
+				m_flags |= BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT);
+				break;
+			case BT_CONSTRAINT_CFM : 
+				m_linearLimits.m_normalCFM[axis] = value;
+				m_flags |= BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT);
+				break;
+			default : 
+				btAssertConstrParams(0);
+		}
+	}
+	else if((axis >=3) && (axis < 6))
+	{
+		switch(num)
+		{
+			case BT_CONSTRAINT_STOP_ERP : 
+				m_angularLimits[axis - 3].m_stopERP = value;
+				m_flags |= BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT);
+				break;
+			case BT_CONSTRAINT_STOP_CFM : 
+				m_angularLimits[axis - 3].m_stopCFM = value;
+				m_flags |= BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT);
+				break;
+			case BT_CONSTRAINT_CFM : 
+				m_angularLimits[axis - 3].m_normalCFM = value;
+				m_flags |= BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT);
+				break;
+			default : 
+				btAssertConstrParams(0);
+		}
+	}
+	else
+	{
+		btAssertConstrParams(0);
+	}
+}
+
+	///return the local value of parameter
+btScalar btGeneric6DofConstraint::getParam(int num, int axis) const 
+{
+	btScalar retVal = 0;
+	if((axis >= 0) && (axis < 3))
+	{
+		switch(num)
+		{
+			case BT_CONSTRAINT_STOP_ERP : 
+				btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT)));
+				retVal = m_linearLimits.m_stopERP[axis];
+				break;
+			case BT_CONSTRAINT_STOP_CFM : 
+				btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT)));
+				retVal = m_linearLimits.m_stopCFM[axis];
+				break;
+			case BT_CONSTRAINT_CFM : 
+				btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT)));
+				retVal = m_linearLimits.m_normalCFM[axis];
+				break;
+			default : 
+				btAssertConstrParams(0);
+		}
+	}
+	else if((axis >=3) && (axis < 6))
+	{
+		switch(num)
+		{
+			case BT_CONSTRAINT_STOP_ERP : 
+				btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT)));
+				retVal = m_angularLimits[axis - 3].m_stopERP;
+				break;
+			case BT_CONSTRAINT_STOP_CFM : 
+				btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT)));
+				retVal = m_angularLimits[axis - 3].m_stopCFM;
+				break;
+			case BT_CONSTRAINT_CFM : 
+				btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT)));
+				retVal = m_angularLimits[axis - 3].m_normalCFM;
+				break;
+			default : 
+				btAssertConstrParams(0);
+		}
+	}
+	else
+	{
+		btAssertConstrParams(0);
+	}
+	return retVal;
+}
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h	(revision 8284)
@@ -13,4 +13,8 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
+/// 2009 March: btGeneric6DofConstraint refactored by Roman Ponomarev
+/// Added support for generic constraint solver through getInfo1/getInfo2 methods
+
 /*
 2007-09-09
@@ -46,5 +50,7 @@
     btScalar m_damping;//!< Damping.
     btScalar m_limitSoftness;//! Relaxation factor
-    btScalar m_ERP;//!< Error tolerance factor when joint is at limit
+    btScalar m_normalCFM;//!< Constraint force mixing factor
+    btScalar m_stopERP;//!< Error tolerance factor when joint is at limit
+    btScalar m_stopCFM;//!< Constraint force mixing factor when joint is at limit
     btScalar m_bounce;//!< restitution factor
     bool m_enableMotor;
@@ -55,4 +61,5 @@
     //!@{
     btScalar m_currentLimitError;//!  How much is violated this limit
+    btScalar m_currentPosition;     //!  current value of angle 
     int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit
     btScalar m_accumulatedImpulse;
@@ -65,7 +72,9 @@
         m_maxMotorForce = 0.1f;
         m_maxLimitForce = 300.0f;
-        m_loLimit = -SIMD_INFINITY;
-        m_hiLimit = SIMD_INFINITY;
-        m_ERP = 0.5f;
+        m_loLimit = 1.0f;
+        m_hiLimit = -1.0f;
+		m_normalCFM = 0.f;
+		m_stopERP = 0.2f;
+		m_stopCFM = 0.f;
         m_bounce = 0.0f;
         m_damping = 1.0f;
@@ -83,5 +92,7 @@
         m_loLimit = limot.m_loLimit;
         m_hiLimit = limot.m_hiLimit;
-        m_ERP = limot.m_ERP;
+		m_normalCFM = limot.m_normalCFM;
+		m_stopERP = limot.m_stopERP;
+		m_stopCFM =	limot.m_stopCFM;
         m_bounce = limot.m_bounce;
         m_currentLimit = limot.m_currentLimit;
@@ -113,5 +124,5 @@
 
 	//! apply the correction impulses for two bodies
-    btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btSolverBody& bodyA,btRigidBody * body1,btSolverBody& bodyB);
+    btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1);
 
 };
@@ -130,4 +141,7 @@
     btScalar	m_damping;//!< Damping for linear limit
     btScalar	m_restitution;//! Bounce parameter for linear limit
+	btVector3	m_normalCFM;//!< Constraint force mixing factor
+    btVector3	m_stopERP;//!< Error tolerance factor when joint is at limit
+	btVector3	m_stopCFM;//!< Constraint force mixing factor when joint is at limit
     //!@}
 	bool		m_enableMotor[3];
@@ -135,4 +149,5 @@
     btVector3	m_maxMotorForce;//!< max force on motor
     btVector3	m_currentLimitError;//!  How much is violated this limit
+    btVector3	m_currentLinearDiff;//!  Current relative offset of constraint frames
     int			m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit
 
@@ -142,4 +157,7 @@
     	m_upperLimit.setValue(0.f,0.f,0.f);
     	m_accumulatedImpulse.setValue(0.f,0.f,0.f);
+		m_normalCFM.setValue(0.f, 0.f, 0.f);
+		m_stopERP.setValue(0.2f, 0.2f, 0.2f);
+		m_stopCFM.setValue(0.f, 0.f, 0.f);
 
     	m_limitSoftness = 0.7f;
@@ -163,4 +181,8 @@
     	m_damping = other.m_damping;
     	m_restitution = other.m_restitution;
+		m_normalCFM = other.m_normalCFM;
+		m_stopERP = other.m_stopERP;
+		m_stopCFM = other.m_stopCFM;
+
 		for(int i=0; i < 3; i++) 
 		{
@@ -193,6 +215,6 @@
     	btScalar timeStep,
         btScalar jacDiagABInv,
-        btRigidBody& body1,btSolverBody& bodyA,const btVector3 &pointInA,
-        btRigidBody& body2,btSolverBody& bodyB,const btVector3 &pointInB,
+        btRigidBody& body1,const btVector3 &pointInA,
+        btRigidBody& body2,const btVector3 &pointInB,
         int limit_index,
         const btVector3 & axis_normal_on_a,
@@ -201,4 +223,13 @@
 
 };
+
+enum bt6DofFlags
+{
+	BT_6DOF_FLAGS_CFM_NORM = 1,
+	BT_6DOF_FLAGS_CFM_STOP = 2,
+	BT_6DOF_FLAGS_ERP_STOP = 4
+};
+#define BT_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis
+
 
 /// btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space
@@ -216,18 +247,20 @@
 <li> Angulars limits have these possible ranges:
 <table border=1 >
-<tr
-
+<tr>
 	<td><b>AXIS</b></td>
 	<td><b>MIN ANGLE</b></td>
 	<td><b>MAX ANGLE</b></td>
+</tr><tr>
 	<td>X</td>
-		<td>-PI</td>
-		<td>PI</td>
+	<td>-PI</td>
+	<td>PI</td>
+</tr><tr>
 	<td>Y</td>
-		<td>-PI/2</td>
-		<td>PI/2</td>
+	<td>-PI/2</td>
+	<td>PI/2</td>
+</tr><tr>
 	<td>Z</td>
-		<td>-PI/2</td>
-		<td>PI/2</td>
+	<td>-PI</td>
+	<td>PI</td>
 </tr>
 </table>
@@ -273,9 +306,15 @@
     btVector3 m_calculatedAxis[3];
     btVector3 m_calculatedLinearDiff;
+	btScalar	m_factA;
+	btScalar	m_factB;
+	bool		m_hasStaticBody;
     
 	btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes
 
     bool	m_useLinearReferenceFrameA;
+	bool	m_useOffsetForConstraintFrame;
     
+	int		m_flags;
+
     //!@}
 
@@ -288,7 +327,7 @@
 
 
-	int setAngularLimits(btConstraintInfo2 *info, int row_offset);
-
-	int setLinearLimits(btConstraintInfo2 *info);
+	int setAngularLimits(btConstraintInfo2 *info, int row_offset,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB);
+
+	int setLinearLimits(btConstraintInfo2 *info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB);
 
     void buildLinearJacobian(
@@ -312,7 +351,6 @@
 
     btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
-
-    btGeneric6DofConstraint();
-
+    btGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
+    
 	//! Calcs global transform of the offsets
 	/*!
@@ -320,5 +358,7 @@
 	\sa btGeneric6DofConstraint.getCalculatedTransformA , btGeneric6DofConstraint.getCalculatedTransformB, btGeneric6DofConstraint.calculateAngleInfo
 	*/
-    void calculateTransforms();
+    void calculateTransforms(const btTransform& transA,const btTransform& transB);
+
+	void calculateTransforms();
 
 	//! Gets the global transform of the offset for body A
@@ -367,7 +407,10 @@
 	virtual void getInfo1 (btConstraintInfo1* info);
 
+	void getInfo1NonVirtual (btConstraintInfo1* info);
+
 	virtual void getInfo2 (btConstraintInfo2* info);
 
-    virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+	void getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB);
+
 
     void	updateRHS(btScalar	timeStep);
@@ -381,12 +424,19 @@
     //! Get the relative Euler angle
     /*!
-	\pre btGeneric6DofConstraint.buildJacobian must be called previously.
+	\pre btGeneric6DofConstraint::calculateTransforms() must be called previously.
 	*/
     btScalar getAngle(int axis_index) const;
+
+	//! Get the relative position of the constraint pivot
+    /*!
+	\pre btGeneric6DofConstraint::calculateTransforms() must be called previously.
+	*/
+	btScalar getRelativePivotPosition(int axis_index) const;
+
 
 	//! Test angular limit.
 	/*!
 	Calculates angular correction and returns true if limit needs to be corrected.
-	\pre btGeneric6DofConstraint.buildJacobian must be called previously.
+	\pre btGeneric6DofConstraint::calculateTransforms() must be called previously.
 	*/
     bool testAngularLimitMotor(int axis_index);
@@ -404,14 +454,12 @@
     void	setAngularLowerLimit(const btVector3& angularLower)
     {
-        m_angularLimits[0].m_loLimit = angularLower.getX();
-        m_angularLimits[1].m_loLimit = angularLower.getY();
-        m_angularLimits[2].m_loLimit = angularLower.getZ();
+		for(int i = 0; i < 3; i++) 
+			m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]);
     }
 
     void	setAngularUpperLimit(const btVector3& angularUpper)
     {
-        m_angularLimits[0].m_hiLimit = angularUpper.getX();
-        m_angularLimits[1].m_hiLimit = angularUpper.getY();
-        m_angularLimits[2].m_hiLimit = angularUpper.getZ();
+		for(int i = 0; i < 3; i++)
+			m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]);
     }
 
@@ -438,4 +486,6 @@
     	else
     	{
+			lo = btNormalizeAngle(lo);
+			hi = btNormalizeAngle(hi);
     		m_angularLimits[axis-3].m_loLimit = lo;
     		m_angularLimits[axis-3].m_hiLimit = hi;
@@ -460,21 +510,79 @@
     }
 
-    const btRigidBody& getRigidBodyA() const
-    {
-        return m_rbA;
-    }
-    const btRigidBody& getRigidBodyB() const
-    {
-        return m_rbB;
-    }
-
 	virtual void calcAnchorPos(void); // overridable
 
 	int get_limit_motor_info2(	btRotationalLimitMotor * limot,
-								btRigidBody * body0, btRigidBody * body1,
-								btConstraintInfo2 *info, int row, btVector3& ax1, int rotational);
-
-
+								const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB,
+								btConstraintInfo2 *info, int row, btVector3& ax1, int rotational, int rotAllowed = false);
+
+	// access for UseFrameOffset
+	bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
+	void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
+
+	///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+	///If no axis is provided, it uses the default axis for this constraint.
+	virtual	void setParam(int num, btScalar value, int axis = -1);
+	///return the local value of parameter
+	virtual	btScalar getParam(int num, int axis = -1) const;
+
+	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 btGeneric6DofConstraintData
+{
+	btTypedConstraintData	m_typeConstraintData;
+	btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
+	btTransformFloatData m_rbBFrame;
+	
+	btVector3FloatData	m_linearUpperLimit;
+	btVector3FloatData	m_linearLowerLimit;
+
+	btVector3FloatData	m_angularUpperLimit;
+	btVector3FloatData	m_angularLowerLimit;
+	
+	int	m_useLinearReferenceFrameA;
+	int m_useOffsetForConstraintFrame;
+};
+
+SIMD_FORCE_INLINE	int	btGeneric6DofConstraint::calculateSerializeBufferSize() const
+{
+	return sizeof(btGeneric6DofConstraintData);
+}
+
+	///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;
+	btTypedConstraint::serialize(&dof->m_typeConstraintData,serializer);
+
+	m_frameInA.serializeFloat(dof->m_rbAFrame);
+	m_frameInB.serializeFloat(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_useLinearReferenceFrameA = m_useLinearReferenceFrameA? 1 : 0;
+	dof->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame ? 1 : 0;
+
+	return "btGeneric6DofConstraintData";
+}
+
+
+
+
+
 #endif //GENERIC_6DOF_CONSTRAINT_H
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp	(revision 8284)
@@ -0,0 +1,151 @@
+/*
+Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
+Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. 
+
+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 "btGeneric6DofSpringConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btTransformUtil.h"
+
+
+btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA)
+	: btGeneric6DofConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA)
+{
+	for(int i = 0; i < 6; i++)
+	{
+		m_springEnabled[i] = false;
+		m_equilibriumPoint[i] = btScalar(0.f);
+		m_springStiffness[i] = btScalar(0.f);
+		m_springDamping[i] = btScalar(1.f);
+	}
+}
+
+
+void btGeneric6DofSpringConstraint::enableSpring(int index, bool onOff)
+{
+	btAssert((index >= 0) && (index < 6));
+	m_springEnabled[index] = onOff;
+	if(index < 3)
+	{
+		m_linearLimits.m_enableMotor[index] = onOff;
+	}
+	else
+	{
+		m_angularLimits[index - 3].m_enableMotor = onOff;
+	}
+}
+
+
+
+void btGeneric6DofSpringConstraint::setStiffness(int index, btScalar stiffness)
+{
+	btAssert((index >= 0) && (index < 6));
+	m_springStiffness[index] = stiffness;
+}
+
+
+void btGeneric6DofSpringConstraint::setDamping(int index, btScalar damping)
+{
+	btAssert((index >= 0) && (index < 6));
+	m_springDamping[index] = damping;
+}
+
+
+void btGeneric6DofSpringConstraint::setEquilibriumPoint()
+{
+	calculateTransforms();
+	int i;
+
+	for( i = 0; i < 3; i++)
+	{
+		m_equilibriumPoint[i] = m_calculatedLinearDiff[i];
+	}
+	for(i = 0; i < 3; i++)
+	{
+		m_equilibriumPoint[i + 3] = m_calculatedAxisAngleDiff[i];
+	}
+}
+
+
+
+void btGeneric6DofSpringConstraint::setEquilibriumPoint(int index)
+{
+	btAssert((index >= 0) && (index < 6));
+	calculateTransforms();
+	if(index < 3)
+	{
+		m_equilibriumPoint[index] = m_calculatedLinearDiff[index];
+	}
+	else
+	{
+		m_equilibriumPoint[index] = m_calculatedAxisAngleDiff[index - 3];
+	}
+}
+
+void btGeneric6DofSpringConstraint::setEquilibriumPoint(int index, btScalar val)
+{
+	btAssert((index >= 0) && (index < 6));
+	m_equilibriumPoint[index] = val;
+}
+
+
+void btGeneric6DofSpringConstraint::internalUpdateSprings(btConstraintInfo2* info)
+{
+	// it is assumed that calculateTransforms() have been called before this call
+	int i;
+	btVector3 relVel = m_rbB.getLinearVelocity() - m_rbA.getLinearVelocity();
+	for(i = 0; i < 3; i++)
+	{
+		if(m_springEnabled[i])
+		{
+			// get current position of constraint
+			btScalar currPos = m_calculatedLinearDiff[i];
+			// calculate difference
+			btScalar delta = currPos - m_equilibriumPoint[i];
+			// spring force is (delta * m_stiffness) according to Hooke's Law
+			btScalar force = delta * m_springStiffness[i];
+			btScalar velFactor = info->fps * m_springDamping[i] / btScalar(info->m_numIterations);
+			m_linearLimits.m_targetVelocity[i] =  velFactor * force;
+			m_linearLimits.m_maxMotorForce[i] =  btFabs(force) / info->fps;
+		}
+	}
+	for(i = 0; i < 3; i++)
+	{
+		if(m_springEnabled[i + 3])
+		{
+			// get current position of constraint
+			btScalar currPos = m_calculatedAxisAngleDiff[i];
+			// calculate difference
+			btScalar delta = currPos - m_equilibriumPoint[i+3];
+			// spring force is (-delta * m_stiffness) according to Hooke's Law
+			btScalar force = -delta * m_springStiffness[i+3];
+			btScalar velFactor = info->fps * m_springDamping[i+3] / btScalar(info->m_numIterations);
+			m_angularLimits[i].m_targetVelocity = velFactor * force;
+			m_angularLimits[i].m_maxMotorForce = btFabs(force) / info->fps;
+		}
+	}
+}
+
+
+void btGeneric6DofSpringConstraint::getInfo2(btConstraintInfo2* info)
+{
+	// this will be called by constraint solver at the constraint setup stage
+	// set current motor parameters
+	internalUpdateSprings(info);
+	// do the rest of job for constraint setup
+	btGeneric6DofConstraint::getInfo2(info);
+}
+
+
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h	(revision 8284)
@@ -0,0 +1,55 @@
+/*
+Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
+Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. 
+
+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 GENERIC_6DOF_SPRING_CONSTRAINT_H
+#define GENERIC_6DOF_SPRING_CONSTRAINT_H
+
+
+#include "LinearMath/btVector3.h"
+#include "btTypedConstraint.h"
+#include "btGeneric6DofConstraint.h"
+
+
+/// Generic 6 DOF constraint that allows to set spring motors to any translational and rotational DOF
+
+/// DOF index used in enableSpring() and setStiffness() means:
+/// 0 : translation X
+/// 1 : translation Y
+/// 2 : translation Z
+/// 3 : rotation X (3rd Euler rotational around new position of X axis, range [-PI+epsilon, PI-epsilon] )
+/// 4 : rotation Y (2nd Euler rotational around new position of Y axis, range [-PI/2+epsilon, PI/2-epsilon] )
+/// 5 : rotation Z (1st Euler rotational around Z axis, range [-PI+epsilon, PI-epsilon] )
+
+class btGeneric6DofSpringConstraint : public btGeneric6DofConstraint
+{
+protected:
+	bool		m_springEnabled[6];
+	btScalar	m_equilibriumPoint[6];
+	btScalar	m_springStiffness[6];
+	btScalar	m_springDamping[6]; // between 0 and 1 (1 == no damping)
+	void internalUpdateSprings(btConstraintInfo2* info);
+public: 
+    btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
+	void enableSpring(int index, bool onOff);
+	void setStiffness(int index, btScalar stiffness);
+	void setDamping(int index, btScalar damping);
+	void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF
+	void setEquilibriumPoint(int index);  // set the current constraint position/orientation as an equilibrium point for given DOF
+	void setEquilibriumPoint(int index, btScalar val);
+	virtual void getInfo2 (btConstraintInfo2* info);
+};
+
+#endif // GENERIC_6DOF_SPRING_CONSTRAINT_H
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp	(revision 8284)
@@ -0,0 +1,66 @@
+/*
+Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
+Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. 
+
+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 "btHinge2Constraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btTransformUtil.h"
+
+
+
+// constructor
+// anchor, axis1 and axis2 are in world coordinate system
+// axis1 must be orthogonal to axis2
+btHinge2Constraint::btHinge2Constraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2)
+: btGeneric6DofSpringConstraint(rbA, rbB, btTransform::getIdentity(), btTransform::getIdentity(), true),
+ m_anchor(anchor),
+ m_axis1(axis1),
+ m_axis2(axis2)
+{
+	// build frame basis
+	// 6DOF constraint uses Euler angles and to define limits
+	// it is assumed that rotational order is :
+	// Z - first, allowed limits are (-PI,PI);
+	// new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number 
+	// used to prevent constraint from instability on poles;
+	// new position of X, allowed limits are (-PI,PI);
+	// So to simulate ODE Universal joint we should use parent axis as Z, child axis as Y and limit all other DOFs
+	// Build the frame in world coordinate system first
+	btVector3 zAxis = axis1.normalize();
+	btVector3 xAxis = axis2.normalize();
+	btVector3 yAxis = zAxis.cross(xAxis); // we want right coordinate system
+	btTransform frameInW;
+	frameInW.setIdentity();
+	frameInW.getBasis().setValue(	xAxis[0], yAxis[0], zAxis[0],	
+									xAxis[1], yAxis[1], zAxis[1],
+									xAxis[2], yAxis[2], zAxis[2]);
+	frameInW.setOrigin(anchor);
+	// now get constraint frame in local coordinate systems
+	m_frameInA = rbA.getCenterOfMassTransform().inverse() * frameInW;
+	m_frameInB = rbB.getCenterOfMassTransform().inverse() * frameInW;
+	// sei limits
+	setLinearLowerLimit(btVector3(0.f, 0.f, -1.f));
+	setLinearUpperLimit(btVector3(0.f, 0.f,  1.f));
+	// like front wheels of a car
+	setAngularLowerLimit(btVector3(1.f,  0.f, -SIMD_HALF_PI * 0.5f)); 
+	setAngularUpperLimit(btVector3(-1.f, 0.f,  SIMD_HALF_PI * 0.5f));
+	// enable suspension
+	enableSpring(2, true);
+	setStiffness(2, SIMD_PI * SIMD_PI * 4.f); // period 1 sec for 1 kilogramm weel :-)
+	setDamping(2, 0.01f);
+	setEquilibriumPoint();
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHinge2Constraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHinge2Constraint.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHinge2Constraint.h	(revision 8284)
@@ -0,0 +1,58 @@
+/*
+Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
+Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. 
+
+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 HINGE2_CONSTRAINT_H
+#define HINGE2_CONSTRAINT_H
+
+
+
+#include "LinearMath/btVector3.h"
+#include "btTypedConstraint.h"
+#include "btGeneric6DofSpringConstraint.h"
+
+
+
+// Constraint similar to ODE Hinge2 Joint
+// has 3 degrees of frredom:
+// 2 rotational degrees of freedom, similar to Euler rotations around Z (axis 1) and X (axis 2)
+// 1 translational (along axis Z) with suspension spring
+
+class btHinge2Constraint : public btGeneric6DofSpringConstraint
+{
+protected:
+	btVector3	m_anchor;
+	btVector3	m_axis1;
+	btVector3	m_axis2;
+public:
+	// constructor
+	// anchor, axis1 and axis2 are in world coordinate system
+	// axis1 must be orthogonal to axis2
+    btHinge2Constraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2);
+	// access
+	const btVector3& getAnchor() { return m_calculatedTransformA.getOrigin(); }
+	const btVector3& getAnchor2() { return m_calculatedTransformB.getOrigin(); }
+	const btVector3& getAxis1() { return m_axis1; }
+	const btVector3& getAxis2() { return m_axis2; }
+	btScalar getAngle1() { return getAngle(2); }
+	btScalar getAngle2() { return getAngle(0); }
+	// limits
+	void setUpperLimit(btScalar ang1max) { setAngularUpperLimit(btVector3(-1.f, 0.f, ang1max)); }
+	void setLowerLimit(btScalar ang1min) { setAngularLowerLimit(btVector3( 1.f, 0.f, ang1min)); }
+};
+
+
+
+#endif // HINGE2_CONSTRAINT_H
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp	(revision 8284)
@@ -22,29 +22,26 @@
 #include "btSolverBody.h"
 
-//-----------------------------------------------------------------------------
-
+
+
+//#define HINGE_USE_OBSOLETE_SOLVER false
 #define HINGE_USE_OBSOLETE_SOLVER false
 
-//-----------------------------------------------------------------------------
-
-
-btHingeConstraint::btHingeConstraint()
-: btTypedConstraint (HINGE_CONSTRAINT_TYPE),
-m_enableAngularMotor(false),
-m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
-m_useReferenceFrameA(false)
-{
-	m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
-}
-
-//-----------------------------------------------------------------------------
+#define HINGE_USE_FRAME_OFFSET true
+
+#ifndef __SPU__
+
+
+
+
 
 btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB,
-									 btVector3& axisInA,btVector3& axisInB, bool useReferenceFrameA)
+									 const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA)
 									 :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),
 									 m_angularOnly(false),
 									 m_enableAngularMotor(false),
 									 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
-									 m_useReferenceFrameA(useReferenceFrameA)
+									 m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET),
+									 m_useReferenceFrameA(useReferenceFrameA),
+									 m_flags(0)
 {
 	m_rbAFrame.getOrigin() = pivotInA;
@@ -80,6 +77,6 @@
 	
 	//start with free
-	m_lowerLimit = btScalar(1e30);
-	m_upperLimit = btScalar(-1e30);
+	m_lowerLimit = btScalar(1.0f);
+	m_upperLimit = btScalar(-1.0f);
 	m_biasFactor = 0.3f;
 	m_relaxationFactor = 1.0f;
@@ -89,10 +86,12 @@
 }
 
-//-----------------------------------------------------------------------------
-
-btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA, bool useReferenceFrameA)
+
+
+btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA)
 :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_angularOnly(false), m_enableAngularMotor(false), 
 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
-m_useReferenceFrameA(useReferenceFrameA)
+m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET),
+m_useReferenceFrameA(useReferenceFrameA),
+m_flags(0)
 {
 
@@ -120,6 +119,6 @@
 	
 	//start with free
-	m_lowerLimit = btScalar(1e30);
-	m_upperLimit = btScalar(-1e30);
+	m_lowerLimit = btScalar(1.0f);
+	m_upperLimit = btScalar(-1.0f);
 	m_biasFactor = 0.3f;
 	m_relaxationFactor = 1.0f;
@@ -129,5 +128,5 @@
 }
 
-//-----------------------------------------------------------------------------
+
 
 btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, 
@@ -137,9 +136,11 @@
 m_enableAngularMotor(false),
 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
-m_useReferenceFrameA(useReferenceFrameA)
+m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET),
+m_useReferenceFrameA(useReferenceFrameA),
+m_flags(0)
 {
 	//start with free
-	m_lowerLimit = btScalar(1e30);
-	m_upperLimit = btScalar(-1e30);
+	m_lowerLimit = btScalar(1.0f);
+	m_upperLimit = btScalar(-1.0f);
 	m_biasFactor = 0.3f;
 	m_relaxationFactor = 1.0f;
@@ -149,5 +150,5 @@
 }			
 
-//-----------------------------------------------------------------------------
+
 
 btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA)
@@ -156,5 +157,7 @@
 m_enableAngularMotor(false),
 m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
-m_useReferenceFrameA(useReferenceFrameA)
+m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET),
+m_useReferenceFrameA(useReferenceFrameA),
+m_flags(0)
 {
 	///not providing rigidbody B means implicitly using worldspace for body B
@@ -163,6 +166,6 @@
 
 	//start with free
-	m_lowerLimit = btScalar(1e30);
-	m_upperLimit = btScalar(-1e30);	
+	m_lowerLimit = btScalar(1.0f);
+	m_upperLimit = btScalar(-1.0f);
 	m_biasFactor = 0.3f;
 	m_relaxationFactor = 1.0f;
@@ -172,5 +175,5 @@
 }
 
-//-----------------------------------------------------------------------------
+
 
 void	btHingeConstraint::buildJacobian()
@@ -179,4 +182,5 @@
 	{
 		m_appliedImpulse = btScalar(0.);
+		m_accMotorImpulse = btScalar(0.);
 
 		if (!m_angularOnly)
@@ -222,5 +226,4 @@
 		btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local);
 
-		getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
 		btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local;
 		btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local;
@@ -249,5 +252,5 @@
 
 			// test angular limit
-			testLimit();
+			testLimit(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
 
 		//Compute K = J*W*J' for hinge axis
@@ -259,5 +262,7 @@
 }
 
-//-----------------------------------------------------------------------------
+
+#endif //__SPU__
+
 
 void btHingeConstraint::getInfo1(btConstraintInfo1* info)
@@ -272,6 +277,7 @@
 		info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular
 		info->nub = 1; 
+		//always add the row, to avoid computation (data is not available yet)
 		//prepare constraint
-		testLimit();
+		testLimit(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
 		if(getSolveLimit() || getEnableAngularMotor())
 		{
@@ -279,44 +285,113 @@
 			info->nub--; 
 		}
-	}
-} // btHingeConstraint::getInfo1 ()
-
-//-----------------------------------------------------------------------------
+
+	}
+}
+
+void btHingeConstraint::getInfo1NonVirtual(btConstraintInfo1* info)
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		info->m_numConstraintRows = 0;
+		info->nub = 0;
+	}
+	else
+	{
+		//always add the 'limit' row, to avoid computation (data is not available yet)
+		info->m_numConstraintRows = 6; // Fixed 3 linear + 2 angular
+		info->nub = 0; 
+	}
+}
 
 void btHingeConstraint::getInfo2 (btConstraintInfo2* info)
 {
+	if(m_useOffsetForConstraintFrame)
+	{
+		getInfo2InternalUsingFrameOffset(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getAngularVelocity(),m_rbB.getAngularVelocity());
+	}
+	else
+	{
+		getInfo2Internal(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getAngularVelocity(),m_rbB.getAngularVelocity());
+	}
+}
+
+
+void	btHingeConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB)
+{
+	///the regular (virtual) implementation getInfo2 already performs 'testLimit' during getInfo1, so we need to do it now
+	testLimit(transA,transB);
+
+	getInfo2Internal(info,transA,transB,angVelA,angVelB);
+}
+
+
+void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB)
+{
+
 	btAssert(!m_useSolveConstraintObsolete);
-	int i, s = info->rowskip;
+	int i, skip = info->rowskip;
 	// transforms in world space
-	btTransform trA = m_rbA.getCenterOfMassTransform()*m_rbAFrame;
-	btTransform trB = m_rbB.getCenterOfMassTransform()*m_rbBFrame;
+	btTransform trA = transA*m_rbAFrame;
+	btTransform trB = transB*m_rbBFrame;
 	// pivot point
 	btVector3 pivotAInW = trA.getOrigin();
 	btVector3 pivotBInW = trB.getOrigin();
+#if 0
+	if (0)
+	{
+		for (i=0;i<6;i++)
+		{
+			info->m_J1linearAxis[i*skip]=0;
+			info->m_J1linearAxis[i*skip+1]=0;
+			info->m_J1linearAxis[i*skip+2]=0;
+
+			info->m_J1angularAxis[i*skip]=0;
+			info->m_J1angularAxis[i*skip+1]=0;
+			info->m_J1angularAxis[i*skip+2]=0;
+
+			info->m_J2angularAxis[i*skip]=0;
+			info->m_J2angularAxis[i*skip+1]=0;
+			info->m_J2angularAxis[i*skip+2]=0;
+
+			info->m_constraintError[i*skip]=0.f;
+		}
+	}
+#endif //#if 0
 	// linear (all fixed)
-    info->m_J1linearAxis[0] = 1;
-    info->m_J1linearAxis[s + 1] = 1;
-    info->m_J1linearAxis[2 * s + 2] = 1;
-	btVector3 a1 = pivotAInW - m_rbA.getCenterOfMassTransform().getOrigin();
+
+	if (!m_angularOnly)
+	{
+		info->m_J1linearAxis[0] = 1;
+		info->m_J1linearAxis[skip + 1] = 1;
+		info->m_J1linearAxis[2 * skip + 2] = 1;
+	}	
+
+
+
+
+	btVector3 a1 = pivotAInW - transA.getOrigin();
 	{
 		btVector3* angular0 = (btVector3*)(info->m_J1angularAxis);
-		btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + s);
-		btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * s);
+		btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + skip);
+		btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * skip);
 		btVector3 a1neg = -a1;
 		a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
 	}
-	btVector3 a2 = pivotBInW - m_rbB.getCenterOfMassTransform().getOrigin();
+	btVector3 a2 = pivotBInW - transB.getOrigin();
 	{
 		btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
-		btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + s);
-		btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * s);
+		btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + skip);
+		btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * skip);
 		a2.getSkewSymmetricMatrix(angular0,angular1,angular2);
 	}
 	// linear RHS
     btScalar k = info->fps * info->erp;
-	for(i = 0; i < 3; i++)
-    {
-        info->m_constraintError[i * s] = k * (pivotBInW[i] - pivotAInW[i]);
-    }
+	if (!m_angularOnly)
+	{
+		for(i = 0; i < 3; i++)
+		{
+			info->m_constraintError[i * skip] = k * (pivotBInW[i] - pivotAInW[i]);
+		}
+	}
 	// make rotations around X and Y equal
 	// the hinge axis should be the only unconstrained
@@ -403,8 +478,12 @@
 		}
 		info->m_constraintError[srow] = btScalar(0.0f);
+		btScalar currERP = (m_flags & BT_HINGE_FLAGS_ERP_STOP) ? m_stopERP : info->erp;
 		if(powered)
 		{
-            info->cfm[srow] = btScalar(0.0); 
-			btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * info->erp);
+			if(m_flags & BT_HINGE_FLAGS_CFM_NORM)
+			{
+				info->cfm[srow] = m_normalCFM;
+			}
+			btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * currERP);
 			info->m_constraintError[srow] += mot_fact * m_motorTargetVelocity * m_referenceSign;
 			info->m_lowerLimit[srow] = - m_maxMotorImpulse;
@@ -413,7 +492,10 @@
 		if(limit)
 		{
-			k = info->fps * info->erp;
+			k = info->fps * currERP;
 			info->m_constraintError[srow] += k * limit_err;
-			info->cfm[srow] = btScalar(0.0);
+			if(m_flags & BT_HINGE_FLAGS_CFM_STOP)
+			{
+				info->cfm[srow] = m_stopCFM;
+			}
 			if(lostop == histop) 
 			{
@@ -436,6 +518,6 @@
 			if(bounce > btScalar(0.0))
 			{
-				btScalar vel = m_rbA.getAngularVelocity().dot(ax1);
-				vel -= m_rbB.getAngularVelocity().dot(ax1);
+				btScalar vel = angVelA.dot(ax1);
+				vel -= angVelB.dot(ax1);
 				// only apply bounce if the velocity is incoming, and if the
 				// resulting c[] exceeds what we already have.
@@ -468,153 +550,8 @@
 }
 
-//-----------------------------------------------------------------------------
-
-void	btHingeConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep)
-{
-
-	///for backwards compatibility during the transition to 'getInfo/getInfo2'
-	if (m_useSolveConstraintObsolete)
-	{
-
-		btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
-		btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
-
-		btScalar tau = btScalar(0.3);
-
-		//linear part
-		if (!m_angularOnly)
-		{
-			btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 
-			btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
-
-			btVector3 vel1,vel2;
-			bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
-			bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
-			btVector3 vel = vel1 - vel2;
-
-			for (int i=0;i<3;i++)
-			{		
-				const btVector3& normal = m_jac[i].m_linearJointAxis;
-				btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
-
-				btScalar rel_vel;
-				rel_vel = normal.dot(vel);
-				//positional error (zeroth order error)
-				btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
-				btScalar impulse = depth*tau/timeStep  * jacDiagABInv -  rel_vel * jacDiagABInv;
-				m_appliedImpulse += impulse;
-				btVector3 impulse_vector = normal * impulse;
-				btVector3 ftorqueAxis1 = rel_pos1.cross(normal);
-				btVector3 ftorqueAxis2 = rel_pos2.cross(normal);
-				bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse);
-				bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse);
-			}
-		}
-
-		
-		{
-			///solve angular part
-
-			// get axes in world space
-			btVector3 axisA =  getRigidBodyA().getCenterOfMassTransform().getBasis() *  m_rbAFrame.getBasis().getColumn(2);
-			btVector3 axisB =  getRigidBodyB().getCenterOfMassTransform().getBasis() *  m_rbBFrame.getBasis().getColumn(2);
-
-			btVector3 angVelA;
-			bodyA.getAngularVelocity(angVelA);
-			btVector3 angVelB;
-			bodyB.getAngularVelocity(angVelB);
-
-			btVector3 angVelAroundHingeAxisA = axisA * axisA.dot(angVelA);
-			btVector3 angVelAroundHingeAxisB = axisB * axisB.dot(angVelB);
-
-			btVector3 angAorthog = angVelA - angVelAroundHingeAxisA;
-			btVector3 angBorthog = angVelB - angVelAroundHingeAxisB;
-			btVector3 velrelOrthog = angAorthog-angBorthog;
-			{
-				
-
-				//solve orthogonal angular velocity correction
-				btScalar relaxation = btScalar(1.);
-				btScalar len = velrelOrthog.length();
-				if (len > btScalar(0.00001))
-				{
-					btVector3 normal = velrelOrthog.normalized();
-					btScalar denom = getRigidBodyA().computeAngularImpulseDenominator(normal) +
-						getRigidBodyB().computeAngularImpulseDenominator(normal);
-					// scale for mass and relaxation
-					//velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor;
-
-					bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*velrelOrthog,-(btScalar(1.)/denom));
-					bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*velrelOrthog,(btScalar(1.)/denom));
-
-				}
-
-				//solve angular positional correction
-				btVector3 angularError =  axisA.cross(axisB) *(btScalar(1.)/timeStep);
-				btScalar len2 = angularError.length();
-				if (len2>btScalar(0.00001))
-				{
-					btVector3 normal2 = angularError.normalized();
-					btScalar denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) +
-							getRigidBodyB().computeAngularImpulseDenominator(normal2);
-					//angularError *= (btScalar(1.)/denom2) * relaxation;
-					
-					bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*angularError,(btScalar(1.)/denom2));
-					bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*angularError,-(btScalar(1.)/denom2));
-
-				}
-				
-				
-
-
-
-				// solve limit
-				if (m_solveLimit)
-				{
-					btScalar amplitude = ( (angVelB - angVelA).dot( axisA )*m_relaxationFactor + m_correction* (btScalar(1.)/timeStep)*m_biasFactor  ) * m_limitSign;
-
-					btScalar impulseMag = amplitude * m_kHinge;
-
-					// Clamp the accumulated impulse
-					btScalar temp = m_accLimitImpulse;
-					m_accLimitImpulse = btMax(m_accLimitImpulse + impulseMag, btScalar(0) );
-					impulseMag = m_accLimitImpulse - temp;
-
-
-					
-					bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*axisA,impulseMag * m_limitSign);
-					bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*axisA,-(impulseMag * m_limitSign));
-
-				}
-			}
-
-			//apply motor
-			if (m_enableAngularMotor) 
-			{
-				//todo: add limits too
-				btVector3 angularLimit(0,0,0);
-
-				btVector3 velrel = angVelAroundHingeAxisA - angVelAroundHingeAxisB;
-				btScalar projRelVel = velrel.dot(axisA);
-
-				btScalar desiredMotorVel = m_motorTargetVelocity;
-				btScalar motor_relvel = desiredMotorVel - projRelVel;
-
-				btScalar unclippedMotorImpulse = m_kHinge * motor_relvel;;
-				//todo: should clip against accumulated impulse
-				btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse;
-				clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse;
-				btVector3 motorImp = clippedMotorImpulse * axisA;
-			
-				bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*axisA,clippedMotorImpulse);
-				bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*axisA,-clippedMotorImpulse);
-				
-			}
-		}
-	}
-
-}
-
-//-----------------------------------------------------------------------------
+
+
+
+
 
 void	btHingeConstraint::updateRHS(btScalar	timeStep)
@@ -624,17 +561,22 @@
 }
 
-//-----------------------------------------------------------------------------
 
 btScalar btHingeConstraint::getHingeAngle()
 {
-	const btVector3 refAxis0  = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(0);
-	const btVector3 refAxis1  = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(1);
-	const btVector3 swingAxis = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(1);
-	btScalar angle = btAtan2Fast(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1));
+	return getHingeAngle(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
+}
+
+btScalar btHingeConstraint::getHingeAngle(const btTransform& transA,const btTransform& transB)
+{
+	const btVector3 refAxis0  = transA.getBasis() * m_rbAFrame.getBasis().getColumn(0);
+	const btVector3 refAxis1  = transA.getBasis() * m_rbAFrame.getBasis().getColumn(1);
+	const btVector3 swingAxis = transB.getBasis() * m_rbBFrame.getBasis().getColumn(1);
+//	btScalar angle = btAtan2Fast(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1));
+	btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1));
 	return m_referenceSign * angle;
 }
 
-//-----------------------------------------------------------------------------
-
+
+#if 0
 void btHingeConstraint::testLimit()
 {
@@ -660,7 +602,403 @@
 	}
 	return;
-} // btHingeConstraint::testLimit()
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
+}
+#else
+
+
+void btHingeConstraint::testLimit(const btTransform& transA,const btTransform& transB)
+{
+	// Compute limit information
+	m_hingeAngle = getHingeAngle(transA,transB);
+	m_correction = btScalar(0.);
+	m_limitSign = btScalar(0.);
+	m_solveLimit = false;
+	if (m_lowerLimit <= m_upperLimit)
+	{
+		m_hingeAngle = btAdjustAngleToLimits(m_hingeAngle, m_lowerLimit, m_upperLimit);
+		if (m_hingeAngle <= m_lowerLimit)
+		{
+			m_correction = (m_lowerLimit - m_hingeAngle);
+			m_limitSign = 1.0f;
+			m_solveLimit = true;
+		} 
+		else if (m_hingeAngle >= m_upperLimit)
+		{
+			m_correction = m_upperLimit - m_hingeAngle;
+			m_limitSign = -1.0f;
+			m_solveLimit = true;
+		}
+	}
+	return;
+}
+#endif
+
+static btVector3 vHinge(0, 0, btScalar(1));
+
+void btHingeConstraint::setMotorTarget(const btQuaternion& qAinB, btScalar dt)
+{
+	// convert target from body to constraint space
+	btQuaternion qConstraint = m_rbBFrame.getRotation().inverse() * qAinB * m_rbAFrame.getRotation();
+	qConstraint.normalize();
+
+	// extract "pure" hinge component
+	btVector3 vNoHinge = quatRotate(qConstraint, vHinge); vNoHinge.normalize();
+	btQuaternion qNoHinge = shortestArcQuat(vHinge, vNoHinge);
+	btQuaternion qHinge = qNoHinge.inverse() * qConstraint;
+	qHinge.normalize();
+
+	// compute angular target, clamped to limits
+	btScalar targetAngle = qHinge.getAngle();
+	if (targetAngle > SIMD_PI) // long way around. flip quat and recalculate.
+	{
+		qHinge = operator-(qHinge);
+		targetAngle = qHinge.getAngle();
+	}
+	if (qHinge.getZ() < 0)
+		targetAngle = -targetAngle;
+
+	setMotorTarget(targetAngle, dt);
+}
+
+void btHingeConstraint::setMotorTarget(btScalar targetAngle, btScalar dt)
+{
+	if (m_lowerLimit < m_upperLimit)
+	{
+		if (targetAngle < m_lowerLimit)
+			targetAngle = m_lowerLimit;
+		else if (targetAngle > m_upperLimit)
+			targetAngle = m_upperLimit;
+	}
+
+	// compute angular velocity
+	btScalar curAngle  = getHingeAngle(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
+	btScalar dAngle = targetAngle - curAngle;
+	m_motorTargetVelocity = dAngle / dt;
+}
+
+
+
+void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB)
+{
+	btAssert(!m_useSolveConstraintObsolete);
+	int i, s = info->rowskip;
+	// transforms in world space
+	btTransform trA = transA*m_rbAFrame;
+	btTransform trB = transB*m_rbBFrame;
+	// pivot point
+	btVector3 pivotAInW = trA.getOrigin();
+	btVector3 pivotBInW = trB.getOrigin();
+#if 1
+	// difference between frames in WCS
+	btVector3 ofs = trB.getOrigin() - trA.getOrigin();
+	// now get weight factors depending on masses
+	btScalar miA = getRigidBodyA().getInvMass();
+	btScalar miB = getRigidBodyB().getInvMass();
+	bool hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON);
+	btScalar miS = miA + miB;
+	btScalar factA, factB;
+	if(miS > btScalar(0.f))
+	{
+		factA = miB / miS;
+	}
+	else 
+	{
+		factA = btScalar(0.5f);
+	}
+	factB = btScalar(1.0f) - factA;
+	// get the desired direction of hinge axis
+	// as weighted sum of Z-orthos of frameA and frameB in WCS
+	btVector3 ax1A = trA.getBasis().getColumn(2);
+	btVector3 ax1B = trB.getBasis().getColumn(2);
+	btVector3 ax1 = ax1A * factA + ax1B * factB;
+	ax1.normalize();
+	// fill first 3 rows 
+	// we want: velA + wA x relA == velB + wB x relB
+	btTransform bodyA_trans = transA;
+	btTransform bodyB_trans = transB;
+	int s0 = 0;
+	int s1 = s;
+	int s2 = s * 2;
+	int nrow = 2; // last filled row
+	btVector3 tmpA, tmpB, relA, relB, p, q;
+	// get vector from bodyB to frameB in WCS
+	relB = trB.getOrigin() - bodyB_trans.getOrigin();
+	// get its projection to hinge axis
+	btVector3 projB = ax1 * relB.dot(ax1);
+	// get vector directed from bodyB to hinge axis (and orthogonal to it)
+	btVector3 orthoB = relB - projB;
+	// same for bodyA
+	relA = trA.getOrigin() - bodyA_trans.getOrigin();
+	btVector3 projA = ax1 * relA.dot(ax1);
+	btVector3 orthoA = relA - projA;
+	btVector3 totalDist = projA - projB;
+	// get offset vectors relA and relB
+	relA = orthoA + totalDist * factA;
+	relB = orthoB - totalDist * factB;
+	// now choose average ortho to hinge axis
+	p = orthoB * factA + orthoA * factB;
+	btScalar len2 = p.length2();
+	if(len2 > SIMD_EPSILON)
+	{
+		p /= btSqrt(len2);
+	}
+	else
+	{
+		p = trA.getBasis().getColumn(1);
+	}
+	// make one more ortho
+	q = ax1.cross(p);
+	// fill three rows
+	tmpA = relA.cross(p);
+	tmpB = relB.cross(p);
+    for (i=0; i<3; i++) info->m_J1angularAxis[s0+i] = tmpA[i];
+    for (i=0; i<3; i++) info->m_J2angularAxis[s0+i] = -tmpB[i];
+	tmpA = relA.cross(q);
+	tmpB = relB.cross(q);
+	if(hasStaticBody && getSolveLimit())
+	{ // to make constraint between static and dynamic objects more rigid
+		// remove wA (or wB) from equation if angular limit is hit
+		tmpB *= factB;
+		tmpA *= factA;
+	}
+	for (i=0; i<3; i++) info->m_J1angularAxis[s1+i] = tmpA[i];
+    for (i=0; i<3; i++) info->m_J2angularAxis[s1+i] = -tmpB[i];
+	tmpA = relA.cross(ax1);
+	tmpB = relB.cross(ax1);
+	if(hasStaticBody)
+	{ // to make constraint between static and dynamic objects more rigid
+		// remove wA (or wB) from equation
+		tmpB *= factB;
+		tmpA *= factA;
+	}
+	for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = tmpA[i];
+    for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = -tmpB[i];
+
+	btScalar k = info->fps * info->erp;
+
+	if (!m_angularOnly)
+	{
+		for (i=0; i<3; i++) info->m_J1linearAxis[s0+i] = p[i];
+		for (i=0; i<3; i++) info->m_J1linearAxis[s1+i] = q[i];
+		for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = ax1[i];
+	
+	// compute three elements of right hand side
+	
+		btScalar rhs = k * p.dot(ofs);
+		info->m_constraintError[s0] = rhs;
+		rhs = k * q.dot(ofs);
+		info->m_constraintError[s1] = rhs;
+		rhs = k * ax1.dot(ofs);
+		info->m_constraintError[s2] = rhs;
+	}
+	// the hinge axis should be the only unconstrained
+	// rotational axis, the angular velocity of the two bodies perpendicular to
+	// the hinge axis should be equal. thus the constraint equations are
+	//    p*w1 - p*w2 = 0
+	//    q*w1 - q*w2 = 0
+	// where p and q are unit vectors normal to the hinge axis, and w1 and w2
+	// are the angular velocity vectors of the two bodies.
+	int s3 = 3 * s;
+	int s4 = 4 * s;
+	info->m_J1angularAxis[s3 + 0] = p[0];
+	info->m_J1angularAxis[s3 + 1] = p[1];
+	info->m_J1angularAxis[s3 + 2] = p[2];
+	info->m_J1angularAxis[s4 + 0] = q[0];
+	info->m_J1angularAxis[s4 + 1] = q[1];
+	info->m_J1angularAxis[s4 + 2] = q[2];
+
+	info->m_J2angularAxis[s3 + 0] = -p[0];
+	info->m_J2angularAxis[s3 + 1] = -p[1];
+	info->m_J2angularAxis[s3 + 2] = -p[2];
+	info->m_J2angularAxis[s4 + 0] = -q[0];
+	info->m_J2angularAxis[s4 + 1] = -q[1];
+	info->m_J2angularAxis[s4 + 2] = -q[2];
+	// compute the right hand side of the constraint equation. set relative
+	// body velocities along p and q to bring the hinge back into alignment.
+	// if ax1A,ax1B are the unit length hinge axes as computed from bodyA and
+	// bodyB, we need to rotate both bodies along the axis u = (ax1 x ax2).
+	// if "theta" is the angle between ax1 and ax2, we need an angular velocity
+	// along u to cover angle erp*theta in one step :
+	//   |angular_velocity| = angle/time = erp*theta / stepsize
+	//                      = (erp*fps) * theta
+	//    angular_velocity  = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2|
+	//                      = (erp*fps) * theta * (ax1 x ax2) / sin(theta)
+	// ...as ax1 and ax2 are unit length. if theta is smallish,
+	// theta ~= sin(theta), so
+	//    angular_velocity  = (erp*fps) * (ax1 x ax2)
+	// ax1 x ax2 is in the plane space of ax1, so we project the angular
+	// velocity to p and q to find the right hand side.
+	k = info->fps * info->erp;
+	btVector3 u = ax1A.cross(ax1B);
+	info->m_constraintError[s3] = k * u.dot(p);
+	info->m_constraintError[s4] = k * u.dot(q);
+#endif
+	// check angular limits
+	nrow = 4; // last filled row
+	int srow;
+	btScalar limit_err = btScalar(0.0);
+	int limit = 0;
+	if(getSolveLimit())
+	{
+		limit_err = m_correction * m_referenceSign;
+		limit = (limit_err > btScalar(0.0)) ? 1 : 2;
+	}
+	// if the hinge has joint limits or motor, add in the extra row
+	int powered = 0;
+	if(getEnableAngularMotor())
+	{
+		powered = 1;
+	}
+	if(limit || powered) 
+	{
+		nrow++;
+		srow = nrow * info->rowskip;
+		info->m_J1angularAxis[srow+0] = ax1[0];
+		info->m_J1angularAxis[srow+1] = ax1[1];
+		info->m_J1angularAxis[srow+2] = ax1[2];
+
+		info->m_J2angularAxis[srow+0] = -ax1[0];
+		info->m_J2angularAxis[srow+1] = -ax1[1];
+		info->m_J2angularAxis[srow+2] = -ax1[2];
+
+		btScalar lostop = getLowerLimit();
+		btScalar histop = getUpperLimit();
+		if(limit && (lostop == histop))
+		{  // the joint motor is ineffective
+			powered = 0;
+		}
+		info->m_constraintError[srow] = btScalar(0.0f);
+		btScalar currERP = (m_flags & BT_HINGE_FLAGS_ERP_STOP) ? m_stopERP : info->erp;
+		if(powered)
+		{
+			if(m_flags & BT_HINGE_FLAGS_CFM_NORM)
+			{
+				info->cfm[srow] = m_normalCFM;
+			}
+			btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * currERP);
+			info->m_constraintError[srow] += mot_fact * m_motorTargetVelocity * m_referenceSign;
+			info->m_lowerLimit[srow] = - m_maxMotorImpulse;
+			info->m_upperLimit[srow] =   m_maxMotorImpulse;
+		}
+		if(limit)
+		{
+			k = info->fps * currERP;
+			info->m_constraintError[srow] += k * limit_err;
+			if(m_flags & BT_HINGE_FLAGS_CFM_STOP)
+			{
+				info->cfm[srow] = m_stopCFM;
+			}
+			if(lostop == histop) 
+			{
+				// limited low and high simultaneously
+				info->m_lowerLimit[srow] = -SIMD_INFINITY;
+				info->m_upperLimit[srow] = SIMD_INFINITY;
+			}
+			else if(limit == 1) 
+			{ // low limit
+				info->m_lowerLimit[srow] = 0;
+				info->m_upperLimit[srow] = SIMD_INFINITY;
+			}
+			else 
+			{ // high limit
+				info->m_lowerLimit[srow] = -SIMD_INFINITY;
+				info->m_upperLimit[srow] = 0;
+			}
+			// bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that)
+			btScalar bounce = m_relaxationFactor;
+			if(bounce > btScalar(0.0))
+			{
+				btScalar vel = angVelA.dot(ax1);
+				vel -= angVelB.dot(ax1);
+				// only apply bounce if the velocity is incoming, and if the
+				// resulting c[] exceeds what we already have.
+				if(limit == 1)
+				{	// low limit
+					if(vel < 0)
+					{
+						btScalar newc = -bounce * vel;
+						if(newc > info->m_constraintError[srow])
+						{
+							info->m_constraintError[srow] = newc;
+						}
+					}
+				}
+				else
+				{	// high limit - all those computations are reversed
+					if(vel > 0)
+					{
+						btScalar newc = -bounce * vel;
+						if(newc < info->m_constraintError[srow])
+						{
+							info->m_constraintError[srow] = newc;
+						}
+					}
+				}
+			}
+			info->m_constraintError[srow] *= m_biasFactor;
+		} // if(limit)
+	} // if angular limit or powered
+}
+
+
+///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+///If no axis is provided, it uses the default axis for this constraint.
+void btHingeConstraint::setParam(int num, btScalar value, int axis)
+{
+	if((axis == -1) || (axis == 5))
+	{
+		switch(num)
+		{	
+			case BT_CONSTRAINT_STOP_ERP :
+				m_stopERP = value;
+				m_flags |= BT_HINGE_FLAGS_ERP_STOP;
+				break;
+			case BT_CONSTRAINT_STOP_CFM :
+				m_stopCFM = value;
+				m_flags |= BT_HINGE_FLAGS_CFM_STOP;
+				break;
+			case BT_CONSTRAINT_CFM :
+				m_normalCFM = value;
+				m_flags |= BT_HINGE_FLAGS_CFM_NORM;
+				break;
+			default : 
+				btAssertConstrParams(0);
+		}
+	}
+	else
+	{
+		btAssertConstrParams(0);
+	}
+}
+
+///return the local value of parameter
+btScalar btHingeConstraint::getParam(int num, int axis) const 
+{
+	btScalar retVal = 0;
+	if((axis == -1) || (axis == 5))
+	{
+		switch(num)
+		{	
+			case BT_CONSTRAINT_STOP_ERP :
+				btAssertConstrParams(m_flags & BT_HINGE_FLAGS_ERP_STOP);
+				retVal = m_stopERP;
+				break;
+			case BT_CONSTRAINT_STOP_CFM :
+				btAssertConstrParams(m_flags & BT_HINGE_FLAGS_CFM_STOP);
+				retVal = m_stopCFM;
+				break;
+			case BT_CONSTRAINT_CFM :
+				btAssertConstrParams(m_flags & BT_HINGE_FLAGS_CFM_NORM);
+				retVal = m_normalCFM;
+				break;
+			default : 
+				btAssertConstrParams(0);
+		}
+	}
+	else
+	{
+		btAssertConstrParams(0);
+	}
+	return retVal;
+}
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.h	(revision 8284)
@@ -25,7 +25,24 @@
 class btRigidBody;
 
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btHingeConstraintData	btHingeConstraintDoubleData
+#define btHingeConstraintDataName	"btHingeConstraintDoubleData"
+#else
+#define btHingeConstraintData	btHingeConstraintFloatData
+#define btHingeConstraintDataName	"btHingeConstraintFloatData"
+#endif //BT_USE_DOUBLE_PRECISION
+
+
+enum btHingeFlags
+{
+	BT_HINGE_FLAGS_CFM_STOP = 1,
+	BT_HINGE_FLAGS_ERP_STOP = 2,
+	BT_HINGE_FLAGS_CFM_NORM = 4
+};
+
+
 /// hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space
 /// axis defines the orientation of the hinge axis
-class btHingeConstraint : public btTypedConstraint
+ATTRIBUTE_ALIGNED16(class) btHingeConstraint : public btTypedConstraint
 {
 #ifdef IN_PARALLELL_SOLVER
@@ -61,12 +78,20 @@
 	bool		m_solveLimit;
 	bool		m_useSolveConstraintObsolete;
+	bool		m_useOffsetForConstraintFrame;
 	bool		m_useReferenceFrameA;
 
+	btScalar	m_accMotorImpulse;
+
+	int			m_flags;
+	btScalar	m_normalCFM;
+	btScalar	m_stopCFM;
+	btScalar	m_stopERP;
+
 	
 public:
 
-	btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btVector3& axisInA,btVector3& axisInB, bool useReferenceFrameA = false);
-
-	btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA, bool useReferenceFrameA = false);
+	btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false);
+
+	btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false);
 	
 	btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
@@ -74,5 +99,4 @@
 	btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false);
 
-	btHingeConstraint();
 
 	virtual void	buildJacobian();
@@ -80,7 +104,13 @@
 	virtual void getInfo1 (btConstraintInfo1* info);
 
+	void getInfo1NonVirtual(btConstraintInfo1* info);
+
 	virtual void getInfo2 (btConstraintInfo2* info);
-	
-	virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+
+	void	getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
+
+	void	getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
+	void	getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB);
+		
 
 	void	updateRHS(btScalar	timeStep);
@@ -117,8 +147,17 @@
 	}
 
+	// extra motor API, including ability to set a target rotation (as opposed to angular velocity)
+	// note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to
+	//       maintain a given angular target.
+	void enableMotor(bool enableMotor) 	{ m_enableAngularMotor = enableMotor; }
+	void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; }
+	void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B.
+	void setMotorTarget(btScalar targetAngle, btScalar dt);
+
+
 	void	setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
 	{
-		m_lowerLimit = low;
-		m_upperLimit = high;
+		m_lowerLimit = btNormalizeAngle(low);
+		m_upperLimit = btNormalizeAngle(high);
 
 		m_limitSoftness =  _softness;
@@ -128,4 +167,27 @@
 	}
 
+	void	setAxis(btVector3& axisInA)
+	{
+		btVector3 rbAxisA1, rbAxisA2;
+		btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
+		btVector3 pivotInA = m_rbAFrame.getOrigin();
+//		m_rbAFrame.getOrigin() = pivotInA;
+		m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(),
+										rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(),
+										rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() );
+
+		btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA;
+
+		btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
+		btVector3 rbAxisB1 =  quatRotate(rotationArc,rbAxisA1);
+		btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
+
+
+		m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(pivotInA);
+		m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(),
+										rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(),
+										rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() );
+	}
+
 	btScalar	getLowerLimit() const
 	{
@@ -141,9 +203,14 @@
 	btScalar getHingeAngle();
 
-	void testLimit();
-
-
-	const btTransform& getAFrame() { return m_rbAFrame; };	
-	const btTransform& getBFrame() { return m_rbBFrame; };
+	btScalar getHingeAngle(const btTransform& transA,const btTransform& transB);
+
+	void testLimit(const btTransform& transA,const btTransform& transB);
+
+
+	const btTransform& getAFrame() const { return m_rbAFrame; };	
+	const btTransform& getBFrame() const { return m_rbBFrame; };
+
+	btTransform& getAFrame() { return m_rbAFrame; };	
+	btTransform& getBFrame() { return m_rbBFrame; };
 
 	inline int getSolveLimit()
@@ -173,6 +240,93 @@
 		return m_maxMotorImpulse; 
 	}
+	// access for UseFrameOffset
+	bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
+	void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
+
+
+	///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+	///If no axis is provided, it uses the default axis for this constraint.
+	virtual	void	setParam(int num, btScalar value, int axis = -1);
+	///return the local value of parameter
+	virtual	btScalar getParam(int num, int axis = -1) const;
+
+	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	btHingeConstraintDoubleData
+{
+	btTypedConstraintData	m_typeConstraintData;
+	btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
+	btTransformDoubleData m_rbBFrame;
+	int			m_useReferenceFrameA;
+	int			m_angularOnly;
+	int			m_enableAngularMotor;
+	float	m_motorTargetVelocity;
+	float	m_maxMotorImpulse;
+
+	float	m_lowerLimit;
+	float	m_upperLimit;
+	float	m_limitSoftness;
+	float	m_biasFactor;
+	float	m_relaxationFactor;
+
+};
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btHingeConstraintFloatData
+{
+	btTypedConstraintData	m_typeConstraintData;
+	btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
+	btTransformFloatData m_rbBFrame;
+	int			m_useReferenceFrameA;
+	int			m_angularOnly;
+	
+	int			m_enableAngularMotor;
+	float	m_motorTargetVelocity;
+	float	m_maxMotorImpulse;
+
+	float	m_lowerLimit;
+	float	m_upperLimit;
+	float	m_limitSoftness;
+	float	m_biasFactor;
+	float	m_relaxationFactor;
+
+};
+
+
+
+SIMD_FORCE_INLINE	int	btHingeConstraint::calculateSerializeBufferSize() const
+{
+	return sizeof(btHingeConstraintData);
+}
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+SIMD_FORCE_INLINE	const char*	btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const
+{
+	btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer;
+	btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer);
+
+	m_rbAFrame.serialize(hingeData->m_rbAFrame);
+	m_rbBFrame.serialize(hingeData->m_rbBFrame);
+
+	hingeData->m_angularOnly = m_angularOnly;
+	hingeData->m_enableAngularMotor = m_enableAngularMotor;
+	hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse);
+	hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity);
+	hingeData->m_useReferenceFrameA = m_useReferenceFrameA;
+	
+	hingeData->m_lowerLimit = float(m_lowerLimit);
+	hingeData->m_upperLimit = float(m_upperLimit);
+	hingeData->m_limitSoftness = float(m_limitSoftness);
+	hingeData->m_biasFactor = float(m_biasFactor);
+	hingeData->m_relaxationFactor = float(m_relaxationFactor);
+
+	return btHingeConstraintDataName;
+}
+
 #endif //HINGECONSTRAINT_H
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btJacobianEntry.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btJacobianEntry.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btJacobianEntry.h	(revision 8284)
@@ -29,5 +29,5 @@
 /// it can be used in combination with a constraint solver
 /// Can be used to relate the effect of an impulse to the constraint error
-class btJacobianEntry
+ATTRIBUTE_ALIGNED16(class) btJacobianEntry
 {
 public:
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp	(revision 8284)
@@ -21,12 +21,9 @@
 
 
-btPoint2PointConstraint::btPoint2PointConstraint()
-:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE),
-m_useSolveConstraintObsolete(false)
-{
-}
+
 
 btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB)
 :btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB),
+m_flags(0),
 m_useSolveConstraintObsolete(false)
 {
@@ -37,4 +34,5 @@
 btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA)
 :btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)),
+m_flags(0),
 m_useSolveConstraintObsolete(false)
 {
@@ -44,4 +42,5 @@
 void	btPoint2PointConstraint::buildJacobian()
 {
+
 	///we need it for both methods
 	{
@@ -67,8 +66,13 @@
 	}
 
-}
-
+
+}
 
 void btPoint2PointConstraint::getInfo1 (btConstraintInfo1* info)
+{
+	getInfo1NonVirtual(info);
+}
+
+void btPoint2PointConstraint::getInfo1NonVirtual (btConstraintInfo1* info)
 {
 	if (m_useSolveConstraintObsolete)
@@ -83,13 +87,17 @@
 }
 
+
+
+
 void btPoint2PointConstraint::getInfo2 (btConstraintInfo2* info)
 {
+	getInfo2NonVirtual(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
+}
+
+void btPoint2PointConstraint::getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& body0_trans, const btTransform& body1_trans)
+{
 	btAssert(!m_useSolveConstraintObsolete);
 
 	 //retrieve matrices
-	btTransform body0_trans;
-	body0_trans = m_rbA.getCenterOfMassTransform();
-    btTransform body1_trans;
-	body1_trans = m_rbB.getCenterOfMassTransform();
 
 	// anchor points in global coordinates with respect to body PORs.
@@ -97,6 +105,6 @@
     // set jacobian
     info->m_J1linearAxis[0] = 1;
-    info->m_J1linearAxis[info->rowskip+1] = 1;
-    info->m_J1linearAxis[2*info->rowskip+2] = 1;
+	info->m_J1linearAxis[info->rowskip+1] = 1;
+	info->m_J1linearAxis[2*info->rowskip+2] = 1;
 
 	btVector3 a1 = body0_trans.getBasis()*getPivotInA();
@@ -127,12 +135,19 @@
 
     // set right hand side
-    btScalar k = info->fps * info->erp;
+	btScalar currERP = (m_flags & BT_P2P_FLAGS_ERP) ? m_erp : info->erp;
+    btScalar k = info->fps * currERP;
     int j;
-
 	for (j=0; j<3; j++)
     {
-        info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] -                     a1[j] - body0_trans.getOrigin()[j]);
+        info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]);
 		//printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]);
     }
+	if(m_flags & BT_P2P_FLAGS_CFM)
+	{
+		for (j=0; j<3; j++)
+		{
+			info->cfm[j*info->rowskip] = m_cfm;
+		}
+	}
 
 	btScalar impulseClamp = m_setting.m_impulseClamp;//
@@ -145,81 +160,9 @@
 		}
 	}
-	
-}
-
-
-void	btPoint2PointConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep)
-{
-	if (m_useSolveConstraintObsolete)
-	{
-		btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA;
-		btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB;
-
-
-		btVector3 normal(0,0,0);
-		
-
-	//	btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity();
-	//	btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity();
-
-		for (int i=0;i<3;i++)
-		{		
-			normal[i] = 1;
-			btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
-
-			btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); 
-			btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
-			//this jacobian entry could be re-used for all iterations
-			
-			btVector3 vel1,vel2;
-			bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
-			bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
-			btVector3 vel = vel1 - vel2;
-			
-			btScalar rel_vel;
-			rel_vel = normal.dot(vel);
-
-		/*
-			//velocity error (first order error)
-			btScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA,
-															m_rbB.getLinearVelocity(),angvelB);
-		*/
-		
-			//positional error (zeroth order error)
-			btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
-			
-			btScalar deltaImpulse = depth*m_setting.m_tau/timeStep  * jacDiagABInv -  m_setting.m_damping * rel_vel * jacDiagABInv;
-
-			btScalar impulseClamp = m_setting.m_impulseClamp;
-			
-			const btScalar sum = btScalar(m_appliedImpulse) + deltaImpulse;
-			if (sum < -impulseClamp)
-			{
-				deltaImpulse = -impulseClamp-m_appliedImpulse;
-				m_appliedImpulse = -impulseClamp;
-			}
-			else if (sum > impulseClamp) 
-			{
-				deltaImpulse = impulseClamp-m_appliedImpulse;
-				m_appliedImpulse = impulseClamp;
-			}
-			else
-			{
-				m_appliedImpulse = sum;
-			}
-
-			
-			btVector3 impulse_vector = normal * deltaImpulse;
-			
-			btVector3 ftorqueAxis1 = rel_pos1.cross(normal);
-			btVector3 ftorqueAxis2 = rel_pos2.cross(normal);
-			bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,deltaImpulse);
-			bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-deltaImpulse);
-
-
-			normal[i] = 0;
-		}
-	}
-}
+	info->m_damping = m_setting.m_damping;
+	
+}
+
+
 
 void	btPoint2PointConstraint::updateRHS(btScalar	timeStep)
@@ -229,2 +172,59 @@
 }
 
+///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+///If no axis is provided, it uses the default axis for this constraint.
+void btPoint2PointConstraint::setParam(int num, btScalar value, int axis)
+{
+	if(axis != -1)
+	{
+		btAssertConstrParams(0);
+	}
+	else
+	{
+		switch(num)
+		{
+			case BT_CONSTRAINT_ERP :
+			case BT_CONSTRAINT_STOP_ERP :
+				m_erp = value; 
+				m_flags |= BT_P2P_FLAGS_ERP;
+				break;
+			case BT_CONSTRAINT_CFM :
+			case BT_CONSTRAINT_STOP_CFM :
+				m_cfm = value; 
+				m_flags |= BT_P2P_FLAGS_CFM;
+				break;
+			default: 
+				btAssertConstrParams(0);
+		}
+	}
+}
+
+///return the local value of parameter
+btScalar btPoint2PointConstraint::getParam(int num, int axis) const 
+{
+	btScalar retVal(SIMD_INFINITY);
+	if(axis != -1)
+	{
+		btAssertConstrParams(0);
+	}
+	else
+	{
+		switch(num)
+		{
+			case BT_CONSTRAINT_ERP :
+			case BT_CONSTRAINT_STOP_ERP :
+				btAssertConstrParams(m_flags & BT_P2P_FLAGS_ERP);
+				retVal = m_erp; 
+				break;
+			case BT_CONSTRAINT_CFM :
+			case BT_CONSTRAINT_STOP_CFM :
+				btAssertConstrParams(m_flags & BT_P2P_FLAGS_CFM);
+				retVal = m_cfm; 
+				break;
+			default: 
+				btAssertConstrParams(0);
+		}
+	}
+	return retVal;
+}
+	
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h	(revision 8284)
@@ -23,4 +23,13 @@
 class btRigidBody;
 
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btPoint2PointConstraintData	btPoint2PointConstraintDoubleData
+#define btPoint2PointConstraintDataName	"btPoint2PointConstraintDoubleData"
+#else
+#define btPoint2PointConstraintData	btPoint2PointConstraintFloatData
+#define btPoint2PointConstraintDataName	"btPoint2PointConstraintFloatData"
+#endif //BT_USE_DOUBLE_PRECISION
+
 struct	btConstraintSetting
 {
@@ -36,6 +45,12 @@
 };
 
+enum btPoint2PointFlags
+{
+	BT_P2P_FLAGS_ERP = 1,
+	BT_P2P_FLAGS_CFM = 2
+};
+
 /// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space
-class btPoint2PointConstraint : public btTypedConstraint
+ATTRIBUTE_ALIGNED16(class) btPoint2PointConstraint : public btTypedConstraint
 {
 #ifdef IN_PARALLELL_SOLVER
@@ -47,5 +62,7 @@
 	btVector3	m_pivotInB;
 	
-	
+	int			m_flags;
+	btScalar	m_erp;
+	btScalar	m_cfm;
 	
 public:
@@ -60,5 +77,4 @@
 	btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA);
 
-	btPoint2PointConstraint();
 
 	virtual void	buildJacobian();
@@ -66,8 +82,9 @@
 	virtual void getInfo1 (btConstraintInfo1* info);
 
+	void getInfo1NonVirtual (btConstraintInfo1* info);
+
 	virtual void getInfo2 (btConstraintInfo2* info);
 
-
-	virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+	void getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& body0_trans, const btTransform& body1_trans);
 
 	void	updateRHS(btScalar	timeStep);
@@ -93,6 +110,52 @@
 	}
 
+	///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+	///If no axis is provided, it uses the default axis for this constraint.
+	virtual	void	setParam(int num, btScalar value, int axis = -1);
+	///return the local value of parameter
+	virtual	btScalar getParam(int num, int axis = -1) const;
+
+	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	btPoint2PointConstraintFloatData
+{
+	btTypedConstraintData	m_typeConstraintData;
+	btVector3FloatData	m_pivotInA;
+	btVector3FloatData	m_pivotInB;
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btPoint2PointConstraintDoubleData
+{
+	btTypedConstraintData	m_typeConstraintData;
+	btVector3DoubleData	m_pivotInA;
+	btVector3DoubleData	m_pivotInB;
+};
+
+
+SIMD_FORCE_INLINE	int	btPoint2PointConstraint::calculateSerializeBufferSize() const
+{
+	return sizeof(btPoint2PointConstraintData);
+
+}
+
+	///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;
+
+	btTypedConstraint::serialize(&p2pData->m_typeConstraintData,serializer);
+	m_pivotInA.serialize(p2pData->m_pivotInA);
+	m_pivotInB.serialize(p2pData->m_pivotInB);
+
+	return btPoint2PointConstraintDataName;
+}
+
 #endif //POINT2POINTCONSTRAINT_H
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp	(revision 8284)
@@ -35,4 +35,6 @@
 #include <string.h> //for memset
 
+int		gNumSplitImpulseRecoveries = 0;
+
 btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
 :m_btSeed2(0)
@@ -56,5 +58,5 @@
 
 // Project Gauss Seidel or the equivalent Sequential Impulse
-void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
+void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
 {
 #ifdef USE_SIMD
@@ -63,6 +65,6 @@
 	__m128	upperLimit1 = _mm_set1_ps(c.m_upperLimit);
 	__m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm)));
-	__m128 deltaVel1Dotn	=	_mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.m_deltaLinearVelocity.mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.m_deltaAngularVelocity.mVec128));
-	__m128 deltaVel2Dotn	=	_mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.m_deltaAngularVelocity.mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.m_deltaLinearVelocity.mVec128));
+	__m128 deltaVel1Dotn	=	_mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
+	__m128 deltaVel2Dotn	=	_mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128));
 	deltaImpulse	=	_mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
 	deltaImpulse	=	_mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
@@ -77,11 +79,11 @@
 	deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) );
 	c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1) );
-	__m128	linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,_mm_set1_ps(body1.m_invMass));
-	__m128	linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,_mm_set1_ps(body2.m_invMass));
+	__m128	linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
+	__m128	linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
 	__m128 impulseMagnitude = deltaImpulse;
-	body1.m_deltaLinearVelocity.mVec128 = _mm_add_ps(body1.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
-	body1.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body1.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
-	body2.m_deltaLinearVelocity.mVec128 = _mm_sub_ps(body2.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
-	body2.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body2.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
+	body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
+	body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
+	body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
+	body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
 #else
 	resolveSingleConstraintRowGeneric(body1,body2,c);
@@ -90,11 +92,11 @@
 
 // Project Gauss Seidel or the equivalent Sequential Impulse
- void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
 {
 	btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
-	const btScalar deltaVel1Dotn	=	c.m_contactNormal.dot(body1.m_deltaLinearVelocity) 	+ c.m_relpos1CrossNormal.dot(body1.m_deltaAngularVelocity);
-	const btScalar deltaVel2Dotn	=	-c.m_contactNormal.dot(body2.m_deltaLinearVelocity) + c.m_relpos2CrossNormal.dot(body2.m_deltaAngularVelocity);
-
-	const btScalar delta_rel_vel	=	deltaVel1Dotn-deltaVel2Dotn;
+	const btScalar deltaVel1Dotn	=	c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) 	+ c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
+	const btScalar deltaVel2Dotn	=	-c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
+
+//	const btScalar delta_rel_vel	=	deltaVel1Dotn-deltaVel2Dotn;
 	deltaImpulse	-=	deltaVel1Dotn*c.m_jacDiagABInv;
 	deltaImpulse	-=	deltaVel2Dotn*c.m_jacDiagABInv;
@@ -115,11 +117,9 @@
 		c.m_appliedImpulse = sum;
 	}
-	if (body1.m_invMass)
-		body1.applyImpulse(c.m_contactNormal*body1.m_invMass,c.m_angularComponentA,deltaImpulse);
-	if (body2.m_invMass)
-		body2.applyImpulse(-c.m_contactNormal*body2.m_invMass,c.m_angularComponentB,deltaImpulse);
-}
-
- void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
+		body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
+		body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
+}
+
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
 {
 #ifdef USE_SIMD
@@ -128,6 +128,6 @@
 	__m128	upperLimit1 = _mm_set1_ps(c.m_upperLimit);
 	__m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm)));
-	__m128 deltaVel1Dotn	=	_mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.m_deltaLinearVelocity.mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.m_deltaAngularVelocity.mVec128));
-	__m128 deltaVel2Dotn	=	_mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.m_deltaAngularVelocity.mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.m_deltaLinearVelocity.mVec128));
+	__m128 deltaVel1Dotn	=	_mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
+	__m128 deltaVel2Dotn	=	_mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128));
 	deltaImpulse	=	_mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
 	deltaImpulse	=	_mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
@@ -139,11 +139,11 @@
 	deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
 	c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
-	__m128	linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,_mm_set1_ps(body1.m_invMass));
-	__m128	linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,_mm_set1_ps(body2.m_invMass));
+	__m128	linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
+	__m128	linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
 	__m128 impulseMagnitude = deltaImpulse;
-	body1.m_deltaLinearVelocity.mVec128 = _mm_add_ps(body1.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
-	body1.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body1.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
-	body2.m_deltaLinearVelocity.mVec128 = _mm_sub_ps(body2.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
-	body2.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body2.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
+	body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
+	body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
+	body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
+	body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
 #else
 	resolveSingleConstraintRowLowerLimit(body1,body2,c);
@@ -152,9 +152,9 @@
 
 // Project Gauss Seidel or the equivalent Sequential Impulse
- void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
 {
 	btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
-	const btScalar deltaVel1Dotn	=	c.m_contactNormal.dot(body1.m_deltaLinearVelocity) 	+ c.m_relpos1CrossNormal.dot(body1.m_deltaAngularVelocity);
-	const btScalar deltaVel2Dotn	=	-c.m_contactNormal.dot(body2.m_deltaLinearVelocity) + c.m_relpos2CrossNormal.dot(body2.m_deltaAngularVelocity);
+	const btScalar deltaVel1Dotn	=	c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) 	+ c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
+	const btScalar deltaVel2Dotn	=	-c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
 
 	deltaImpulse	-=	deltaVel1Dotn*c.m_jacDiagABInv;
@@ -170,8 +170,71 @@
 		c.m_appliedImpulse = sum;
 	}
-	if (body1.m_invMass)
-		body1.applyImpulse(c.m_contactNormal*body1.m_invMass,c.m_angularComponentA,deltaImpulse);
-	if (body2.m_invMass)
-		body2.applyImpulse(-c.m_contactNormal*body2.m_invMass,c.m_angularComponentB,deltaImpulse);
+	body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
+	body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
+}
+
+
+void	btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulseCacheFriendly(
+        btRigidBody& body1,
+        btRigidBody& body2,
+        const btSolverConstraint& c)
+{
+		if (c.m_rhsPenetration)
+        {
+			gNumSplitImpulseRecoveries++;
+			btScalar deltaImpulse = c.m_rhsPenetration-btScalar(c.m_appliedPushImpulse)*c.m_cfm;
+			const btScalar deltaVel1Dotn	=	c.m_contactNormal.dot(body1.internalGetPushVelocity()) 	+ c.m_relpos1CrossNormal.dot(body1.internalGetTurnVelocity());
+			const btScalar deltaVel2Dotn	=	-c.m_contactNormal.dot(body2.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetTurnVelocity());
+
+			deltaImpulse	-=	deltaVel1Dotn*c.m_jacDiagABInv;
+			deltaImpulse	-=	deltaVel2Dotn*c.m_jacDiagABInv;
+			const btScalar sum = btScalar(c.m_appliedPushImpulse) + deltaImpulse;
+			if (sum < c.m_lowerLimit)
+			{
+				deltaImpulse = c.m_lowerLimit-c.m_appliedPushImpulse;
+				c.m_appliedPushImpulse = c.m_lowerLimit;
+			}
+			else
+			{
+				c.m_appliedPushImpulse = sum;
+			}
+			body1.internalApplyPushImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
+			body2.internalApplyPushImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
+        }
+}
+
+ void btSequentialImpulseConstraintSolver::resolveSplitPenetrationSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
+{
+#ifdef USE_SIMD
+	if (!c.m_rhsPenetration)
+		return;
+
+	gNumSplitImpulseRecoveries++;
+
+	__m128 cpAppliedImp = _mm_set1_ps(c.m_appliedPushImpulse);
+	__m128	lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
+	__m128	upperLimit1 = _mm_set1_ps(c.m_upperLimit);
+	__m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhsPenetration), _mm_mul_ps(_mm_set1_ps(c.m_appliedPushImpulse),_mm_set1_ps(c.m_cfm)));
+	__m128 deltaVel1Dotn	=	_mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.internalGetPushVelocity().mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetTurnVelocity().mVec128));
+	__m128 deltaVel2Dotn	=	_mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetTurnVelocity().mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.internalGetPushVelocity().mVec128));
+	deltaImpulse	=	_mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
+	deltaImpulse	=	_mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
+	btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
+	btSimdScalar resultLowerLess,resultUpperLess;
+	resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
+	resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
+	__m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
+	deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
+	c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
+	__m128	linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
+	__m128	linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
+	__m128 impulseMagnitude = deltaImpulse;
+	body1.internalGetPushVelocity().mVec128 = _mm_add_ps(body1.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
+	body1.internalGetTurnVelocity().mVec128 = _mm_add_ps(body1.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
+	body2.internalGetPushVelocity().mVec128 = _mm_sub_ps(body2.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
+	body2.internalGetTurnVelocity().mVec128 = _mm_add_ps(body2.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
+#else
+	resolveSplitPenetrationImpulseCacheFriendly(body1,body2,c);
+#endif
 }
 
@@ -215,27 +278,31 @@
 
 
-
+#if 0
 void	btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject)
 {
 	btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0;
 
-	solverBody->m_deltaLinearVelocity.setValue(0.f,0.f,0.f);
-	solverBody->m_deltaAngularVelocity.setValue(0.f,0.f,0.f);
+	solverBody->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
+	solverBody->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
+	solverBody->internalGetPushVelocity().setValue(0.f,0.f,0.f);
+	solverBody->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
 
 	if (rb)
 	{
-		solverBody->m_invMass = rb->getInvMass();
+		solverBody->internalGetInvMass() = btVector3(rb->getInvMass(),rb->getInvMass(),rb->getInvMass())*rb->getLinearFactor();
 		solverBody->m_originalBody = rb;
 		solverBody->m_angularFactor = rb->getAngularFactor();
 	} else
 	{
-		solverBody->m_invMass = 0.f;
+		solverBody->internalGetInvMass().setValue(0,0,0);
 		solverBody->m_originalBody = 0;
-		solverBody->m_angularFactor = 1.f;
-	}
-}
-
-
-int		gNumSplitImpulseRecoveries = 0;
+		solverBody->m_angularFactor.setValue(1,1,1);
+	}
+}
+#endif
+
+
+
+
 
 btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution)
@@ -263,6 +330,5 @@
 
 
-
-btSolverConstraint&	btSequentialImpulseConstraintSolver::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)
+void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyB,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
 {
 
@@ -271,11 +337,8 @@
 	btRigidBody* body1=btRigidBody::upcast(colObj1);
 
-	btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expand();
-	memset(&solverConstraint,0xff,sizeof(btSolverConstraint));
 	solverConstraint.m_contactNormal = normalAxis;
 
-	solverConstraint.m_solverBodyIdA = solverBodyIdA;
-	solverConstraint.m_solverBodyIdB = solverBodyIdB;
-	solverConstraint.m_frictionIndex = frictionIndex;
+	solverConstraint.m_solverBodyA = body0 ? body0 : &getFixedBody();
+	solverConstraint.m_solverBodyB = body1 ? body1 : &getFixedBody();
 
 	solverConstraint.m_friction = cp.m_combinedFriction;
@@ -283,5 +346,5 @@
 
 	solverConstraint.m_appliedImpulse = 0.f;
-	//	solverConstraint.m_appliedPushImpulse = 0.f;
+	solverConstraint.m_appliedPushImpulse = 0.f;
 
 	{
@@ -338,14 +401,23 @@
 		rel_vel = vel1Dotn+vel2Dotn;
 
-		btScalar positionalError = 0.f;
-
-		btSimdScalar velocityError =  - rel_vel;
+//		btScalar positionalError = 0.f;
+
+		btSimdScalar velocityError =  desiredVelocity - rel_vel;
 		btSimdScalar	velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);
 		solverConstraint.m_rhs = velocityImpulse;
-		solverConstraint.m_cfm = 0.f;
+		solverConstraint.m_cfm = cfmSlip;
 		solverConstraint.m_lowerLimit = 0;
 		solverConstraint.m_upperLimit = 1e10f;
 	}
-
+}
+
+
+
+btSolverConstraint&	btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
+{
+	btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing();
+	solverConstraint.m_frictionIndex = frictionIndex;
+	setupFrictionConstraint(solverConstraint, normalAxis, solverBodyA, solverBodyB, cp, rel_pos1, rel_pos2, 
+							colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
 	return solverConstraint;
 }
@@ -353,4 +425,5 @@
 int	btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body)
 {
+#if 0
 	int solverBodyIdA = -1;
 
@@ -374,68 +447,34 @@
 	}
 	return solverBodyIdA;
+#endif
+	return 0;
 }
 #include <stdio.h>
 
 
-
-void	btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal)
-{
-	btCollisionObject* colObj0=0,*colObj1=0;
-
-	colObj0 = (btCollisionObject*)manifold->getBody0();
-	colObj1 = (btCollisionObject*)manifold->getBody1();
-
-	int solverBodyIdA=-1;
-	int solverBodyIdB=-1;
-
-	if (manifold->getNumContacts())
-	{
-		solverBodyIdA = getOrInitSolverBody(*colObj0);
-		solverBodyIdB = getOrInitSolverBody(*colObj1);
-	}
-
-	///avoid collision response between two static objects
-	if (!solverBodyIdA && !solverBodyIdB)
-		return;
-
-	btVector3 rel_pos1;
-	btVector3 rel_pos2;
-	btScalar relaxation;
-
-	for (int j=0;j<manifold->getNumContacts();j++)
-	{
-
-		btManifoldPoint& cp = manifold->getContactPoint(j);
-
-		if (cp.getDistance() <= manifold->getContactProcessingThreshold())
-		{
+void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstraint& solverConstraint, 
+																 btCollisionObject* colObj0, btCollisionObject* colObj1,
+																 btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
+																 btVector3& vel, btScalar& rel_vel, btScalar& relaxation,
+																 btVector3& rel_pos1, btVector3& rel_pos2)
+{
+			btRigidBody* rb0 = btRigidBody::upcast(colObj0);
+			btRigidBody* rb1 = btRigidBody::upcast(colObj1);
 
 			const btVector3& pos1 = cp.getPositionWorldOnA();
 			const btVector3& pos2 = cp.getPositionWorldOnB();
 
+//			btVector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); 
+//			btVector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
 			rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); 
 			rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
 
-
 			relaxation = 1.f;
-			btScalar rel_vel;
-			btVector3 vel;
-
-			int frictionIndex = m_tmpSolverContactConstraintPool.size();
-
-			{
-				btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expand();
-				btRigidBody* rb0 = btRigidBody::upcast(colObj0);
-				btRigidBody* rb1 = btRigidBody::upcast(colObj1);
-
-				solverConstraint.m_solverBodyIdA = solverBodyIdA;
-				solverConstraint.m_solverBodyIdB = solverBodyIdB;
-
-				solverConstraint.m_originalContactPoint = &cp;
-
-				btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
-				solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0);
-				btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);		
-				solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0);
+
+			btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
+			solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0);
+			btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);		
+			solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0);
+
 				{
 #ifdef COMPUTE_IMPULSE_DENOM
@@ -467,10 +506,10 @@
 
 
-				btVector3 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : 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 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : 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);
 
 				btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop;
@@ -499,7 +538,7 @@
 					solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
 					if (rb0)
-						m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
+						rb0->internalApplyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
 					if (rb1)
-						m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass(),-solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse);
+						rb1->internalApplyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse);
 				} else
 				{
@@ -507,5 +546,5 @@
 				}
 
-				//							solverConstraint.m_appliedPushImpulse = 0.f;
+				solverConstraint.m_appliedPushImpulse = 0.f;
 
 				{
@@ -523,5 +562,15 @@
 					btScalar  penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
 					btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
-					solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
+					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;
@@ -530,54 +579,14 @@
 
 
-				/////setup the friction constraints
-
-
-
-				if (1)
-				{
-					solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size();
-					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 /= btSqrt(lat_rel_vel);
-							applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
-							applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
-							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);
-								cp.m_lateralFrictionDir2.normalize();//??
-								applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
-								applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
-								addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
-							}
-							cp.m_lateralFrictionInitialized = true;
-						} else
-						{
-							//re-calculate friction direction every frame, todo: check if this is really needed
-							btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
-							applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
-							applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
-
-							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);
-								applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
-								addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
-							}
-							cp.m_lateralFrictionInitialized = true;
-						}
-
-					} else
-					{
-						addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
-						if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
-							addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
-					}
-
+
+
+}
+
+
+
+void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, 
+																		btRigidBody* rb0, btRigidBody* rb1, 
+																 btManifoldPoint& cp, const btContactSolverInfo& infoGlobal)
+{
 					if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
 					{
@@ -588,7 +597,7 @@
 								frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
 								if (rb0)
-									m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
+									rb0->internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
 								if (rb1)
-									m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),-frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
+									rb1->internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-frictionConstraint1.m_angularComponentB,-(btScalar)frictionConstraint1.m_appliedImpulse);
 							} else
 							{
@@ -604,7 +613,7 @@
 								frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
 								if (rb0)
-									m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
+									rb0->internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
 								if (rb1)
-									m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
+									rb1->internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-(btScalar)frictionConstraint2.m_appliedImpulse);
 							} else
 							{
@@ -622,14 +631,107 @@
 						}
 					}
+}
+
+
+
+
+void	btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal)
+{
+	btCollisionObject* colObj0=0,*colObj1=0;
+
+	colObj0 = (btCollisionObject*)manifold->getBody0();
+	colObj1 = (btCollisionObject*)manifold->getBody1();
+
+
+	btRigidBody* solverBodyA = btRigidBody::upcast(colObj0);
+	btRigidBody* solverBodyB = btRigidBody::upcast(colObj1);
+
+	///avoid collision response between two static objects
+	if ((!solverBodyA || !solverBodyA->getInvMass()) && (!solverBodyB || !solverBodyB->getInvMass()))
+		return;
+
+	for (int j=0;j<manifold->getNumContacts();j++)
+	{
+
+		btManifoldPoint& cp = manifold->getContactPoint(j);
+
+		if (cp.getDistance() <= manifold->getContactProcessingThreshold())
+		{
+			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);
+			solverConstraint.m_solverBodyA = rb0? rb0 : &getFixedBody();
+			solverConstraint.m_solverBodyB = rb1? rb1 : &getFixedBody();
+			solverConstraint.m_originalContactPoint = &cp;
+
+			setupContactConstraint(solverConstraint, colObj0, colObj1, cp, infoGlobal, vel, rel_vel, relaxation, rel_pos1, rel_pos2);
+
+//			const btVector3& pos1 = cp.getPositionWorldOnA();
+//			const btVector3& pos2 = cp.getPositionWorldOnB();
+
+			/////setup the friction constraints
+
+			solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size();
+
+			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 /= 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);
+						applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
+						addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+					}
+
+					applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
+					applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
+					addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+					cp.m_lateralFrictionInitialized = true;
+				} else
+				{
+					//re-calculate friction direction every frame, todo: check if this is really needed
+					btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
+					if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+					{
+						applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
+						applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
+						addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+					}
+
+					applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
+					applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
+					addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+
+					cp.m_lateralFrictionInitialized = true;
 				}
-			}
-
-
-		}
-	}
-}
-
-
-btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** /*bodies */,int /*numBodies */,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
+
+			} else
+			{
+				addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.m_contactMotion1, cp.m_contactCFM1);
+				if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+					addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2);
+			}
+			
+			setFrictionConstraintImpulse( solverConstraint, rb0, rb1, cp, infoGlobal);
+
+		}
+	}
+}
+
+
+btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
 {
 	BT_PROFILE("solveGroupCacheFriendlySetup");
@@ -644,4 +746,31 @@
 	}
 
+	if (infoGlobal.m_splitImpulse)
+	{
+		for (int i = 0; i < numBodies; i++)
+		{
+			btRigidBody* body = btRigidBody::upcast(bodies[i]);
+			if (body)
+			{	
+				body->internalGetDeltaLinearVelocity().setZero();
+				body->internalGetDeltaAngularVelocity().setZero();
+				body->internalGetPushVelocity().setZero();
+				body->internalGetTurnVelocity().setZero();
+			}
+		}
+	}
+	else
+	{
+		for (int i = 0; i < numBodies; i++)
+		{
+			btRigidBody* body = btRigidBody::upcast(bodies[i]);
+			if (body)
+			{	
+				body->internalGetDeltaLinearVelocity().setZero();
+				body->internalGetDeltaAngularVelocity().setZero();
+			}
+		}
+	}
+
 	if (1)
 	{
@@ -653,8 +782,4 @@
 		}
 	}
-
-	btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
-	initSolverBody(&fixedBody,0);
-
 	//btRigidBody* rb0=0,*rb1=0;
 
@@ -665,9 +790,10 @@
 			int totalNumRows = 0;
 			int i;
+			
+			m_tmpConstraintSizesPool.resize(numConstraints);
 			//calculate the total number of contraint rows
 			for (i=0;i<numConstraints;i++)
 			{
-
-				btTypedConstraint::btConstraintInfo1 info1;
+				btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
 				constraints[i]->getInfo1(&info1);
 				totalNumRows += info1.m_numConstraintRows;
@@ -675,14 +801,12 @@
 			m_tmpSolverNonContactConstraintPool.resize(totalNumRows);
 
-			btTypedConstraint::btConstraintInfo1 info1;
-			info1.m_numConstraintRows = 0;
-
-
+			
 			///setup the btSolverConstraints
 			int currentRow = 0;
 
-			for (i=0;i<numConstraints;i++,currentRow+=info1.m_numConstraintRows)
+			for (i=0;i<numConstraints;i++)
 			{
-				constraints[i]->getInfo1(&info1);
+				const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
+				
 				if (info1.m_numConstraintRows)
 				{
@@ -697,10 +821,5 @@
 					btRigidBody& rbB = constraint->getRigidBodyB();
 
-					int solverBodyIdA = getOrInitSolverBody(rbA);
-					int solverBodyIdB = getOrInitSolverBody(rbB);
-
-					btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA];
-					btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB];
-
+					
 					int j;
 					for ( j=0;j<info1.m_numConstraintRows;j++)
@@ -711,12 +830,12 @@
 						currentConstraintRow[j].m_appliedImpulse = 0.f;
 						currentConstraintRow[j].m_appliedPushImpulse = 0.f;
-						currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA;
-						currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB;
+						currentConstraintRow[j].m_solverBodyA = &rbA;
+						currentConstraintRow[j].m_solverBodyB = &rbB;
 					}
 
-					bodyAPtr->m_deltaLinearVelocity.setValue(0.f,0.f,0.f);
-					bodyAPtr->m_deltaAngularVelocity.setValue(0.f,0.f,0.f);
-					bodyBPtr->m_deltaLinearVelocity.setValue(0.f,0.f,0.f);
-					bodyBPtr->m_deltaAngularVelocity.setValue(0.f,0.f,0.f);
+					rbA.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
+					rbA.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
+					rbB.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
+					rbB.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
 
 
@@ -733,7 +852,10 @@
 					btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
 					info2.m_constraintError = &currentConstraintRow->m_rhs;
+					currentConstraintRow->m_cfm = infoGlobal.m_globalCfm;
+					info2.m_damping = infoGlobal.m_damping;
 					info2.cfm = &currentConstraintRow->m_cfm;
 					info2.m_lowerLimit = &currentConstraintRow->m_lowerLimit;
 					info2.m_upperLimit = &currentConstraintRow->m_upperLimit;
+					info2.m_numIterations = infoGlobal.m_numIterations;
 					constraints[i]->getInfo2(&info2);
 
@@ -742,4 +864,5 @@
 					{
 						btSolverConstraint& solverConstraint = currentConstraintRow[j];
+						solverConstraint.m_originalContactPoint = constraint;
 
 						{
@@ -778,5 +901,5 @@
 							btScalar restitution = 0.f;
 							btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2
-							btScalar	velocityError = restitution - rel_vel;// * damping;
+							btScalar	velocityError = restitution - rel_vel * info2.m_damping;
 							btScalar	penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
 							btScalar	velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
@@ -787,4 +910,5 @@
 					}
 				}
+				currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows;
 			}
 		}
@@ -793,5 +917,5 @@
 			int i;
 			btPersistentManifold* manifold = 0;
-			btCollisionObject* colObj0=0,*colObj1=0;
+//			btCollisionObject* colObj0=0,*colObj1=0;
 
 
@@ -830,11 +954,154 @@
 }
 
-btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
-{
-	BT_PROFILE("solveGroupCacheFriendlyIterations");
+btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
+{
 
 	int numConstraintPool = m_tmpSolverContactConstraintPool.size();
 	int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
 
+	int j;
+
+	if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
+	{
+		if ((iteration & 7) == 0) {
+			for (j=0; j<numConstraintPool; ++j) {
+				int tmp = m_orderTmpConstraintPool[j];
+				int swapi = btRandInt2(j+1);
+				m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
+				m_orderTmpConstraintPool[swapi] = tmp;
+			}
+
+			for (j=0; j<numFrictionPool; ++j) {
+				int tmp = m_orderFrictionConstraintPool[j];
+				int swapi = btRandInt2(j+1);
+				m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
+				m_orderFrictionConstraintPool[swapi] = tmp;
+			}
+		}
+	}
+
+	if (infoGlobal.m_solverMode & SOLVER_SIMD)
+	{
+		///solve all joint constraints, using SIMD, if available
+		for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
+		{
+			btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j];
+			resolveSingleConstraintRowGenericSIMD(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
+		}
+
+		for (j=0;j<numConstraints;j++)
+		{
+			constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
+		}
+
+		///solve all contact constraints using SIMD, if available
+		int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+		for (j=0;j<numPoolConstraints;j++)
+		{
+			const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
+			resolveSingleConstraintRowLowerLimitSIMD(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+
+		}
+		///solve all friction constraints, using SIMD, if available
+		int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
+		for (j=0;j<numFrictionPoolConstraints;j++)
+		{
+			btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
+			btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+
+			if (totalImpulse>btScalar(0))
+			{
+				solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
+				solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
+
+				resolveSingleConstraintRowGenericSIMD(*solveManifold.m_solverBodyA,	*solveManifold.m_solverBodyB,solveManifold);
+			}
+		}
+	} else
+	{
+
+		///solve all joint constraints
+		for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
+		{
+			btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j];
+			resolveSingleConstraintRowGeneric(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
+		}
+
+		for (j=0;j<numConstraints;j++)
+		{
+			constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
+		}
+		///solve all contact constraints
+		int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+		for (j=0;j<numPoolConstraints;j++)
+		{
+			const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
+			resolveSingleConstraintRowLowerLimit(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+		}
+		///solve all friction constraints
+		int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
+		for (j=0;j<numFrictionPoolConstraints;j++)
+		{
+			btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
+			btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+
+			if (totalImpulse>btScalar(0))
+			{
+				solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
+				solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
+
+				resolveSingleConstraintRowGeneric(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+			}
+		}
+	}
+	return 0.f;
+}
+
+
+void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
+{
+	int iteration;
+	if (infoGlobal.m_splitImpulse)
+	{
+		if (infoGlobal.m_solverMode & SOLVER_SIMD)
+		{
+			for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
+			{
+				{
+					int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+					int j;
+					for (j=0;j<numPoolConstraints;j++)
+					{
+						const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
+
+						resolveSplitPenetrationSIMD(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+					}
+				}
+			}
+		}
+		else
+		{
+			for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
+			{
+				{
+					int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+					int j;
+					for (j=0;j<numPoolConstraints;j++)
+					{
+						const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
+
+						resolveSplitPenetrationImpulseCacheFriendly(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+					}
+				}
+			}
+		}
+	}
+}
+
+btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
+{
+	BT_PROFILE("solveGroupCacheFriendlyIterations");
+
+	
 	//should traverse the contacts random order...
 	int iteration;
@@ -842,138 +1109,16 @@
 		for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
 		{			
-
-			int j;
-			if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
-			{
-				if ((iteration & 7) == 0) {
-					for (j=0; j<numConstraintPool; ++j) {
-						int tmp = m_orderTmpConstraintPool[j];
-						int swapi = btRandInt2(j+1);
-						m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
-						m_orderTmpConstraintPool[swapi] = tmp;
-					}
-
-					for (j=0; j<numFrictionPool; ++j) {
-						int tmp = m_orderFrictionConstraintPool[j];
-						int swapi = btRandInt2(j+1);
-						m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
-						m_orderFrictionConstraintPool[swapi] = tmp;
-					}
-				}
-			}
-
-			if (infoGlobal.m_solverMode & SOLVER_SIMD)
-			{
-				///solve all joint constraints, using SIMD, if available
-				for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
-				{
-					btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j];
-					resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint);
-				}
-
-				for (j=0;j<numConstraints;j++)
-				{
-					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);
-				}
-
-				///solve all contact constraints using SIMD, if available
-				int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
-				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);
-
-				}
-				///solve all friction constraints, using SIMD, if available
-				int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
-				for (j=0;j<numFrictionPoolConstraints;j++)
-				{
-					btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
-					btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
-
-					if (totalImpulse>btScalar(0))
-					{
-						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);
-					}
-				}
-			} else
-			{
-
-				///solve all joint constraints
-				for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
-				{
-					btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j];
-					resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint);
-				}
-
-				for (j=0;j<numConstraints;j++)
-				{
-					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);
-				}
-
-				///solve all contact constraints
-				int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
-				for (j=0;j<numPoolConstraints;j++)
-				{
-					const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
-					resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
-				}
-				///solve all friction constraints
-				int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
-				for (j=0;j<numFrictionPoolConstraints;j++)
-				{
-					btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
-					btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
-
-					if (totalImpulse>btScalar(0))
-					{
-						solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
-						solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
-
-						resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],							m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
-					}
-				}
-			}
-
-
-
-		}
+			solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
+		}
+		
+		solveGroupCacheFriendlySplitImpulseIterations(bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
 	}
 	return 0.f;
 }
 
-
-
-/// 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*/)
-{
-
-	
-
-	BT_PROFILE("solveGroup");
-	//we only implement SOLVER_CACHE_FRIENDLY now
-	//you need to provide at least some bodies
-	btAssert(bodies);
-	btAssert(numBodies);
-
-	int i;
-
-	solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
-	solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
-
+btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies ,int numBodies,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** /*constraints*/,int /* numConstraints*/,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
+{
 	int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
-	int j;
+	int i,j;
 
 	for (j=0;j<numPoolConstraints;j++)
@@ -993,20 +1138,34 @@
 	}
 
+	numPoolConstraints = m_tmpSolverNonContactConstraintPool.size();
+	for (j=0;j<numPoolConstraints;j++)
+	{
+		const btSolverConstraint& solverConstr = m_tmpSolverNonContactConstraintPool[j];
+		btTypedConstraint* constr = (btTypedConstraint*)solverConstr.m_originalContactPoint;
+		btScalar sum = constr->internalGetAppliedImpulse();
+		sum += solverConstr.m_appliedImpulse;
+		constr->internalSetAppliedImpulse(sum);
+	}
+
+
 	if (infoGlobal.m_splitImpulse)
 	{		
-		for ( i=0;i<m_tmpSolverBodyPool.size();i++)
-		{
-			m_tmpSolverBodyPool[i].writebackVelocity(infoGlobal.m_timeStep);
+		for ( i=0;i<numBodies;i++)
+		{
+			btRigidBody* body = btRigidBody::upcast(bodies[i]);
+			if (body)
+				body->internalWritebackVelocity(infoGlobal.m_timeStep);
 		}
 	} else
 	{
-		for ( i=0;i<m_tmpSolverBodyPool.size();i++)
-		{
-			m_tmpSolverBodyPool[i].writebackVelocity();
-		}
-	}
-
-
-	m_tmpSolverBodyPool.resize(0);
+		for ( i=0;i<numBodies;i++)
+		{
+			btRigidBody* body = btRigidBody::upcast(bodies[i]);
+			if (body)
+				body->internalWritebackVelocity();
+		}
+	}
+
+
 	m_tmpSolverContactConstraintPool.resize(0);
 	m_tmpSolverNonContactConstraintPool.resize(0);
@@ -1018,9 +1177,21 @@
 
 
-
-
-
-
-
+/// 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*/)
+{
+
+	BT_PROFILE("solveGroup");
+	//you need to provide at least some bodies
+	btAssert(bodies);
+	btAssert(numBodies);
+
+	solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
+
+	solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
+
+	solveGroupCacheFriendlyFinish(bodies, numBodies, manifoldPtr,  numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
+	
+	return 0.f;
+}
 
 void	btSequentialImpulseConstraintSolver::reset()
@@ -1029,3 +1200,9 @@
 }
 
-
+btRigidBody& btSequentialImpulseConstraintSolver::getFixedBody()
+{
+	static btRigidBody s_fixed(0, 0,0);
+	s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
+	return s_fixed;
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h	(revision 8284)
@@ -22,6 +22,6 @@
 #include "btSolverBody.h"
 #include "btSolverConstraint.h"
-
-
+#include "btTypedConstraint.h"
+#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
 
 ///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
@@ -30,5 +30,4 @@
 protected:
 
-	btAlignedObjectArray<btSolverBody>	m_tmpSolverBodyPool;
 	btConstraintArray			m_tmpSolverContactConstraintPool;
 	btConstraintArray			m_tmpSolverNonContactConstraintPool;
@@ -36,32 +35,61 @@
 	btAlignedObjectArray<int>	m_orderTmpConstraintPool;
 	btAlignedObjectArray<int>	m_orderFrictionConstraintPool;
+	btAlignedObjectArray<btTypedConstraint::btConstraintInfo1> m_tmpConstraintSizesPool;
 
-	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);
+	void setupFrictionConstraint(	btSolverConstraint& solverConstraint, const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyIdB,
+									btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
+									btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, 
+									btScalar desiredVelocity=0., btScalar cfmSlip=0.);
+
+	btSolverConstraint&	addFrictionConstraint(const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0., btScalar cfmSlip=0.);
 	
+	void setupContactConstraint(btSolverConstraint& solverConstraint, btCollisionObject* colObj0, btCollisionObject* colObj1, btManifoldPoint& cp, 
+								const btContactSolverInfo& infoGlobal, btVector3& vel, btScalar& rel_vel, btScalar& relaxation, 
+								btVector3& rel_pos1, btVector3& rel_pos2);
+
+	void setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, btRigidBody* rb0, btRigidBody* rb1, 
+										 btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
+
 	///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
 	unsigned long	m_btSeed2;
 
-	void	initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);
+//	void	initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);
 	btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);
 
 	void	convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal);
 
+
+	void	resolveSplitPenetrationSIMD(
+        btRigidBody& body1,
+        btRigidBody& body2,
+        const btSolverConstraint& contactConstraint);
+
 	void	resolveSplitPenetrationImpulseCacheFriendly(
-        btSolverBody& body1,
-        btSolverBody& body2,
-        const btSolverConstraint& contactConstraint,
-        const btContactSolverInfo& solverInfo);
+        btRigidBody& body1,
+        btRigidBody& body2,
+        const btSolverConstraint& contactConstraint);
 
 	//internal method
 	int	getOrInitSolverBody(btCollisionObject& body);
 
-	void	resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+	void	resolveSingleConstraintRowGeneric(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& contactConstraint);
 
-	void	resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+	void	resolveSingleConstraintRowGenericSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& contactConstraint);
 	
-	void	resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+	void	resolveSingleConstraintRowLowerLimit(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& contactConstraint);
 	
-	void	resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+	void	resolveSingleConstraintRowLowerLimitSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& contactConstraint);
 		
+protected:
+	static btRigidBody& getFixedBody();
+	
+	virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
+	virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
+	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 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);
+
+
 public:
 
@@ -72,7 +100,6 @@
 	virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher);
 	
-	btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
-	btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
 
+	
 	///clear internal cached data and reset random seed
 	virtual	void	reset();
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp	(revision 8284)
@@ -19,5 +19,5 @@
 */
 
-//-----------------------------------------------------------------------------
+
 
 #include "btSliderConstraint.h"
@@ -26,5 +26,5 @@
 #include <new>
 
-//-----------------------------------------------------------------------------
+#define USE_OFFSET_FOR_CONSTANT_FRAME true
 
 void btSliderConstraint::initParams()
@@ -37,19 +37,25 @@
 	m_restitutionDirLin = SLIDER_CONSTRAINT_DEF_RESTITUTION;
 	m_dampingDirLin = btScalar(0.);
+	m_cfmDirLin = SLIDER_CONSTRAINT_DEF_CFM;
 	m_softnessDirAng = SLIDER_CONSTRAINT_DEF_SOFTNESS;
 	m_restitutionDirAng = SLIDER_CONSTRAINT_DEF_RESTITUTION;
 	m_dampingDirAng = btScalar(0.);
+	m_cfmDirAng = SLIDER_CONSTRAINT_DEF_CFM;
 	m_softnessOrthoLin = SLIDER_CONSTRAINT_DEF_SOFTNESS;
 	m_restitutionOrthoLin = SLIDER_CONSTRAINT_DEF_RESTITUTION;
 	m_dampingOrthoLin = SLIDER_CONSTRAINT_DEF_DAMPING;
+	m_cfmOrthoLin = SLIDER_CONSTRAINT_DEF_CFM;
 	m_softnessOrthoAng = SLIDER_CONSTRAINT_DEF_SOFTNESS;
 	m_restitutionOrthoAng = SLIDER_CONSTRAINT_DEF_RESTITUTION;
 	m_dampingOrthoAng = SLIDER_CONSTRAINT_DEF_DAMPING;
+	m_cfmOrthoAng = SLIDER_CONSTRAINT_DEF_CFM;
 	m_softnessLimLin = SLIDER_CONSTRAINT_DEF_SOFTNESS;
 	m_restitutionLimLin = SLIDER_CONSTRAINT_DEF_RESTITUTION;
 	m_dampingLimLin = SLIDER_CONSTRAINT_DEF_DAMPING;
+	m_cfmLimLin = SLIDER_CONSTRAINT_DEF_CFM;
 	m_softnessLimAng = SLIDER_CONSTRAINT_DEF_SOFTNESS;
 	m_restitutionLimAng = SLIDER_CONSTRAINT_DEF_RESTITUTION;
 	m_dampingLimAng = SLIDER_CONSTRAINT_DEF_DAMPING;
+	m_cfmLimAng = SLIDER_CONSTRAINT_DEF_CFM;
 
 	m_poweredLinMotor = false;
@@ -63,62 +69,116 @@
 	m_accumulatedAngMotorImpulse = btScalar(0.0);
 
-} // btSliderConstraint::initParams()
-
-//-----------------------------------------------------------------------------
-
-btSliderConstraint::btSliderConstraint()
-        :btTypedConstraint(SLIDER_CONSTRAINT_TYPE),
-		m_useLinearReferenceFrameA(true),
-		m_useSolveConstraintObsolete(false)
-//		m_useSolveConstraintObsolete(true)
+	m_flags = 0;
+	m_flags = 0;
+
+	m_useOffsetForConstraintFrame = USE_OFFSET_FOR_CONSTANT_FRAME;
+
+	calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
+}
+
+
+
+
+
+btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA)
+        : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, rbA, rbB),
+		m_useSolveConstraintObsolete(false),
+		m_frameInA(frameInA),
+        m_frameInB(frameInB),
+		m_useLinearReferenceFrameA(useLinearReferenceFrameA)
 {
 	initParams();
-} // btSliderConstraint::btSliderConstraint()
-
-//-----------------------------------------------------------------------------
-
-btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA)
-        : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, rbA, rbB)
-        , m_frameInA(frameInA)
-        , m_frameInB(frameInB),
-		m_useLinearReferenceFrameA(useLinearReferenceFrameA),
-		m_useSolveConstraintObsolete(false)
-//		m_useSolveConstraintObsolete(true)
-{
+}
+
+
+
+btSliderConstraint::btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA)
+        : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, getFixedBody(), rbB),
+		m_useSolveConstraintObsolete(false),
+		m_frameInB(frameInB),
+		m_useLinearReferenceFrameA(useLinearReferenceFrameA)
+{
+	///not providing rigidbody A means implicitly using worldspace for body A
+	m_frameInA = rbB.getCenterOfMassTransform() * m_frameInB;
+//	m_frameInA.getOrigin() = m_rbA.getCenterOfMassTransform()(m_frameInA.getOrigin());
+
 	initParams();
-} // btSliderConstraint::btSliderConstraint()
-
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::buildJacobian()
-{
-	if (!m_useSolveConstraintObsolete) 
-	{
-		return;
-	}
-	if(m_useLinearReferenceFrameA)
-	{
-		buildJacobianInt(m_rbA, m_rbB, m_frameInA, m_frameInB);
+}
+
+
+
+
+
+
+void btSliderConstraint::getInfo1(btConstraintInfo1* info)
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		info->m_numConstraintRows = 0;
+		info->nub = 0;
 	}
 	else
 	{
-		buildJacobianInt(m_rbB, m_rbA, m_frameInB, m_frameInA);
-	}
-} // btSliderConstraint::buildJacobian()
-
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB)
-{
-	//calculate transforms
-    m_calculatedTransformA = rbA.getCenterOfMassTransform() * frameInA;
-    m_calculatedTransformB = rbB.getCenterOfMassTransform() * frameInB;
+		info->m_numConstraintRows = 4; // Fixed 2 linear + 2 angular
+		info->nub = 2; 
+		//prepare constraint
+		calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform());
+		testAngLimits();
+		testLinLimits();
+		if(getSolveLinLimit() || getPoweredLinMotor())
+		{
+			info->m_numConstraintRows++; // limit 3rd linear as well
+			info->nub--; 
+		}
+		if(getSolveAngLimit() || getPoweredAngMotor())
+		{
+			info->m_numConstraintRows++; // limit 3rd angular as well
+			info->nub--; 
+		}
+	}
+}
+
+void btSliderConstraint::getInfo1NonVirtual(btConstraintInfo1* info)
+{
+
+	info->m_numConstraintRows = 6; // Fixed 2 linear + 2 angular + 1 limit (even if not used)
+	info->nub = 0; 
+}
+
+void btSliderConstraint::getInfo2(btConstraintInfo2* info)
+{
+	getInfo2NonVirtual(info,m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(), m_rbA.getLinearVelocity(),m_rbB.getLinearVelocity(), m_rbA.getInvMass(),m_rbB.getInvMass());
+}
+
+
+
+
+
+
+
+void btSliderConstraint::calculateTransforms(const btTransform& transA,const btTransform& transB)
+{
+	if(m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete))
+	{
+		m_calculatedTransformA = transA * m_frameInA;
+		m_calculatedTransformB = transB * m_frameInB;
+	}
+	else
+	{
+		m_calculatedTransformA = transB * m_frameInB;
+		m_calculatedTransformB = transA * m_frameInA;
+	}
 	m_realPivotAInW = m_calculatedTransformA.getOrigin();
 	m_realPivotBInW = m_calculatedTransformB.getOrigin();
 	m_sliderAxis = m_calculatedTransformA.getBasis().getColumn(0); // along X
-	m_delta = m_realPivotBInW - m_realPivotAInW;
+	if(m_useLinearReferenceFrameA || m_useSolveConstraintObsolete)
+	{
+		m_delta = m_realPivotBInW - m_realPivotAInW;
+	}
+	else
+	{
+		m_delta = m_realPivotAInW - m_realPivotBInW;
+	}
 	m_projPivotInW = m_realPivotAInW + m_sliderAxis.dot(m_delta) * m_sliderAxis;
-	m_relPosA = m_projPivotInW - rbA.getCenterOfMassPosition();
-	m_relPosB = m_realPivotBInW - rbB.getCenterOfMassPosition();
     btVector3 normalWorld;
     int i;
@@ -127,79 +187,130 @@
     {
 		normalWorld = m_calculatedTransformA.getBasis().getColumn(i);
-		new (&m_jacLin[i]) btJacobianEntry(
-			rbA.getCenterOfMassTransform().getBasis().transpose(),
-			rbB.getCenterOfMassTransform().getBasis().transpose(),
-			m_relPosA,
-			m_relPosB,
-			normalWorld,
-			rbA.getInvInertiaDiagLocal(),
-			rbA.getInvMass(),
-			rbB.getInvInertiaDiagLocal(),
-			rbB.getInvMass()
-			);
-		m_jacLinDiagABInv[i] = btScalar(1.) / m_jacLin[i].getDiagonal();
 		m_depth[i] = m_delta.dot(normalWorld);
     }
-	testLinLimits();
-    // angular part
-    for(i = 0; i < 3; i++)
-    {
-		normalWorld = m_calculatedTransformA.getBasis().getColumn(i);
-		new (&m_jacAng[i])	btJacobianEntry(
-			normalWorld,
-            rbA.getCenterOfMassTransform().getBasis().transpose(),
-            rbB.getCenterOfMassTransform().getBasis().transpose(),
-            rbA.getInvInertiaDiagLocal(),
-            rbB.getInvInertiaDiagLocal()
-			);
-	}
-	testAngLimits();
-	btVector3 axisA = m_calculatedTransformA.getBasis().getColumn(0);
-	m_kAngle = btScalar(1.0 )/ (rbA.computeAngularImpulseDenominator(axisA) + rbB.computeAngularImpulseDenominator(axisA));
-	// clear accumulator for motors
-	m_accumulatedLinMotorImpulse = btScalar(0.0);
-	m_accumulatedAngMotorImpulse = btScalar(0.0);
-} // btSliderConstraint::buildJacobianInt()
-
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::getInfo1(btConstraintInfo1* info)
-{
-	if (m_useSolveConstraintObsolete)
-	{
-		info->m_numConstraintRows = 0;
-		info->nub = 0;
+}
+ 
+
+
+void btSliderConstraint::testLinLimits(void)
+{
+	m_solveLinLim = false;
+	m_linPos = m_depth[0];
+	if(m_lowerLinLimit <= m_upperLinLimit)
+	{
+		if(m_depth[0] > m_upperLinLimit)
+		{
+			m_depth[0] -= m_upperLinLimit;
+			m_solveLinLim = true;
+		}
+		else if(m_depth[0] < m_lowerLinLimit)
+		{
+			m_depth[0] -= m_lowerLinLimit;
+			m_solveLinLim = true;
+		}
+		else
+		{
+			m_depth[0] = btScalar(0.);
+		}
 	}
 	else
 	{
-		info->m_numConstraintRows = 4; // Fixed 2 linear + 2 angular
-		info->nub = 2; 
-		//prepare constraint
-		calculateTransforms();
-		testLinLimits();
-		if(getSolveLinLimit() || getPoweredLinMotor())
-		{
-			info->m_numConstraintRows++; // limit 3rd linear as well
-			info->nub--; 
-		}
-		testAngLimits();
-		if(getSolveAngLimit() || getPoweredAngMotor())
-		{
-			info->m_numConstraintRows++; // limit 3rd angular as well
-			info->nub--; 
-		}
-	}
-} // btSliderConstraint::getInfo1()
-
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::getInfo2(btConstraintInfo2* info)
-{
+		m_depth[0] = btScalar(0.);
+	}
+}
+
+
+
+void btSliderConstraint::testAngLimits(void)
+{
+	m_angDepth = btScalar(0.);
+	m_solveAngLim = false;
+	if(m_lowerAngLimit <= m_upperAngLimit)
+	{
+		const btVector3 axisA0 = m_calculatedTransformA.getBasis().getColumn(1);
+		const btVector3 axisA1 = m_calculatedTransformA.getBasis().getColumn(2);
+		const btVector3 axisB0 = m_calculatedTransformB.getBasis().getColumn(1);
+//		btScalar rot = btAtan2Fast(axisB0.dot(axisA1), axisB0.dot(axisA0));  
+		btScalar rot = btAtan2(axisB0.dot(axisA1), axisB0.dot(axisA0));  
+		rot = btAdjustAngleToLimits(rot, m_lowerAngLimit, m_upperAngLimit);
+		m_angPos = rot;
+		if(rot < m_lowerAngLimit)
+		{
+			m_angDepth = rot - m_lowerAngLimit;
+			m_solveAngLim = true;
+		} 
+		else if(rot > m_upperAngLimit)
+		{
+			m_angDepth = rot - m_upperAngLimit;
+			m_solveAngLim = true;
+		}
+	}
+}
+
+btVector3 btSliderConstraint::getAncorInA(void)
+{
+	btVector3 ancorInA;
+	ancorInA = m_realPivotAInW + (m_lowerLinLimit + m_upperLinLimit) * btScalar(0.5) * m_sliderAxis;
+	ancorInA = m_rbA.getCenterOfMassTransform().inverse() * ancorInA;
+	return ancorInA;
+}
+
+
+
+btVector3 btSliderConstraint::getAncorInB(void)
+{
+	btVector3 ancorInB;
+	ancorInB = m_frameInB.getOrigin();
+	return ancorInB;
+}
+
+
+void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB, const btVector3& linVelA,const btVector3& linVelB, btScalar rbAinvMass,btScalar rbBinvMass  )
+{
+	const btTransform& trA = getCalculatedTransformA();
+	const btTransform& trB = getCalculatedTransformB();
+	
 	btAssert(!m_useSolveConstraintObsolete);
 	int i, s = info->rowskip;
-	const btTransform& trA = getCalculatedTransformA();
-	const btTransform& trB = getCalculatedTransformB();
+	
 	btScalar signFact = m_useLinearReferenceFrameA ? btScalar(1.0f) : btScalar(-1.0f);
-	// make rotations around Y and Z equal
+	
+	// difference between frames in WCS
+	btVector3 ofs = trB.getOrigin() - trA.getOrigin();
+	// now get weight factors depending on masses
+	btScalar miA = rbAinvMass;
+	btScalar miB = rbBinvMass;
+	bool hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON);
+	btScalar miS = miA + miB;
+	btScalar factA, factB;
+	if(miS > btScalar(0.f))
+	{
+		factA = miB / miS;
+	}
+	else 
+	{
+		factA = btScalar(0.5f);
+	}
+	factB = btScalar(1.0f) - factA;
+	btVector3 ax1, p, q;
+	btVector3 ax1A = trA.getBasis().getColumn(0);
+	btVector3 ax1B = trB.getBasis().getColumn(0);
+	if(m_useOffsetForConstraintFrame)
+	{
+		// get the desired direction of slider axis
+		// as weighted sum of X-orthos of frameA and frameB in WCS
+		ax1 = ax1A * factA + ax1B * factB;
+		ax1.normalize();
+		// construct two orthos to slider axis
+		btPlaneSpace1 (ax1, p, q);
+	}
+	else
+	{ // old way - use frameA
+		ax1 = trA.getBasis().getColumn(0);
+		// get 2 orthos to slider axis (Y, Z)
+		p = trA.getBasis().getColumn(1);
+		q = trA.getBasis().getColumn(2);
+	}
+	// make rotations around these orthos equal
 	// the slider axis should be the only unconstrained
 	// rotational axis, the angular velocity of the two bodies perpendicular to
@@ -209,10 +320,4 @@
 	// where p and q are unit vectors normal to the slider axis, and w1 and w2
 	// are the angular velocity vectors of the two bodies.
-	// get slider axis (X)
-	btVector3 ax1 = trA.getBasis().getColumn(0);
-	// get 2 orthos to slider axis (Y, Z)
-	btVector3 p = trA.getBasis().getColumn(1);
-	btVector3 q = trA.getBasis().getColumn(2);
-	// set the two slider rows 
 	info->m_J1angularAxis[0] = p[0];
 	info->m_J1angularAxis[1] = p[1];
@@ -230,6 +335,6 @@
 	// compute the right hand side of the constraint equation. set relative
 	// body velocities along p and q to bring the slider back into alignment.
-	// if ax1,ax2 are the unit length slider axes as computed from body1 and
-	// body2, we need to rotate both bodies along the axis u = (ax1 x ax2).
+	// if ax1A,ax1B are the unit length slider axes as computed from bodyA and
+	// bodyB, we need to rotate both bodies along the axis u = (ax1 x ax2).
 	// if "theta" is the angle between ax1 and ax2, we need an angular velocity
 	// along u to cover angle erp*theta in one step :
@@ -243,56 +348,118 @@
 	// ax1 x ax2 is in the plane space of ax1, so we project the angular
 	// velocity to p and q to find the right hand side.
-	btScalar k = info->fps * info->erp * getSoftnessOrthoAng();
-    btVector3 ax2 = trB.getBasis().getColumn(0);
-	btVector3 u = ax1.cross(ax2);
+//	btScalar k = info->fps * info->erp * getSoftnessOrthoAng();
+	btScalar currERP = (m_flags & BT_SLIDER_FLAGS_ERP_ORTANG) ? m_softnessOrthoAng : m_softnessOrthoAng * info->erp;
+	btScalar k = info->fps * currERP;
+
+	btVector3 u = ax1A.cross(ax1B);
 	info->m_constraintError[0] = k * u.dot(p);
 	info->m_constraintError[s] = k * u.dot(q);
-	// pull out pos and R for both bodies. also get the connection
-	// vector c = pos2-pos1.
-	// next two rows. we want: vel2 = vel1 + w1 x c ... but this would
-	// result in three equations, so we project along the planespace vectors
-	// so that sliding along the slider axis is disregarded. for symmetry we
-	// also consider rotation around center of mass of two bodies (factA and factB).
-	btTransform bodyA_trans = m_rbA.getCenterOfMassTransform();
-	btTransform bodyB_trans = m_rbB.getCenterOfMassTransform();
-	int s2 = 2 * s, s3 = 3 * s;
-	btVector3 c;
-	btScalar miA = m_rbA.getInvMass();
-	btScalar miB = m_rbB.getInvMass();
-	btScalar miS = miA + miB;
-	btScalar factA, factB;
-	if(miS > btScalar(0.f))
-	{
-		factA = miB / miS;
-	}
-	else 
-	{
-		factA = btScalar(0.5f);
-	}
-	if(factA > 0.99f) factA = 0.99f;
-	if(factA < 0.01f) factA = 0.01f;
-	factB = btScalar(1.0f) - factA;
-	c = bodyB_trans.getOrigin() - bodyA_trans.getOrigin();
-	btVector3 tmp = c.cross(p);
-	for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = factA*tmp[i];
-	for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = factB*tmp[i];
-	tmp = c.cross(q);
-	for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = factA*tmp[i];
-	for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = factB*tmp[i];
-
-	for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i];
-	for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i];
-	// compute two elements of right hand side. we want to align the offset
-	// point (in body 2's frame) with the center of body 1.
-	btVector3 ofs; // offset point in global coordinates
-	ofs = trB.getOrigin() - trA.getOrigin();
-	k = info->fps * info->erp * getSoftnessOrthoLin();
-	info->m_constraintError[s2] = k * p.dot(ofs);
-	info->m_constraintError[s3] = k * q.dot(ofs);
-	int nrow = 3; // last filled row
+	if(m_flags & BT_SLIDER_FLAGS_CFM_ORTANG)
+	{
+		info->cfm[0] = m_cfmOrthoAng;
+		info->cfm[s] = m_cfmOrthoAng;
+	}
+
+	int nrow = 1; // last filled row
 	int srow;
-	// check linear limits linear
-	btScalar limit_err = btScalar(0.0);
-	int limit = 0;
+	btScalar limit_err;
+	int limit;
+	int powered;
+
+	// next two rows. 
+	// we want: velA + wA x relA == velB + wB x relB ... but this would
+	// result in three equations, so we project along two orthos to the slider axis
+
+	btTransform bodyA_trans = transA;
+	btTransform bodyB_trans = transB;
+	nrow++;
+	int s2 = nrow * s;
+	nrow++;
+	int s3 = nrow * s;
+	btVector3 tmpA(0,0,0), tmpB(0,0,0), relA(0,0,0), relB(0,0,0), c(0,0,0);
+	if(m_useOffsetForConstraintFrame)
+	{
+		// get vector from bodyB to frameB in WCS
+		relB = trB.getOrigin() - bodyB_trans.getOrigin();
+		// get its projection to slider axis
+		btVector3 projB = ax1 * relB.dot(ax1);
+		// get vector directed from bodyB to slider axis (and orthogonal to it)
+		btVector3 orthoB = relB - projB;
+		// same for bodyA
+		relA = trA.getOrigin() - bodyA_trans.getOrigin();
+		btVector3 projA = ax1 * relA.dot(ax1);
+		btVector3 orthoA = relA - projA;
+		// get desired offset between frames A and B along slider axis
+		btScalar sliderOffs = m_linPos - m_depth[0];
+		// desired vector from projection of center of bodyA to projection of center of bodyB to slider axis
+		btVector3 totalDist = projA + ax1 * sliderOffs - projB;
+		// get offset vectors relA and relB
+		relA = orthoA + totalDist * factA;
+		relB = orthoB - totalDist * factB;
+		// now choose average ortho to slider axis
+		p = orthoB * factA + orthoA * factB;
+		btScalar len2 = p.length2();
+		if(len2 > SIMD_EPSILON)
+		{
+			p /= btSqrt(len2);
+		}
+		else
+		{
+			p = trA.getBasis().getColumn(1);
+		}
+		// make one more ortho
+		q = ax1.cross(p);
+		// fill two rows
+		tmpA = relA.cross(p);
+		tmpB = relB.cross(p);
+		for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = tmpA[i];
+		for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = -tmpB[i];
+		tmpA = relA.cross(q);
+		tmpB = relB.cross(q);
+		if(hasStaticBody && getSolveAngLimit())
+		{ // to make constraint between static and dynamic objects more rigid
+			// remove wA (or wB) from equation if angular limit is hit
+			tmpB *= factB;
+			tmpA *= factA;
+		}
+		for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = tmpA[i];
+		for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = -tmpB[i];
+		for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i];
+		for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i];
+	}
+	else
+	{	// old way - maybe incorrect if bodies are not on the slider axis
+		// see discussion "Bug in slider constraint" http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=4024&start=0
+		c = bodyB_trans.getOrigin() - bodyA_trans.getOrigin();
+		btVector3 tmp = c.cross(p);
+		for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = factA*tmp[i];
+		for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = factB*tmp[i];
+		tmp = c.cross(q);
+		for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = factA*tmp[i];
+		for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = factB*tmp[i];
+
+		for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i];
+		for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i];
+	}
+	// compute two elements of right hand side
+
+	//	k = info->fps * info->erp * getSoftnessOrthoLin();
+	currERP = (m_flags & BT_SLIDER_FLAGS_ERP_ORTLIN) ? m_softnessOrthoLin : m_softnessOrthoLin * info->erp;
+	k = info->fps * currERP;
+
+	btScalar rhs = k * p.dot(ofs);
+	info->m_constraintError[s2] = rhs;
+	rhs = k * q.dot(ofs);
+	info->m_constraintError[s3] = rhs;
+	if(m_flags & BT_SLIDER_FLAGS_CFM_ORTLIN)
+	{
+		info->cfm[s2] = m_cfmOrthoLin;
+		info->cfm[s3] = m_cfmOrthoLin;
+	}
+
+
+	// check linear limits
+	limit_err = btScalar(0.0);
+	limit = 0;
 	if(getSolveLinLimit())
 	{
@@ -300,5 +467,5 @@
 		limit = (limit_err > btScalar(0.0)) ? 2 : 1;
 	}
-	int powered = 0;
+	powered = 0;
 	if(getPoweredLinMotor())
 	{
@@ -320,14 +487,30 @@
 		// a torque couple will result in limited slider-jointed free
 		// bodies from gaining angular momentum.
-		// the solution used here is to apply the constraint forces at the center of mass of the two bodies
-		btVector3 ltd;	// Linear Torque Decoupling vector (a torque)
-//		c = btScalar(0.5) * c;
-		ltd = c.cross(ax1);
-		info->m_J1angularAxis[srow+0] = factA*ltd[0];
-		info->m_J1angularAxis[srow+1] = factA*ltd[1];
-		info->m_J1angularAxis[srow+2] = factA*ltd[2];
-		info->m_J2angularAxis[srow+0] = factB*ltd[0];
-		info->m_J2angularAxis[srow+1] = factB*ltd[1];
-		info->m_J2angularAxis[srow+2] = factB*ltd[2];
+		if(m_useOffsetForConstraintFrame)
+		{
+			// this is needed only when bodyA and bodyB are both dynamic.
+			if(!hasStaticBody)
+			{
+				tmpA = relA.cross(ax1);
+				tmpB = relB.cross(ax1);
+				info->m_J1angularAxis[srow+0] = tmpA[0];
+				info->m_J1angularAxis[srow+1] = tmpA[1];
+				info->m_J1angularAxis[srow+2] = tmpA[2];
+				info->m_J2angularAxis[srow+0] = -tmpB[0];
+				info->m_J2angularAxis[srow+1] = -tmpB[1];
+				info->m_J2angularAxis[srow+2] = -tmpB[2];
+			}
+		}
+		else
+		{ // The old way. May be incorrect if bodies are not on the slider axis
+			btVector3 ltd;	// Linear Torque Decoupling vector (a torque)
+			ltd = c.cross(ax1);
+			info->m_J1angularAxis[srow+0] = factA*ltd[0];
+			info->m_J1angularAxis[srow+1] = factA*ltd[1];
+			info->m_J1angularAxis[srow+2] = factA*ltd[2];
+			info->m_J2angularAxis[srow+0] = factB*ltd[0];
+			info->m_J2angularAxis[srow+1] = factB*ltd[1];
+			info->m_J2angularAxis[srow+2] = factB*ltd[2];
+		}
 		// right-hand part
 		btScalar lostop = getLowerLinLimit();
@@ -340,10 +523,13 @@
 		info->m_lowerLimit[srow] = 0.;
 		info->m_upperLimit[srow] = 0.;
+		currERP = (m_flags & BT_SLIDER_FLAGS_ERP_LIMLIN) ? m_softnessLimLin : info->erp;
 		if(powered)
 		{
-            info->cfm[nrow] = btScalar(0.0); 
+			if(m_flags & BT_SLIDER_FLAGS_CFM_DIRLIN)
+			{
+				info->cfm[srow] = m_cfmDirLin;
+			}
 			btScalar tag_vel = getTargetLinMotorVelocity();
-			btScalar mot_fact = getMotorFactor(m_linPos, m_lowerLinLimit, m_upperLinLimit, tag_vel, info->fps * info->erp);
-//			info->m_constraintError[srow] += mot_fact * getTargetLinMotorVelocity();
+			btScalar mot_fact = getMotorFactor(m_linPos, m_lowerLinLimit, m_upperLinLimit, tag_vel, info->fps * currERP);
 			info->m_constraintError[srow] -= signFact * mot_fact * getTargetLinMotorVelocity();
 			info->m_lowerLimit[srow] += -getMaxLinMotorForce() * info->fps;
@@ -352,7 +538,10 @@
 		if(limit)
 		{
-			k = info->fps * info->erp;
+			k = info->fps * currERP;
 			info->m_constraintError[srow] += k * limit_err;
-			info->cfm[srow] = btScalar(0.0); // stop_cfm;
+			if(m_flags & BT_SLIDER_FLAGS_CFM_LIMLIN)
+			{
+				info->cfm[srow] = m_cfmLimLin;
+			}
 			if(lostop == histop) 
 			{	// limited low and high simultaneously
@@ -374,6 +563,6 @@
 			if(bounce > btScalar(0.0))
 			{
-				btScalar vel = m_rbA.getLinearVelocity().dot(ax1);
-				vel -= m_rbB.getLinearVelocity().dot(ax1);
+				btScalar vel = linVelA.dot(ax1);
+				vel -= linVelB.dot(ax1);
 				vel *= signFact;
 				// only apply bounce if the velocity is incoming, and if the
@@ -437,8 +626,12 @@
 			powered = 0;
 		}
+		currERP = (m_flags & BT_SLIDER_FLAGS_ERP_LIMANG) ? m_softnessLimAng : info->erp;
 		if(powered)
 		{
-            info->cfm[srow] = btScalar(0.0); 
-			btScalar mot_fact = getMotorFactor(m_angPos, m_lowerAngLimit, m_upperAngLimit, getTargetAngMotorVelocity(), info->fps * info->erp);
+			if(m_flags & BT_SLIDER_FLAGS_CFM_DIRANG)
+			{
+				info->cfm[srow] = m_cfmDirAng;
+			}
+			btScalar mot_fact = getMotorFactor(m_angPos, m_lowerAngLimit, m_upperAngLimit, getTargetAngMotorVelocity(), info->fps * currERP);
 			info->m_constraintError[srow] = mot_fact * getTargetAngMotorVelocity();
 			info->m_lowerLimit[srow] = -getMaxAngMotorForce() * info->fps;
@@ -447,7 +640,10 @@
 		if(limit)
 		{
-			k = info->fps * info->erp;
+			k = info->fps * currERP;
 			info->m_constraintError[srow] += k * limit_err;
-			info->cfm[srow] = btScalar(0.0); // stop_cfm;
+			if(m_flags & BT_SLIDER_FLAGS_CFM_LIMANG)
+			{
+				info->cfm[srow] = m_cfmLimAng;
+			}
 			if(lostop == histop) 
 			{
@@ -500,318 +696,162 @@
 		} // if(limit)
 	} // if angular limit or powered
-} // btSliderConstraint::getInfo2()
-
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep)
-{
-	if (m_useSolveConstraintObsolete)
-	{
-		m_timeStep = timeStep;
-		if(m_useLinearReferenceFrameA)
-		{
-			solveConstraintInt(m_rbA,bodyA, m_rbB,bodyB);
+}
+
+
+///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+///If no axis is provided, it uses the default axis for this constraint.
+void btSliderConstraint::setParam(int num, btScalar value, int axis)
+{
+	switch(num)
+	{
+	case BT_CONSTRAINT_STOP_ERP :
+		if(axis < 1)
+		{
+			m_softnessLimLin = value;
+			m_flags |= BT_SLIDER_FLAGS_ERP_LIMLIN;
+		}
+		else if(axis < 3)
+		{
+			m_softnessOrthoLin = value;
+			m_flags |= BT_SLIDER_FLAGS_ERP_ORTLIN;
+		}
+		else if(axis == 3)
+		{
+			m_softnessLimAng = value;
+			m_flags |= BT_SLIDER_FLAGS_ERP_LIMANG;
+		}
+		else if(axis < 6)
+		{
+			m_softnessOrthoAng = value;
+			m_flags |= BT_SLIDER_FLAGS_ERP_ORTANG;
 		}
 		else
 		{
-			solveConstraintInt(m_rbB,bodyB, m_rbA,bodyA);
-		}
-	}
-} // btSliderConstraint::solveConstraint()
-
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btSolverBody& bodyA,btRigidBody& rbB, btSolverBody& bodyB)
-{
-    int i;
-    // linear
-    btVector3 velA;
-	bodyA.getVelocityInLocalPointObsolete(m_relPosA,velA);
-    btVector3 velB;
-	bodyB.getVelocityInLocalPointObsolete(m_relPosB,velB);
-    btVector3 vel = velA - velB;
-	for(i = 0; i < 3; i++)
-    {
-		const btVector3& normal = m_jacLin[i].m_linearJointAxis;
-		btScalar rel_vel = normal.dot(vel);
-		// calculate positional error
-		btScalar depth = m_depth[i];
-		// get parameters
-		btScalar softness = (i) ? m_softnessOrthoLin : (m_solveLinLim ? m_softnessLimLin : m_softnessDirLin);
-		btScalar restitution = (i) ? m_restitutionOrthoLin : (m_solveLinLim ? m_restitutionLimLin : m_restitutionDirLin);
-		btScalar damping = (i) ? m_dampingOrthoLin : (m_solveLinLim ? m_dampingLimLin : m_dampingDirLin);
-		// calcutate and apply impulse
-		btScalar normalImpulse = softness * (restitution * depth / m_timeStep - damping * rel_vel) * m_jacLinDiagABInv[i];
-		btVector3 impulse_vector = normal * normalImpulse;
-		
-		//rbA.applyImpulse( impulse_vector, m_relPosA);
-		//rbB.applyImpulse(-impulse_vector, m_relPosB);
-		{
-			btVector3 ftorqueAxis1 = m_relPosA.cross(normal);
-			btVector3 ftorqueAxis2 = m_relPosB.cross(normal);
-			bodyA.applyImpulse(normal*rbA.getInvMass(), rbA.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse);
-			bodyB.applyImpulse(normal*rbB.getInvMass(), rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse);
-		}
-
-
-
-		if(m_poweredLinMotor && (!i))
-		{ // apply linear motor
-			if(m_accumulatedLinMotorImpulse < m_maxLinMotorForce)
-			{
-				btScalar desiredMotorVel = m_targetLinMotorVelocity;
-				btScalar motor_relvel = desiredMotorVel + rel_vel;
-				normalImpulse = -motor_relvel * m_jacLinDiagABInv[i];
-				// clamp accumulated impulse
-				btScalar new_acc = m_accumulatedLinMotorImpulse + btFabs(normalImpulse);
-				if(new_acc  > m_maxLinMotorForce)
-				{
-					new_acc = m_maxLinMotorForce;
-				}
-				btScalar del = new_acc  - m_accumulatedLinMotorImpulse;
-				if(normalImpulse < btScalar(0.0))
-				{
-					normalImpulse = -del;
-				}
-				else
-				{
-					normalImpulse = del;
-				}
-				m_accumulatedLinMotorImpulse = new_acc;
-				// apply clamped impulse
-				impulse_vector = normal * normalImpulse;
-				//rbA.applyImpulse( impulse_vector, m_relPosA);
-				//rbB.applyImpulse(-impulse_vector, m_relPosB);
-
-				{
-					btVector3 ftorqueAxis1 = m_relPosA.cross(normal);
-					btVector3 ftorqueAxis2 = m_relPosB.cross(normal);
-					bodyA.applyImpulse(normal*rbA.getInvMass(), rbA.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse);
-					bodyB.applyImpulse(normal*rbB.getInvMass(), rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse);
-				}
-
-
-
-			}
-		}
-    }
-	// angular 
-	// get axes in world space
-	btVector3 axisA =  m_calculatedTransformA.getBasis().getColumn(0);
-	btVector3 axisB =  m_calculatedTransformB.getBasis().getColumn(0);
-
-	btVector3 angVelA;
-	bodyA.getAngularVelocity(angVelA);
-	btVector3 angVelB;
-	bodyB.getAngularVelocity(angVelB);
-
-	btVector3 angVelAroundAxisA = axisA * axisA.dot(angVelA);
-	btVector3 angVelAroundAxisB = axisB * axisB.dot(angVelB);
-
-	btVector3 angAorthog = angVelA - angVelAroundAxisA;
-	btVector3 angBorthog = angVelB - angVelAroundAxisB;
-	btVector3 velrelOrthog = angAorthog-angBorthog;
-	//solve orthogonal angular velocity correction
-	btScalar len = velrelOrthog.length();
-	btScalar orthorImpulseMag = 0.f;
-
-	if (len > btScalar(0.00001))
-	{
-		btVector3 normal = velrelOrthog.normalized();
-		btScalar denom = rbA.computeAngularImpulseDenominator(normal) + rbB.computeAngularImpulseDenominator(normal);
-		//velrelOrthog *= (btScalar(1.)/denom) * m_dampingOrthoAng * m_softnessOrthoAng;
-		orthorImpulseMag = (btScalar(1.)/denom) * m_dampingOrthoAng * m_softnessOrthoAng;
-	}
-	//solve angular positional correction
-	btVector3 angularError = axisA.cross(axisB) *(btScalar(1.)/m_timeStep);
-	btVector3 angularAxis = angularError;
-	btScalar angularImpulseMag = 0;
-
-	btScalar len2 = angularError.length();
-	if (len2>btScalar(0.00001))
-	{
-		btVector3 normal2 = angularError.normalized();
-		btScalar denom2 = rbA.computeAngularImpulseDenominator(normal2) + rbB.computeAngularImpulseDenominator(normal2);
-		angularImpulseMag = (btScalar(1.)/denom2) * m_restitutionOrthoAng * m_softnessOrthoAng;
-		angularError *= angularImpulseMag;
-	}
-	// apply impulse
-	//rbA.applyTorqueImpulse(-velrelOrthog+angularError);
-	//rbB.applyTorqueImpulse(velrelOrthog-angularError);
-
-	bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*velrelOrthog,-orthorImpulseMag);
-	bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*velrelOrthog,orthorImpulseMag);
-	bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*angularAxis,angularImpulseMag);
-	bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*angularAxis,-angularImpulseMag);
-
-
-	btScalar impulseMag;
-	//solve angular limits
-	if(m_solveAngLim)
-	{
-		impulseMag = (angVelB - angVelA).dot(axisA) * m_dampingLimAng + m_angDepth * m_restitutionLimAng / m_timeStep;
-		impulseMag *= m_kAngle * m_softnessLimAng;
-	}
-	else
-	{
-		impulseMag = (angVelB - angVelA).dot(axisA) * m_dampingDirAng + m_angDepth * m_restitutionDirAng / m_timeStep;
-		impulseMag *= m_kAngle * m_softnessDirAng;
-	}
-	btVector3 impulse = axisA * impulseMag;
-	//rbA.applyTorqueImpulse(impulse);
-	//rbB.applyTorqueImpulse(-impulse);
-
-	bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*axisA,impulseMag);
-	bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*axisA,-impulseMag);
-
-
-
-	//apply angular motor
-	if(m_poweredAngMotor) 
-	{
-		if(m_accumulatedAngMotorImpulse < m_maxAngMotorForce)
-		{
-			btVector3 velrel = angVelAroundAxisA - angVelAroundAxisB;
-			btScalar projRelVel = velrel.dot(axisA);
-
-			btScalar desiredMotorVel = m_targetAngMotorVelocity;
-			btScalar motor_relvel = desiredMotorVel - projRelVel;
-
-			btScalar angImpulse = m_kAngle * motor_relvel;
-			// clamp accumulated impulse
-			btScalar new_acc = m_accumulatedAngMotorImpulse + btFabs(angImpulse);
-			if(new_acc  > m_maxAngMotorForce)
-			{
-				new_acc = m_maxAngMotorForce;
-			}
-			btScalar del = new_acc  - m_accumulatedAngMotorImpulse;
-			if(angImpulse < btScalar(0.0))
-			{
-				angImpulse = -del;
-			}
-			else
-			{
-				angImpulse = del;
-			}
-			m_accumulatedAngMotorImpulse = new_acc;
-			// apply clamped impulse
-			btVector3 motorImp = angImpulse * axisA;
-			//rbA.applyTorqueImpulse(motorImp);
-			//rbB.applyTorqueImpulse(-motorImp);
-
-			bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*axisA,angImpulse);
-			bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*axisA,-angImpulse);
-		}
-	}
-} // btSliderConstraint::solveConstraint()
-
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::calculateTransforms(void){
-	if(m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete))
-	{
-		m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA;
-		m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB;
-	}
-	else
-	{
-		m_calculatedTransformA = m_rbB.getCenterOfMassTransform() * m_frameInB;
-		m_calculatedTransformB = m_rbA.getCenterOfMassTransform() * m_frameInA;
-	}
-	m_realPivotAInW = m_calculatedTransformA.getOrigin();
-	m_realPivotBInW = m_calculatedTransformB.getOrigin();
-	m_sliderAxis = m_calculatedTransformA.getBasis().getColumn(0); // along X
-	if(m_useLinearReferenceFrameA || m_useSolveConstraintObsolete)
-	{
-		m_delta = m_realPivotBInW - m_realPivotAInW;
-	}
-	else
-	{
-		m_delta = m_realPivotAInW - m_realPivotBInW;
-	}
-	m_projPivotInW = m_realPivotAInW + m_sliderAxis.dot(m_delta) * m_sliderAxis;
-    btVector3 normalWorld;
-    int i;
-    //linear part
-    for(i = 0; i < 3; i++)
-    {
-		normalWorld = m_calculatedTransformA.getBasis().getColumn(i);
-		m_depth[i] = m_delta.dot(normalWorld);
-    }
-} // btSliderConstraint::calculateTransforms()
- 
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::testLinLimits(void)
-{
-	m_solveLinLim = false;
-	m_linPos = m_depth[0];
-	if(m_lowerLinLimit <= m_upperLinLimit)
-	{
-		if(m_depth[0] > m_upperLinLimit)
-		{
-			m_depth[0] -= m_upperLinLimit;
-			m_solveLinLim = true;
-		}
-		else if(m_depth[0] < m_lowerLinLimit)
-		{
-			m_depth[0] -= m_lowerLinLimit;
-			m_solveLinLim = true;
+			btAssertConstrParams(0);
+		}
+		break;
+	case BT_CONSTRAINT_CFM :
+		if(axis < 1)
+		{
+			m_cfmDirLin = value;
+			m_flags |= BT_SLIDER_FLAGS_CFM_DIRLIN;
+		}
+		else if(axis == 3)
+		{
+			m_cfmDirAng = value;
+			m_flags |= BT_SLIDER_FLAGS_CFM_DIRANG;
 		}
 		else
 		{
-			m_depth[0] = btScalar(0.);
-		}
-	}
-	else
-	{
-		m_depth[0] = btScalar(0.);
-	}
-} // btSliderConstraint::testLinLimits()
-
-//-----------------------------------------------------------------------------
-
-void btSliderConstraint::testAngLimits(void)
-{
-	m_angDepth = btScalar(0.);
-	m_solveAngLim = false;
-	if(m_lowerAngLimit <= m_upperAngLimit)
-	{
-		const btVector3 axisA0 = m_calculatedTransformA.getBasis().getColumn(1);
-		const btVector3 axisA1 = m_calculatedTransformA.getBasis().getColumn(2);
-		const btVector3 axisB0 = m_calculatedTransformB.getBasis().getColumn(1);
-		btScalar rot = btAtan2Fast(axisB0.dot(axisA1), axisB0.dot(axisA0));  
-		m_angPos = rot;
-		if(rot < m_lowerAngLimit)
-		{
-			m_angDepth = rot - m_lowerAngLimit;
-			m_solveAngLim = true;
-		} 
-		else if(rot > m_upperAngLimit)
-		{
-			m_angDepth = rot - m_upperAngLimit;
-			m_solveAngLim = true;
-		}
-	}
-} // btSliderConstraint::testAngLimits()
-	
-//-----------------------------------------------------------------------------
-
-btVector3 btSliderConstraint::getAncorInA(void)
-{
-	btVector3 ancorInA;
-	ancorInA = m_realPivotAInW + (m_lowerLinLimit + m_upperLinLimit) * btScalar(0.5) * m_sliderAxis;
-	ancorInA = m_rbA.getCenterOfMassTransform().inverse() * ancorInA;
-	return ancorInA;
-} // btSliderConstraint::getAncorInA()
-
-//-----------------------------------------------------------------------------
-
-btVector3 btSliderConstraint::getAncorInB(void)
-{
-	btVector3 ancorInB;
-	ancorInB = m_frameInB.getOrigin();
-	return ancorInB;
-} // btSliderConstraint::getAncorInB();
+			btAssertConstrParams(0);
+		}
+		break;
+	case BT_CONSTRAINT_STOP_CFM :
+		if(axis < 1)
+		{
+			m_cfmLimLin = value;
+			m_flags |= BT_SLIDER_FLAGS_CFM_LIMLIN;
+		}
+		else if(axis < 3)
+		{
+			m_cfmOrthoLin = value;
+			m_flags |= BT_SLIDER_FLAGS_CFM_ORTLIN;
+		}
+		else if(axis == 3)
+		{
+			m_cfmLimAng = value;
+			m_flags |= BT_SLIDER_FLAGS_CFM_LIMANG;
+		}
+		else if(axis < 6)
+		{
+			m_cfmOrthoAng = value;
+			m_flags |= BT_SLIDER_FLAGS_CFM_ORTANG;
+		}
+		else
+		{
+			btAssertConstrParams(0);
+		}
+		break;
+	}
+}
+
+///return the local value of parameter
+btScalar btSliderConstraint::getParam(int num, int axis) const 
+{
+	btScalar retVal(SIMD_INFINITY);
+	switch(num)
+	{
+	case BT_CONSTRAINT_STOP_ERP :
+		if(axis < 1)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_LIMLIN);
+			retVal = m_softnessLimLin;
+		}
+		else if(axis < 3)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_ORTLIN);
+			retVal = m_softnessOrthoLin;
+		}
+		else if(axis == 3)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_LIMANG);
+			retVal = m_softnessLimAng;
+		}
+		else if(axis < 6)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_ORTANG);
+			retVal = m_softnessOrthoAng;
+		}
+		else
+		{
+			btAssertConstrParams(0);
+		}
+		break;
+	case BT_CONSTRAINT_CFM :
+		if(axis < 1)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_DIRLIN);
+			retVal = m_cfmDirLin;
+		}
+		else if(axis == 3)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_DIRANG);
+			retVal = m_cfmDirAng;
+		}
+		else
+		{
+			btAssertConstrParams(0);
+		}
+		break;
+	case BT_CONSTRAINT_STOP_CFM :
+		if(axis < 1)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_LIMLIN);
+			retVal = m_cfmLimLin;
+		}
+		else if(axis < 3)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_ORTLIN);
+			retVal = m_cfmOrthoLin;
+		}
+		else if(axis == 3)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_LIMANG);
+			retVal = m_cfmLimAng;
+		}
+		else if(axis < 6)
+		{
+			btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_ORTANG);
+			retVal = m_cfmOrthoAng;
+		}
+		else
+		{
+			btAssertConstrParams(0);
+		}
+		break;
+	}
+	return retVal;
+}
+
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h	(revision 8284)
@@ -26,5 +26,5 @@
 #define SLIDER_CONSTRAINT_H
 
-//-----------------------------------------------------------------------------
+
 
 #include "LinearMath/btVector3.h"
@@ -32,15 +32,32 @@
 #include "btTypedConstraint.h"
 
-//-----------------------------------------------------------------------------
+
 
 class btRigidBody;
 
-//-----------------------------------------------------------------------------
+
 
 #define SLIDER_CONSTRAINT_DEF_SOFTNESS		(btScalar(1.0))
 #define SLIDER_CONSTRAINT_DEF_DAMPING		(btScalar(1.0))
 #define SLIDER_CONSTRAINT_DEF_RESTITUTION	(btScalar(0.7))
-
-//-----------------------------------------------------------------------------
+#define SLIDER_CONSTRAINT_DEF_CFM			(btScalar(0.f))
+
+
+enum btSliderFlags
+{
+	BT_SLIDER_FLAGS_CFM_DIRLIN = (1 << 0),
+	BT_SLIDER_FLAGS_ERP_DIRLIN = (1 << 1),
+	BT_SLIDER_FLAGS_CFM_DIRANG = (1 << 2),
+	BT_SLIDER_FLAGS_ERP_DIRANG = (1 << 3),
+	BT_SLIDER_FLAGS_CFM_ORTLIN = (1 << 4),
+	BT_SLIDER_FLAGS_ERP_ORTLIN = (1 << 5),
+	BT_SLIDER_FLAGS_CFM_ORTANG = (1 << 6),
+	BT_SLIDER_FLAGS_ERP_ORTANG = (1 << 7),
+	BT_SLIDER_FLAGS_CFM_LIMLIN = (1 << 8),
+	BT_SLIDER_FLAGS_ERP_LIMLIN = (1 << 9),
+	BT_SLIDER_FLAGS_CFM_LIMANG = (1 << 10),
+	BT_SLIDER_FLAGS_ERP_LIMANG = (1 << 11)
+};
+
 
 class btSliderConstraint : public btTypedConstraint
@@ -49,4 +66,5 @@
 	///for backwards compatibility during the transition to 'getInfo/getInfo2'
 	bool		m_useSolveConstraintObsolete;
+	bool		m_useOffsetForConstraintFrame;
 	btTransform	m_frameInA;
     btTransform	m_frameInB;
@@ -68,23 +86,36 @@
 	btScalar m_restitutionDirLin;
 	btScalar m_dampingDirLin;
+	btScalar m_cfmDirLin;
+
 	btScalar m_softnessDirAng;
 	btScalar m_restitutionDirAng;
 	btScalar m_dampingDirAng;
+	btScalar m_cfmDirAng;
+
 	btScalar m_softnessLimLin;
 	btScalar m_restitutionLimLin;
 	btScalar m_dampingLimLin;
+	btScalar m_cfmLimLin;
+
 	btScalar m_softnessLimAng;
 	btScalar m_restitutionLimAng;
 	btScalar m_dampingLimAng;
+	btScalar m_cfmLimAng;
+
 	btScalar m_softnessOrthoLin;
 	btScalar m_restitutionOrthoLin;
 	btScalar m_dampingOrthoLin;
+	btScalar m_cfmOrthoLin;
+
 	btScalar m_softnessOrthoAng;
 	btScalar m_restitutionOrthoAng;
 	btScalar m_dampingOrthoAng;
+	btScalar m_cfmOrthoAng;
 	
 	// for interlal use
 	bool m_solveLinLim;
 	bool m_solveAngLim;
+
+	int m_flags;
 
 	btJacobianEntry	m_jacLin[3];
@@ -127,13 +158,16 @@
 	// constructors
     btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
-    btSliderConstraint();
+    btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
+
 	// overrides
-    virtual void	buildJacobian();
+
     virtual void getInfo1 (btConstraintInfo1* info);
+
+	void getInfo1NonVirtual(btConstraintInfo1* info);
 	
 	virtual void getInfo2 (btConstraintInfo2* info);
 
-    virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
-	
+	void getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB, btScalar rbAinvMass,btScalar rbBinvMass);
+
 
 	// access
@@ -151,7 +185,7 @@
     void setUpperLinLimit(btScalar upperLimit) { m_upperLinLimit = upperLimit; }
     btScalar getLowerAngLimit() { return m_lowerAngLimit; }
-    void setLowerAngLimit(btScalar lowerLimit) { m_lowerAngLimit = lowerLimit; }
+    void setLowerAngLimit(btScalar lowerLimit) { m_lowerAngLimit = btNormalizeAngle(lowerLimit); }
     btScalar getUpperAngLimit() { return m_upperAngLimit; }
-    void setUpperAngLimit(btScalar upperLimit) { m_upperAngLimit = upperLimit; }
+    void setUpperAngLimit(btScalar upperLimit) { m_upperAngLimit = btNormalizeAngle(upperLimit); }
 	bool getUseLinearReferenceFrameA() { return m_useLinearReferenceFrameA; }
 	btScalar getSoftnessDirLin() { return m_softnessDirLin; }
@@ -211,18 +245,76 @@
 	bool getSolveAngLimit() { return m_solveAngLim; }
 	btScalar getAngDepth() { return m_angDepth; }
-	// internal
-    void	buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB);
-    void	solveConstraintInt(btRigidBody& rbA, btSolverBody& bodyA,btRigidBody& rbB, btSolverBody& bodyB);
 	// shared code used by ODE solver
-	void	calculateTransforms(void);
-	void	testLinLimits(void);
-	void	testLinLimits2(btConstraintInfo2* info);
-	void	testAngLimits(void);
+	void	calculateTransforms(const btTransform& transA,const btTransform& transB);
+	void	testLinLimits();
+	void	testAngLimits();
 	// access for PE Solver
-	btVector3 getAncorInA(void);
-	btVector3 getAncorInB(void);
+	btVector3 getAncorInA();
+	btVector3 getAncorInB();
+	// access for UseFrameOffset
+	bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; }
+	void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; }
+
+	///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+	///If no axis is provided, it uses the default axis for this constraint.
+	virtual	void	setParam(int num, btScalar value, int axis = -1);
+	///return the local value of parameter
+	virtual	btScalar getParam(int num, int axis = -1) const;
+
+	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 btSliderConstraintData
+{
+	btTypedConstraintData	m_typeConstraintData;
+	btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis.
+	btTransformFloatData m_rbBFrame;
+	
+	float	m_linearUpperLimit;
+	float	m_linearLowerLimit;
+
+	float	m_angularUpperLimit;
+	float	m_angularLowerLimit;
+
+	int	m_useLinearReferenceFrameA;
+	int m_useOffsetForConstraintFrame;
+
+};
+
+
+SIMD_FORCE_INLINE		int	btSliderConstraint::calculateSerializeBufferSize() const
+{
+	return sizeof(btSliderConstraintData);
+}
+
+	///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;
+	btTypedConstraint::serialize(&sliderData->m_typeConstraintData,serializer);
+
+	m_frameInA.serializeFloat(sliderData->m_rbAFrame);
+	m_frameInB.serializeFloat(sliderData->m_rbBFrame);
+
+	sliderData->m_linearUpperLimit = float(m_upperLinLimit);
+	sliderData->m_linearLowerLimit = float(m_lowerLinLimit);
+
+	sliderData->m_angularUpperLimit = float(m_upperAngLimit);
+	sliderData->m_angularLowerLimit = float(m_lowerAngLimit);
+
+	sliderData->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA;
+	sliderData->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame;
+
+	return "btSliderConstraintData";
+}
+
+
 
 #endif //SLIDER_CONSTRAINT_H
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h	(revision 8284)
@@ -106,15 +106,14 @@
 
 ///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
-ATTRIBUTE_ALIGNED16 (struct)	btSolverBody
+ATTRIBUTE_ALIGNED64 (struct)	btSolverBodyObsolete
 {
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 	btVector3		m_deltaLinearVelocity;
 	btVector3		m_deltaAngularVelocity;
-	btScalar		m_angularFactor;
-	btScalar		m_invMass;
-	btScalar		m_friction;
+	btVector3		m_angularFactor;
+	btVector3		m_invMass;
 	btRigidBody*	m_originalBody;
 	btVector3		m_pushVelocity;
-	//btVector3		m_turnVelocity;	
+	btVector3		m_turnVelocity;
 
 	
@@ -146,10 +145,16 @@
 	}
 
-	
-/*
+	SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
+	{
+		if (m_originalBody)
+		{
+			m_pushVelocity += linearComponent*impulseMagnitude;
+			m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
+		}
+	}
 	
 	void	writebackVelocity()
 	{
-		if (m_invMass)
+		if (m_originalBody)
 		{
 			m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+ m_deltaLinearVelocity);
@@ -159,12 +164,19 @@
 		}
 	}
-	*/
 
-	void	writebackVelocity(btScalar timeStep=0)
+
+	void	writebackVelocity(btScalar timeStep)
 	{
-		if (m_invMass)
+        (void) timeStep;
+		if (m_originalBody)
 		{
-			m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+m_deltaLinearVelocity);
+			m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+ m_deltaLinearVelocity);
 			m_originalBody->setAngularVelocity(m_originalBody->getAngularVelocity()+m_deltaAngularVelocity);
+			
+			//correct the position/orientation based on push/turn recovery
+			btTransform newTransform;
+			btTransformUtil::integrateTransform(m_originalBody->getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform);
+			m_originalBody->setWorldTransform(newTransform);
+			
 			//m_originalBody->setCompanionId(-1);
 		}
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverConstraint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverConstraint.h	(revision 8284)
@@ -27,5 +27,5 @@
 
 ///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints.
-ATTRIBUTE_ALIGNED16 (struct)	btSolverConstraint
+ATTRIBUTE_ALIGNED64 (struct)	btSolverConstraint
 {
 	BT_DECLARE_ALIGNED_ALLOCATOR();
@@ -59,11 +59,11 @@
 	union
 	{
-		int			m_solverBodyIdA;
-		btScalar	m_unusedPadding2;
+		btRigidBody*	m_solverBodyA;
+		int				m_companionIdA;
 	};
 	union
 	{
-		int			m_solverBodyIdB;
-		btScalar	m_unusedPadding3;
+		btRigidBody*	m_solverBodyB;
+		int				m_companionIdB;
 	};
 	
@@ -78,4 +78,6 @@
 	btScalar		m_lowerLimit;
 	btScalar		m_upperLimit;
+
+	btScalar		m_rhsPenetration;
 
 	enum		btSolverConstraintType
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp	(revision 8284)
@@ -17,38 +17,27 @@
 #include "btTypedConstraint.h"
 #include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btSerializer.h"
 
-static btRigidBody s_fixed(0, 0,0);
 
 #define DEFAULT_DEBUGDRAW_SIZE btScalar(0.3f)
 
-btTypedConstraint::btTypedConstraint(btTypedConstraintType type)
-:m_userConstraintType(-1),
+btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA)
+:btTypedObject(type),
+m_userConstraintType(-1),
 m_userConstraintId(-1),
-m_constraintType (type),
-m_rbA(s_fixed),
-m_rbB(s_fixed),
+m_needsFeedback(false),
+m_rbA(rbA),
+m_rbB(getFixedBody()),
 m_appliedImpulse(btScalar(0.)),
 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
 {
-	s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
-}
-btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA)
-:m_userConstraintType(-1),
-m_userConstraintId(-1),
-m_constraintType (type),
-m_rbA(rbA),
-m_rbB(s_fixed),
-m_appliedImpulse(btScalar(0.)),
-m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
-{
-		s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
-
 }
 
 
 btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB)
-:m_userConstraintType(-1),
+:btTypedObject(type),
+m_userConstraintType(-1),
 m_userConstraintId(-1),
-m_constraintType (type),
+m_needsFeedback(false),
 m_rbA(rbA),
 m_rbB(rbB),
@@ -56,10 +45,8 @@
 m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
 {
-		s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
-
 }
 
 
-//-----------------------------------------------------------------------------
+
 
 btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)
@@ -110,5 +97,46 @@
 	}
 	return lim_fact;
-} // btTypedConstraint::getMotorFactor()
+}
 
+///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;
 
+	tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA);
+	tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB);
+	char* name = (char*) serializer->findNameForPointer(this);
+	tcd->m_name = (char*)serializer->getUniquePointer(name);
+	if (tcd->m_name)
+	{
+		serializer->serializeName(name);
+	}
+
+	tcd->m_objectType = m_objectType;
+	tcd->m_needsFeedback = m_needsFeedback;
+	tcd->m_userConstraintId =m_userConstraintId;
+	tcd->m_userConstraintType =m_userConstraintType;
+
+	tcd->m_appliedImpulse = float(m_appliedImpulse);
+	tcd->m_dbgDrawSize = float(m_dbgDrawSize );
+
+	tcd->m_disableCollisionsBetweenLinkedBodies = false;
+
+	int i;
+	for (i=0;i<m_rbA.getNumConstraintRefs();i++)
+		if (m_rbA.getConstraintRef(i) == this)
+			tcd->m_disableCollisionsBetweenLinkedBodies = true;
+	for (i=0;i<m_rbB.getNumConstraintRefs();i++)
+		if (m_rbB.getConstraintRef(i) == this)
+			tcd->m_disableCollisionsBetweenLinkedBodies = true;
+
+	return "btTypedConstraintData";
+}
+
+btRigidBody& btTypedConstraint::getFixedBody()
+{
+	static btRigidBody s_fixed(0, 0,0);
+	s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
+	return s_fixed;
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2010 Erwin Coumans  http://continuousphysics.com/Bullet/
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -20,25 +20,46 @@
 #include "LinearMath/btScalar.h"
 #include "btSolverConstraint.h"
-struct  btSolverBody;
-
-
-
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+
+class btSerializer;
 
 enum btTypedConstraintType
 {
-	POINT2POINT_CONSTRAINT_TYPE,
+	POINT2POINT_CONSTRAINT_TYPE=MAX_CONTACT_MANIFOLD_TYPE+1,
 	HINGE_CONSTRAINT_TYPE,
 	CONETWIST_CONSTRAINT_TYPE,
 	D6_CONSTRAINT_TYPE,
-	SLIDER_CONSTRAINT_TYPE
+	SLIDER_CONSTRAINT_TYPE,
+	CONTACT_CONSTRAINT_TYPE
 };
 
+
+enum btConstraintParams
+{
+	BT_CONSTRAINT_ERP=1,
+	BT_CONSTRAINT_STOP_ERP,
+	BT_CONSTRAINT_CFM,
+	BT_CONSTRAINT_STOP_CFM
+};
+
+#if 1
+	#define btAssertConstrParams(_par) btAssert(_par) 
+#else
+	#define btAssertConstrParams(_par)
+#endif
+
+
 ///TypedConstraint is the baseclass for Bullet constraints and vehicles
-class btTypedConstraint
+class btTypedConstraint : public btTypedObject
 {
 	int	m_userConstraintType;
-	int	m_userConstraintId;
-
-	btTypedConstraintType m_constraintType;
+
+	union
+	{
+		int	m_userConstraintId;
+		void* m_userConstraintPtr;
+	};
+
+	bool m_needsFeedback;
 
 	btTypedConstraint&	operator=(btTypedConstraint&	other)
@@ -55,8 +76,11 @@
 	btScalar	m_dbgDrawSize;
 
+	///internal method used by the constraint solver, don't use them directly
+	btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
+	
+	static btRigidBody& getFixedBody();
 
 public:
 
-	btTypedConstraint(btTypedConstraintType type);
 	virtual ~btTypedConstraint() {};
 	btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA);
@@ -94,19 +118,43 @@
 		// the constraint.
 		int *findex;
+		// number of solver iterations
+		int m_numIterations;
+
+		//damping of the velocity
+		btScalar	m_damping;
 	};
 
-
-	virtual void	buildJacobian() = 0;
-
+	///internal method used by the constraint solver, don't use them directly
+	virtual void	buildJacobian() {};
+
+	///internal method used by the constraint solver, don't use them directly
 	virtual	void	setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
 	{
-	}
+        (void)ca;
+        (void)solverBodyA;
+        (void)solverBodyB;
+        (void)timeStep;
+	}
+	
+	///internal method used by the constraint solver, don't use them directly
 	virtual void getInfo1 (btConstraintInfo1* info)=0;
 
+	///internal method used by the constraint solver, don't use them directly
 	virtual void getInfo2 (btConstraintInfo2* info)=0;
 
-	virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep) = 0;
-
-	btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
+	///internal method used by the constraint solver, don't use them directly
+	void	internalSetAppliedImpulse(btScalar appliedImpulse)
+	{
+		m_appliedImpulse = appliedImpulse;
+	}
+	///internal method used by the constraint solver, don't use them directly
+	btScalar	internalGetAppliedImpulse()
+	{
+		return m_appliedImpulse;
+	}
+
+	///internal method used by the constraint solver, don't use them directly
+	virtual	void	solveConstraintObsolete(btRigidBody& /*bodyA*/,btRigidBody& /*bodyB*/,btScalar	/*timeStep*/) {};
+
 	
 	const btRigidBody& getRigidBodyA() const
@@ -148,4 +196,14 @@
 	}
 
+	void	setUserConstraintPtr(void* ptr)
+	{
+		m_userConstraintPtr = ptr;
+	}
+
+	void*	getUserConstraintPtr()
+	{
+		return m_userConstraintPtr;
+	}
+
 	int getUid() const
 	{
@@ -153,6 +211,21 @@
 	} 
 
+	bool	needsFeedback() const
+	{
+		return m_needsFeedback;
+	}
+
+	///enableFeedback will allow to read the applied linear and angular impulse
+	///use getAppliedImpulse, getAppliedLinearImpulse and getAppliedAngularImpulse to read feedback information
+	void	enableFeedback(bool needsFeedback)
+	{
+		m_needsFeedback = needsFeedback;
+	}
+
+	///getAppliedImpulse is an estimated total applied impulse. 
+	///This feedback could be used to determine breaking constraints or playing sounds.
 	btScalar	getAppliedImpulse() const
 	{
+		btAssert(m_needsFeedback);
 		return m_appliedImpulse;
 	}
@@ -160,5 +233,5 @@
 	btTypedConstraintType getConstraintType () const
 	{
-		return m_constraintType;
+		return btTypedConstraintType(m_objectType);
 	}
 	
@@ -171,6 +244,72 @@
 		return m_dbgDrawSize;
 	}
-	
+
+	///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). 
+	///If no axis is provided, it uses the default axis for this constraint.
+	virtual	void	setParam(int num, btScalar value, int axis = -1) = 0;
+
+	///return the local value of parameter
+	virtual	btScalar getParam(int num, int axis = -1) const = 0;
+	
+	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;
+
 };
 
+// returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits 
+// all arguments should be normalized angles (i.e. in range [-SIMD_PI, SIMD_PI])
+SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians)
+{
+	if(angleLowerLimitInRadians >= angleUpperLimitInRadians)
+	{
+		return angleInRadians;
+	}
+	else if(angleInRadians < angleLowerLimitInRadians)
+	{
+		btScalar diffLo = btFabs(btNormalizeAngle(angleLowerLimitInRadians - angleInRadians));
+		btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians));
+		return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI);
+	}
+	else if(angleInRadians > angleUpperLimitInRadians)
+	{
+		btScalar diffHi = btFabs(btNormalizeAngle(angleInRadians - angleUpperLimitInRadians));
+		btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians));
+		return (diffLo < diffHi) ? (angleInRadians - SIMD_2_PI) : angleInRadians;
+	}
+	else
+	{
+		return angleInRadians;
+	}
+}
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btTypedConstraintData
+{
+	btRigidBodyData		*m_rbA;
+	btRigidBodyData		*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;
+	char	m_pad4[4];
+	
+};
+
+SIMD_FORCE_INLINE	int	btTypedConstraint::calculateSerializeBufferSize() const
+{
+	return sizeof(btTypedConstraintData);
+}
+
+
+
+
 #endif //TYPED_CONSTRAINT_H
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp	(revision 8284)
@@ -0,0 +1,63 @@
+/*
+Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
+Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. 
+
+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 "btUniversalConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btTransformUtil.h"
+
+
+
+#define UNIV_EPS btScalar(0.01f)
+
+
+// constructor
+// anchor, axis1 and axis2 are in world coordinate system
+// axis1 must be orthogonal to axis2
+btUniversalConstraint::btUniversalConstraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2)
+: btGeneric6DofConstraint(rbA, rbB, btTransform::getIdentity(), btTransform::getIdentity(), true),
+ m_anchor(anchor),
+ m_axis1(axis1),
+ m_axis2(axis2)
+{
+	// build frame basis
+	// 6DOF constraint uses Euler angles and to define limits
+	// it is assumed that rotational order is :
+	// Z - first, allowed limits are (-PI,PI);
+	// new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number 
+	// used to prevent constraint from instability on poles;
+	// new position of X, allowed limits are (-PI,PI);
+	// So to simulate ODE Universal joint we should use parent axis as Z, child axis as Y and limit all other DOFs
+	// Build the frame in world coordinate system first
+	btVector3 zAxis = axis1.normalize();
+	btVector3 yAxis = axis2.normalize();
+	btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system
+	btTransform frameInW;
+	frameInW.setIdentity();
+	frameInW.getBasis().setValue(	xAxis[0], yAxis[0], zAxis[0],	
+									xAxis[1], yAxis[1], zAxis[1],
+									xAxis[2], yAxis[2], zAxis[2]);
+	frameInW.setOrigin(anchor);
+	// now get constraint frame in local coordinate systems
+	m_frameInA = rbA.getCenterOfMassTransform().inverse() * frameInW;
+	m_frameInB = rbB.getCenterOfMassTransform().inverse() * frameInW;
+	// sei limits
+	setLinearLowerLimit(btVector3(0., 0., 0.));
+	setLinearUpperLimit(btVector3(0., 0., 0.));
+	setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI + UNIV_EPS, -SIMD_PI + UNIV_EPS));
+	setAngularUpperLimit(btVector3(0.f,  SIMD_HALF_PI - UNIV_EPS,  SIMD_PI - UNIV_EPS));
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btUniversalConstraint.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/ConstraintSolver/btUniversalConstraint.h	(revision 8284)
@@ -0,0 +1,60 @@
+/*
+Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
+Copyright (C) 2006, 2007 Sony Computer Entertainment Inc. 
+
+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 UNIVERSAL_CONSTRAINT_H
+#define UNIVERSAL_CONSTRAINT_H
+
+
+
+#include "LinearMath/btVector3.h"
+#include "btTypedConstraint.h"
+#include "btGeneric6DofConstraint.h"
+
+
+
+/// Constraint similar to ODE Universal Joint
+/// has 2 rotatioonal degrees of freedom, similar to Euler rotations around Z (axis 1)
+/// and Y (axis 2)
+/// Description from ODE manual : 
+/// "Given axis 1 on body 1, and axis 2 on body 2 that is perpendicular to axis 1, it keeps them perpendicular. 
+/// In other words, rotation of the two bodies about the direction perpendicular to the two axes will be equal."
+
+class btUniversalConstraint : public btGeneric6DofConstraint
+{
+protected:
+	btVector3	m_anchor;
+	btVector3	m_axis1;
+	btVector3	m_axis2;
+public:
+	// constructor
+	// anchor, axis1 and axis2 are in world coordinate system
+	// axis1 must be orthogonal to axis2
+    btUniversalConstraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2);
+	// access
+	const btVector3& getAnchor() { return m_calculatedTransformA.getOrigin(); }
+	const btVector3& getAnchor2() { return m_calculatedTransformB.getOrigin(); }
+	const btVector3& getAxis1() { return m_axis1; }
+	const btVector3& getAxis2() { return m_axis2; }
+	btScalar getAngle1() { return getAngle(2); }
+	btScalar getAngle2() { return getAngle(1); }
+	// limits
+	void setUpperLimit(btScalar ang1max, btScalar ang2max) { setAngularUpperLimit(btVector3(0.f, ang1max, ang2max)); }
+	void setLowerLimit(btScalar ang1min, btScalar ang2min) { setAngularLowerLimit(btVector3(0.f, ang1min, ang2min)); }
+};
+
+
+
+#endif // UNIVERSAL_CONSTRAINT_H
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp	(revision 8284)
@@ -44,5 +44,5 @@
 #include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
 #include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
-#include "LinearMath/btStackAlloc.h"
+
 
 /*
@@ -182,10 +182,10 @@
 {
 	//capsule is convex hull of 2 spheres, so use btMultiSphereShape
-	btVector3 inertiaHalfExtents(radius,height,radius);
+	
 	const int numSpheres = 2;
 	btVector3 positions[numSpheres] = {btVector3(0,height,0),btVector3(0,-height,0)};
 	btScalar radi[numSpheres] = {radius,radius};
 	void* mem = btAlignedAlloc(sizeof(btMultiSphereShape),16);
-	return (plCollisionShapeHandle) new (mem)btMultiSphereShape(inertiaHalfExtents,positions,radi,numSpheres);
+	return (plCollisionShapeHandle) new (mem)btMultiSphereShape(positions,radi,numSpheres);
 }
 plCollisionShapeHandle plNewConeShape(plReal radius, plReal height)
@@ -294,4 +294,12 @@
 	worldTrans.setRotation(orn);
 	body->setWorldTransform(worldTrans);
+}
+
+void	plSetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix)
+{
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
+	btTransform& worldTrans = body->getWorldTransform();
+	worldTrans.setFromOpenGLMatrix(matrix);
 }
 
@@ -366,8 +374,5 @@
 	btGjkPairDetector::ClosestPointInput input;
 	
-	btStackAlloc gStackAlloc(1024*1024*2);
- 
-	input.m_stackAlloc = &gStackAlloc;
-	
+		
 	btTransform tr;
 	tr.setIdentity();
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btActionInterface.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btActionInterface.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btActionInterface.h	(revision 8284)
@@ -21,9 +21,15 @@
 
 #include "LinearMath/btScalar.h"
+#include "btRigidBody.h"
 
 ///Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWorld
 class btActionInterface
 {
-	public:
+protected:
+
+	static btRigidBody& getFixedBody();
+	
+	
+public:
 
 	virtual ~btActionInterface()
@@ -38,2 +44,3 @@
 
 #endif //_BT_ACTION_INTERFACE_H
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp	(revision 8284)
@@ -49,4 +49,8 @@
 	startProfiling(timeStep);
 	
+	if(0 != m_internalPreTickCallback) {
+		(*m_internalPreTickCallback)(this, timeStep);
+	}
+
 
 	///update aabbs information
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -20,4 +20,5 @@
 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
 #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
 #include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
@@ -36,18 +37,6 @@
 #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
 
-//for debug rendering
-#include "BulletCollision/CollisionShapes/btBoxShape.h"
-#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
-#include "BulletCollision/CollisionShapes/btCompoundShape.h"
-#include "BulletCollision/CollisionShapes/btConeShape.h"
-#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
-#include "BulletCollision/CollisionShapes/btCylinderShape.h"
-#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
-#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
+#include "LinearMath/btIDebugDraw.h"
 #include "BulletCollision/CollisionShapes/btSphereShape.h"
-#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
-#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
-#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
-#include "LinearMath/btIDebugDraw.h"
 
 
@@ -56,5 +45,5 @@
 #include "LinearMath/btMotionState.h"
 
-
+#include "LinearMath/btSerializer.h"
 
 
@@ -64,5 +53,6 @@
 m_constraintSolver(constraintSolver),
 m_gravity(0,-10,0),
-m_localTime(btScalar(1.)/btScalar(60.)),
+m_localTime(0),
+m_synchronizeAllMotionStates(false),
 m_profileTimings(0)
 {
@@ -104,21 +94,21 @@
 void	btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
 {
-
+///would like to iterate over m_nonStaticRigidBodies, but unfortunately old API allows
+///to switch status _after_ adding kinematic objects to the world
+///fix it for Bullet 3.x release
 	for (int i=0;i<m_collisionObjects.size();i++)
 	{
 		btCollisionObject* colObj = m_collisionObjects[i];
 		btRigidBody* body = btRigidBody::upcast(colObj);
-		if (body)
-		{
-				if (body->getActivationState() != ISLAND_SLEEPING)
-				{
-					if (body->isKinematicObject())
-					{
-						//to calculate velocities next frame
-						body->saveKinematicState(timeStep);
-					}
-				}
-		}
-	}
+		if (body && body->getActivationState() != ISLAND_SLEEPING)
+		{
+			if (body->isKinematicObject())
+			{
+				//to calculate velocities next frame
+				body->saveKinematicState(timeStep);
+			}
+		}
+	}
+
 }
 
@@ -127,22 +117,6 @@
 	BT_PROFILE("debugDrawWorld");
 
-	if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
-	{
-		int numManifolds = getDispatcher()->getNumManifolds();
-		btVector3 color(0,0,0);
-		for (int i=0;i<numManifolds;i++)
-		{
-			btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
-			//btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
-			//btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
-
-			int numContacts = contactManifold->getNumContacts();
-			for (int j=0;j<numContacts;j++)
-			{
-				btManifoldPoint& cp = contactManifold->getContactPoint(j);
-				getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
-			}
-		}
-	}
+	btCollisionWorld::debugDrawWorld();
+
 	bool drawConstraints = false;
 	if (getDebugDrawer())
@@ -169,40 +143,4 @@
 		int i;
 
-		for (  i=0;i<m_collisionObjects.size();i++)
-		{
-			btCollisionObject* colObj = m_collisionObjects[i];
-			if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
-			{
-				btVector3 color(btScalar(255.),btScalar(255.),btScalar(255.));
-				switch(colObj->getActivationState())
-				{
-				case  ACTIVE_TAG:
-					color = btVector3(btScalar(255.),btScalar(255.),btScalar(255.)); break;
-				case ISLAND_SLEEPING:
-					color =  btVector3(btScalar(0.),btScalar(255.),btScalar(0.));break;
-				case WANTS_DEACTIVATION:
-					color = btVector3(btScalar(0.),btScalar(255.),btScalar(255.));break;
-				case DISABLE_DEACTIVATION:
-					color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));break;
-				case DISABLE_SIMULATION:
-					color = btVector3(btScalar(255.),btScalar(255.),btScalar(0.));break;
-				default:
-					{
-						color = btVector3(btScalar(255.),btScalar(0.),btScalar(0.));
-					}
-				};
-
-				debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color);
-			}
-			if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
-			{
-				btVector3 minAabb,maxAabb;
-				btVector3 colorvec(1,0,0);
-				colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
-				m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
-			}
-
-		}
-	
 		if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
 		{
@@ -218,13 +156,10 @@
 {
 	///@todo: iterate over awake simulation islands!
-	for ( int i=0;i<m_collisionObjects.size();i++)
-	{
-		btCollisionObject* colObj = m_collisionObjects[i];
-		
-		btRigidBody* body = btRigidBody::upcast(colObj);
-		if (body)
-		{
-			body->clearForces();
-		}
+	for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+	{
+		btRigidBody* body = m_nonStaticRigidBodies[i];
+		//need to check if next line is ok
+		//it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up
+		body->clearForces();
 	}
 }	
@@ -234,10 +169,8 @@
 {
 	///@todo: iterate over awake simulation islands!
-	for ( int i=0;i<m_collisionObjects.size();i++)
-	{
-		btCollisionObject* colObj = m_collisionObjects[i];
-		
-		btRigidBody* body = btRigidBody::upcast(colObj);
-		if (body && body->isActive())
+	for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+	{
+		btRigidBody* body = m_nonStaticRigidBodies[i];
+		if (body->isActive())
 		{
 			body->applyGravity();
@@ -270,30 +203,24 @@
 {
 	BT_PROFILE("synchronizeMotionStates");
-	{
-		//todo: iterate over awake simulation islands!
+	if (m_synchronizeAllMotionStates)
+	{
+		//iterate  over all collision objects
 		for ( int i=0;i<m_collisionObjects.size();i++)
 		{
 			btCollisionObject* colObj = m_collisionObjects[i];
-			
 			btRigidBody* body = btRigidBody::upcast(colObj);
 			if (body)
 				synchronizeSingleMotionState(body);
 		}
-	}
-/*
-	if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
-	{
-		for ( int i=0;i<this->m_vehicles.size();i++)
-		{
-			for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
-			{
-				//synchronize the wheels with the (interpolated) chassis worldtransform
-				m_vehicles[i]->updateWheelTransform(v,true);
-			}
-		}
-	}
-	*/
-
-
+	} else
+	{
+		//iterate over all active rigid bodies
+		for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+		{
+			btRigidBody* body = m_nonStaticRigidBodies[i];
+			if (body->isActive())
+				synchronizeSingleMotionState(body);
+		}
+	}
 }
 
@@ -341,11 +268,13 @@
 	{
 
-		saveKinematicState(fixedTimeStep);
-
-		applyGravity();
-
 		//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
 		int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
 
+		saveKinematicState(fixedTimeStep*clampedSimulationSteps);
+
+		applyGravity();
+
+		
+
 		for (int i=0;i<clampedSimulationSteps;i++)
 		{
@@ -354,7 +283,8 @@
 		}
 
-	} 
-
-	synchronizeMotionStates();
+	} else
+	{
+		synchronizeMotionStates();
+	}
 
 	clearForces();
@@ -372,4 +302,8 @@
 	BT_PROFILE("internalSingleStepSimulation");
 
+	if(0 != m_internalPreTickCallback) {
+		(*m_internalPreTickCallback)(this, timeStep);
+	}	
+
 	///apply gravity, predict motion
 	predictUnconstraintMotion(timeStep);
@@ -412,9 +346,8 @@
 {
 	m_gravity = gravity;
-	for ( int i=0;i<m_collisionObjects.size();i++)
-	{
-		btCollisionObject* colObj = m_collisionObjects[i];
-		btRigidBody* body = btRigidBody::upcast(colObj);
-		if (body)
+	for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+	{
+		btRigidBody* body = m_nonStaticRigidBodies[i];
+		if (body->isActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
 		{
 			body->setGravity(gravity);
@@ -428,13 +361,28 @@
 }
 
+void	btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
+{
+	btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask);
+}
+
+void	btDiscreteDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
+{
+	btRigidBody* body = btRigidBody::upcast(collisionObject);
+	if (body)
+		removeRigidBody(body);
+	else
+		btCollisionWorld::removeCollisionObject(collisionObject);
+}
 
 void	btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body)
 {
-	removeCollisionObject(body);
-}
+	m_nonStaticRigidBodies.remove(body);
+	btCollisionWorld::removeCollisionObject(body);
+}
+
 
 void	btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body)
 {
-	if (!body->isStaticOrKinematicObject())
+	if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
 	{
 		body->setGravity(m_gravity);
@@ -443,4 +391,12 @@
 	if (body->getCollisionShape())
 	{
+		if (!body->isStaticObject())
+		{
+			m_nonStaticRigidBodies.push_back(body);
+		} else
+		{
+			body->setActivationState(ISLAND_SLEEPING);
+		}
+
 		bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
 		short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
@@ -453,5 +409,5 @@
 void	btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
 {
-	if (!body->isStaticOrKinematicObject())
+	if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
 	{
 		body->setGravity(m_gravity);
@@ -460,4 +416,12 @@
 	if (body->getCollisionShape())
 	{
+		if (!body->isStaticObject())
+		{
+			m_nonStaticRigidBodies.push_back(body);
+		}
+		 else
+		{
+			body->setActivationState(ISLAND_SLEEPING);
+		}
 		addCollisionObject(body,group,mask);
 	}
@@ -480,8 +444,7 @@
 	BT_PROFILE("updateActivationState");
 
-	for ( int i=0;i<m_collisionObjects.size();i++)
-	{
-		btCollisionObject* colObj = m_collisionObjects[i];
-		btRigidBody* body = btRigidBody::upcast(colObj);
+	for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+	{
+		btRigidBody* body = m_nonStaticRigidBodies[i];
 		if (body)
 		{
@@ -586,5 +549,4 @@
 		}
 };
-
 
 
@@ -604,4 +566,9 @@
 		btStackAlloc*			m_stackAlloc;
 		btDispatcher*			m_dispatcher;
+		
+		btAlignedObjectArray<btCollisionObject*> m_bodies;
+		btAlignedObjectArray<btPersistentManifold*> m_manifolds;
+		btAlignedObjectArray<btTypedConstraint*> m_constraints;
+
 
 		InplaceSolverIslandCallback(
@@ -624,4 +591,5 @@
 		}
 
+
 		InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other)
 		{
@@ -664,14 +632,45 @@
 				}
 
-				///only call solveGroup if there is some work: avoid virtual function call, its overhead can be excessive
-				if (numManifolds + numCurConstraints)
-				{
-					m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
-				}
-		
-			}
+				if (m_solverInfo.m_minimumSolverBatchSize<=1)
+				{
+					///only call solveGroup if there is some work: avoid virtual function call, its overhead can be excessive
+					if (numManifolds + numCurConstraints)
+					{
+						m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,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]);
+					if ((m_constraints.size()+m_manifolds.size())>m_solverInfo.m_minimumSolverBatchSize)
+					{
+						processConstraints();
+					} else
+					{
+						//printf("deferred\n");
+					}
+				}
+			}
+		}
+		void	processConstraints()
+		{
+			if (m_manifolds.size() + m_constraints.size()>0)
+			{
+				m_solver->solveGroup( &m_bodies[0],m_bodies.size(), &m_manifolds[0], m_manifolds.size(), &m_constraints[0], m_constraints.size() ,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
+			}
+			m_bodies.resize(0);
+			m_manifolds.resize(0);
+			m_constraints.resize(0);
+
 		}
 
 	};
+
+	
 
 	//sorted version of all btTypedConstraint, based on islandId
@@ -699,4 +698,6 @@
 	m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback);
 
+	solverCallback.processConstraints();
+
 	m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
 }
@@ -741,5 +742,5 @@
 
 
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+
 
 class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
@@ -754,6 +755,6 @@
 	btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : 
 	  btCollisionWorld::ClosestConvexResultCallback(fromA,toA),
+		m_me(me),
 		m_allowedPenetration(0.0f),
-		m_me(me),
 		m_pairCache(pairCache),
 		m_dispatcher(dispatcher)
@@ -829,44 +830,40 @@
 	BT_PROFILE("integrateTransforms");
 	btTransform predictedTrans;
-	for ( int i=0;i<m_collisionObjects.size();i++)
-	{
-		btCollisionObject* colObj = m_collisionObjects[i];
-		btRigidBody* body = btRigidBody::upcast(colObj);
-		if (body)
-		{
-			body->setHitFraction(1.f);
-
-			if (body->isActive() && (!body->isStaticOrKinematicObject()))
-			{
-				body->predictIntegratedTransform(timeStep, predictedTrans);
-				btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
-
-				if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
-				{
-					BT_PROFILE("CCD motion clamping");
-					if (body->getCollisionShape()->isConvex())
-					{
-						gNumClampedCcdMotions++;
-						
-						btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
-						btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
-						btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
-
-						sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
-						sweepResults.m_collisionFilterMask  = body->getBroadphaseProxy()->m_collisionFilterMask;
-
-						convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults);
-						if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
-						{
-							body->setHitFraction(sweepResults.m_closestHitFraction);
-							body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
-							body->setHitFraction(0.f);
+	for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+	{
+		btRigidBody* body = m_nonStaticRigidBodies[i];
+		body->setHitFraction(1.f);
+
+		if (body->isActive() && (!body->isStaticOrKinematicObject()))
+		{
+			body->predictIntegratedTransform(timeStep, predictedTrans);
+			btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
+
+			if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
+			{
+				BT_PROFILE("CCD motion clamping");
+				if (body->getCollisionShape()->isConvex())
+				{
+					gNumClampedCcdMotions++;
+					
+					btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
+					//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+					btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+
+					sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
+					sweepResults.m_collisionFilterMask  = body->getBroadphaseProxy()->m_collisionFilterMask;
+
+					convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults);
+					if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
+					{
+						body->setHitFraction(sweepResults.m_closestHitFraction);
+						body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
+						body->setHitFraction(0.f);
 //							printf("clamped integration to hit fraction = %f\n",fraction);
-						}
 					}
 				}
-				
-				body->proceedToTransform( predictedTrans);
-			}
+			}
+			
+			body->proceedToTransform( predictedTrans);
 		}
 	}
@@ -880,19 +877,14 @@
 {
 	BT_PROFILE("predictUnconstraintMotion");
-	for ( int i=0;i<m_collisionObjects.size();i++)
-	{
-		btCollisionObject* colObj = m_collisionObjects[i];
-		btRigidBody* body = btRigidBody::upcast(colObj);
-		if (body)
-		{
-			if (!body->isStaticOrKinematicObject())
-			{
-				
-				body->integrateVelocities( timeStep);
-				//damping
-				body->applyDamping(timeStep);
-
-				body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
-			}
+	for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+	{
+		btRigidBody* body = m_nonStaticRigidBodies[i];
+		if (!body->isStaticOrKinematicObject())
+		{
+			body->integrateVelocities( timeStep);
+			//damping
+			body->applyDamping(timeStep);
+
+			body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
 		}
 	}
@@ -914,279 +906,4 @@
 
 	
-
-class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback
-{
-	btIDebugDraw*	m_debugDrawer;
-	btVector3	m_color;
-	btTransform	m_worldTrans;
-
-public:
-
-	DebugDrawcallback(btIDebugDraw*	debugDrawer,const btTransform& worldTrans,const btVector3& color) :
-                m_debugDrawer(debugDrawer),
-		m_color(color),
-		m_worldTrans(worldTrans)
-	{
-	}
-
-	virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
-	{
-		processTriangle(triangle,partId,triangleIndex);
-	}
-
-	virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex)
-	{
-		(void)partId;
-		(void)triangleIndex;
-
-		btVector3 wv0,wv1,wv2;
-		wv0 = m_worldTrans*triangle[0];
-		wv1 = m_worldTrans*triangle[1];
-		wv2 = m_worldTrans*triangle[2];
-		m_debugDrawer->drawLine(wv0,wv1,m_color);
-		m_debugDrawer->drawLine(wv1,wv2,m_color);
-		m_debugDrawer->drawLine(wv2,wv0,m_color);
-	}
-};
-
-void btDiscreteDynamicsWorld::debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color)
-{
-	btVector3 start = transform.getOrigin();
-
-	const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0);
-	const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0);
-	const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius);
-
-	// XY 
-	getDebugDrawer()->drawLine(start-xoffs, start+yoffs, color);
-	getDebugDrawer()->drawLine(start+yoffs, start+xoffs, color);
-	getDebugDrawer()->drawLine(start+xoffs, start-yoffs, color);
-	getDebugDrawer()->drawLine(start-yoffs, start-xoffs, color);
-
-	// XZ
-	getDebugDrawer()->drawLine(start-xoffs, start+zoffs, color);
-	getDebugDrawer()->drawLine(start+zoffs, start+xoffs, color);
-	getDebugDrawer()->drawLine(start+xoffs, start-zoffs, color);
-	getDebugDrawer()->drawLine(start-zoffs, start-xoffs, color);
-
-	// YZ
-	getDebugDrawer()->drawLine(start-yoffs, start+zoffs, color);
-	getDebugDrawer()->drawLine(start+zoffs, start+yoffs, color);
-	getDebugDrawer()->drawLine(start+yoffs, start-zoffs, color);
-	getDebugDrawer()->drawLine(start-zoffs, start-yoffs, color);
-}
-
-void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color)
-{
-	// Draw a small simplex at the center of the object
-	{
-		btVector3 start = worldTransform.getOrigin();
-		getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(1,0,0), btVector3(1,0,0));
-		getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,1,0), btVector3(0,1,0));
-		getDebugDrawer()->drawLine(start, start+worldTransform.getBasis() * btVector3(0,0,1), btVector3(0,0,1));
-	}
-
-	if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
-	{
-		const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
-		for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--)
-		{
-			btTransform childTrans = compoundShape->getChildTransform(i);
-			const btCollisionShape* colShape = compoundShape->getChildShape(i);
-			debugDrawObject(worldTransform*childTrans,colShape,color);
-		}
-
-	} else
-	{
-		switch (shape->getShapeType())
-		{
-
-		case SPHERE_SHAPE_PROXYTYPE:
-			{
-				const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
-				btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
-				
-				debugDrawSphere(radius, worldTransform, color);
-				break;
-			}
-		case MULTI_SPHERE_SHAPE_PROXYTYPE:
-			{
-				const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
-
-				for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
-				{
-					btTransform childTransform = worldTransform;
-					childTransform.getOrigin() += multiSphereShape->getSpherePosition(i);
-					debugDrawSphere(multiSphereShape->getSphereRadius(i), childTransform, color);
-				}
-
-				break;
-			}
-		case CAPSULE_SHAPE_PROXYTYPE:
-			{
-				const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
-
-				btScalar radius = capsuleShape->getRadius();
-				btScalar halfHeight = capsuleShape->getHalfHeight();
-				
-				int upAxis = capsuleShape->getUpAxis();
-
-				
-				btVector3 capStart(0.f,0.f,0.f);
-				capStart[upAxis] = -halfHeight;
-
-				btVector3 capEnd(0.f,0.f,0.f);
-				capEnd[upAxis] = halfHeight;
-
-				// Draw the ends
-				{
-					
-					btTransform childTransform = worldTransform;
-					childTransform.getOrigin() = worldTransform * capStart;
-					debugDrawSphere(radius, childTransform, color);
-				}
-
-				{
-					btTransform childTransform = worldTransform;
-					childTransform.getOrigin() = worldTransform * capEnd;
-					debugDrawSphere(radius, childTransform, color);
-				}
-
-				// Draw some additional lines
-				btVector3 start = worldTransform.getOrigin();
-
-				
-				capStart[(upAxis+1)%3] = radius;
-				capEnd[(upAxis+1)%3] = radius;
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
-				capStart[(upAxis+1)%3] = -radius;
-				capEnd[(upAxis+1)%3] = -radius;
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
-
-				capStart[(upAxis+1)%3] = 0.f;
-				capEnd[(upAxis+1)%3] = 0.f;
-
-				capStart[(upAxis+2)%3] = radius;
-				capEnd[(upAxis+2)%3] = radius;
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
-				capStart[(upAxis+2)%3] = -radius;
-				capEnd[(upAxis+2)%3] = -radius;
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * capStart,start+worldTransform.getBasis() * capEnd, color);
-
-				
-				break;
-			}
-		case CONE_SHAPE_PROXYTYPE:
-			{
-				const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
-				btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
-				btScalar height = coneShape->getHeight();//+coneShape->getMargin();
-				btVector3 start = worldTransform.getOrigin();
-
-				int upAxis= coneShape->getConeUpIndex();
-				
-
-				btVector3	offsetHeight(0,0,0);
-				offsetHeight[upAxis] = height * btScalar(0.5);
-				btVector3	offsetRadius(0,0,0);
-				offsetRadius[(upAxis+1)%3] = radius;
-				btVector3	offset2Radius(0,0,0);
-				offset2Radius[(upAxis+2)%3] = radius;
-
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight+offset2Radius),color);
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight),start+worldTransform.getBasis() * (-offsetHeight-offset2Radius),color);
-
-
-
-				break;
-
-			}
-		case CYLINDER_SHAPE_PROXYTYPE:
-			{
-				const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
-				int upAxis = cylinder->getUpAxis();
-				btScalar radius = cylinder->getRadius();
-				btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
-				btVector3 start = worldTransform.getOrigin();
-				btVector3	offsetHeight(0,0,0);
-				offsetHeight[upAxis] = halfHeight;
-				btVector3	offsetRadius(0,0,0);
-				offsetRadius[(upAxis+1)%3] = radius;
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight+offsetRadius),start+worldTransform.getBasis() * (-offsetHeight+offsetRadius),color);
-				getDebugDrawer()->drawLine(start+worldTransform.getBasis() * (offsetHeight-offsetRadius),start+worldTransform.getBasis() * (-offsetHeight-offsetRadius),color);
-				break;
-			}
-
-			case STATIC_PLANE_PROXYTYPE:
-				{
-					const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
-					btScalar planeConst = staticPlaneShape->getPlaneConstant();
-					const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
-					btVector3 planeOrigin = planeNormal * planeConst;
-					btVector3 vec0,vec1;
-					btPlaneSpace1(planeNormal,vec0,vec1);
-					btScalar vecLen = 100.f;
-					btVector3 pt0 = planeOrigin + vec0*vecLen;
-					btVector3 pt1 = planeOrigin - vec0*vecLen;
-					btVector3 pt2 = planeOrigin + vec1*vecLen;
-					btVector3 pt3 = planeOrigin - vec1*vecLen;
-					getDebugDrawer()->drawLine(worldTransform*pt0,worldTransform*pt1,color);
-					getDebugDrawer()->drawLine(worldTransform*pt2,worldTransform*pt3,color);
-					break;
-
-				}
-		default:
-			{
-
-				if (shape->isConcave())
-				{
-					btConcaveShape* concaveMesh = (btConcaveShape*) shape;
-					
-					///@todo pass camera, for some culling? no -> we are not a graphics lib
-					btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
-					btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
-
-					DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
-					concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
-
-				}
-
-				if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
-				{
-					btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
-					//todo: pass camera for some culling			
-					btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
-					btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
-					//DebugDrawcallback drawCallback;
-					DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
-					convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
-				}
-
-
-				/// for polyhedral shapes
-				if (shape->isPolyhedral())
-				{
-					btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
-
-					int i;
-					for (i=0;i<polyshape->getNumEdges();i++)
-					{
-						btVector3 a,b;
-						polyshape->getEdge(i,a,b);
-						btVector3 wa = worldTransform * a;
-						btVector3 wb = worldTransform * b;
-						getDebugDrawer()->drawLine(wa,wb,color);
-
-					}
-
-					
-				}
-			}
-		}
-	}
-}
-
 
 void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint)
@@ -1350,5 +1067,5 @@
 				if(drawLimits)
 				{
-					btTransform tr = pSlider->getCalculatedTransformA();
+					btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB();
 					btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
 					btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
@@ -1367,5 +1084,5 @@
 	}
 	return;
-} // btDiscreteDynamicsWorld::debugDrawConstraint()
+}
 
 
@@ -1403,2 +1120,42 @@
 
 
+
+void	btDiscreteDynamicsWorld::serializeRigidBodies(btSerializer* serializer)
+{
+	int i;
+	//serialize all collision objects
+	for (i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		if (colObj->getInternalType() & btCollisionObject::CO_RIGID_BODY)
+		{
+			int len = colObj->calculateSerializeBufferSize();
+			btChunk* chunk = serializer->allocate(len,1);
+			const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
+			serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj);
+		}
+	}
+
+	for (i=0;i<m_constraints.size();i++)
+	{
+		btTypedConstraint* constraint = m_constraints[i];
+		int size = constraint->calculateSerializeBufferSize();
+		btChunk* chunk = serializer->allocate(size,1);
+		const char* structType = constraint->serialize(chunk->m_oldPtr,serializer);
+		serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint);
+	}
+}
+
+
+void	btDiscreteDynamicsWorld::serialize(btSerializer* serializer)
+{
+
+	serializer->startSerialization();
+
+	serializeRigidBodies(serializer);
+
+	serializeCollisionObjects(serializer);
+
+	serializer->finishSerialization();
+}
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -13,4 +13,5 @@
 3. This notice may not be removed or altered from any source distribution.
 */
+
 
 #ifndef BT_DISCRETE_DYNAMICS_WORLD_H
@@ -42,4 +43,6 @@
 	btAlignedObjectArray<btTypedConstraint*> m_constraints;
 
+	btAlignedObjectArray<btRigidBody*> m_nonStaticRigidBodies;
+
 	btVector3	m_gravity;
 
@@ -50,4 +53,5 @@
 	bool	m_ownsIslandManager;
 	bool	m_ownsConstraintSolver;
+	bool	m_synchronizeAllMotionStates;
 
 	btAlignedObjectArray<btActionInterface*>	m_actions;
@@ -74,6 +78,5 @@
 	virtual void	saveKinematicState(btScalar timeStep);
 
-	void	debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color);
-
+	void	serializeRigidBodies(btSerializer* serializer);
 
 public:
@@ -121,4 +124,6 @@
 	virtual btVector3 getGravity () const;
 
+	virtual void	addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::StaticFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
+
 	virtual void	addRigidBody(btRigidBody* body);
 
@@ -127,5 +132,7 @@
 	virtual void	removeRigidBody(btRigidBody* body);
 
-	void	debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
+	///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject
+	virtual void	removeCollisionObject(btCollisionObject* collisionObject);
+
 
 	void	debugDrawConstraint(btTypedConstraint* constraint);
@@ -175,4 +182,16 @@
 	virtual void	removeCharacter(btActionInterface* character);
 
+	void	setSynchronizeAllMotionStates(bool synchronizeAll)
+	{
+		m_synchronizeAllMotionStates = synchronizeAll;
+	}
+	bool getSynchronizeAllMotionStates() const
+	{
+		return m_synchronizeAllMotionStates;
+	}
+
+	///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo)
+	virtual	void	serialize(btSerializer* serializer);
+
 };
 
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 8284)
@@ -42,4 +42,5 @@
 protected:
 		btInternalTickCallback m_internalTickCallback;
+		btInternalTickCallback m_internalPreTickCallback;
 		void*	m_worldUserInfo;
 
@@ -50,5 +51,5 @@
 
 		btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration)
-		:btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0), m_worldUserInfo(0)
+		:btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0),m_internalPreTickCallback(0), m_worldUserInfo(0)
 		{
 		}
@@ -103,7 +104,13 @@
 
 		/// Set the callback for when an internal tick (simulation substep) happens, optional user info
-		void setInternalTickCallback(btInternalTickCallback cb,	void* worldUserInfo=0) 
+		void setInternalTickCallback(btInternalTickCallback cb,	void* worldUserInfo=0,bool isPreTick=false) 
 		{ 
-			m_internalTickCallback = cb; 
+			if (isPreTick)
+			{
+				m_internalPreTickCallback = cb;
+			} else
+			{
+				m_internalTickCallback = cb; 
+			}
 			m_worldUserInfo = worldUserInfo;
 		}
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp	(revision 8284)
@@ -20,4 +20,5 @@
 #include "LinearMath/btMotionState.h"
 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include "LinearMath/btSerializer.h"
 
 //'temporarily' global variables
@@ -45,5 +46,6 @@
 	m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
 	m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
-	m_angularFactor = btScalar(1.);
+	m_angularFactor.setValue(1,1,1);
+	m_linearFactor.setValue(1,1,1);
 	m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
 	m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
@@ -86,4 +88,15 @@
 	updateInertiaTensor();
 
+	m_rigidbodyFlags = 0;
+
+
+	m_deltaLinearVelocity.setZero();
+	m_deltaAngularVelocity.setZero();
+	m_invMass = m_inverseMass*m_linearFactor;
+	m_pushVelocity.setZero();
+	m_turnVelocity.setZero();
+
+	
+
 }
 
@@ -136,6 +149,6 @@
 void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
 {
-	m_linearDamping = GEN_clamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
-	m_angularDamping = GEN_clamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+	m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+	m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
 }
 
@@ -227,4 +240,7 @@
 		m_inverseMass = btScalar(1.0) / mass;
 	}
+
+	//Fg = m * a
+	m_gravity = mass * m_gravity_acceleration;
 	
 	m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0),
@@ -232,4 +248,5 @@
 				   inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0));
 
+	m_invMass = m_linearFactor*m_inverseMass;
 }
 
@@ -301,4 +318,26 @@
 }
 
+void	btRigidBody::internalWritebackVelocity(btScalar timeStep)
+{
+    (void) timeStep;
+	if (m_inverseMass)
+	{
+		setLinearVelocity(getLinearVelocity()+ m_deltaLinearVelocity);
+		setAngularVelocity(getAngularVelocity()+m_deltaAngularVelocity);
+		
+		//correct the position/orientation based on push/turn recovery
+		btTransform newTransform;
+		btTransformUtil::integrateTransform(getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform);
+		setWorldTransform(newTransform);
+		//m_originalBody->setCompanionId(-1);
+	}
+//	m_deltaLinearVelocity.setZero();
+//	m_deltaAngularVelocity .setZero();
+//	m_pushVelocity.setZero();
+//	m_turnVelocity.setZero();
+}
+
+
+
 void btRigidBody::addConstraintRef(btTypedConstraint* c)
 {
@@ -315,2 +354,50 @@
 	m_checkCollideWith = m_constraintRefs.size() > 0;
 }
+
+int	btRigidBody::calculateSerializeBufferSize()	const
+{
+	int sz = sizeof(btRigidBodyData);
+	return sz;
+}
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+const char*	btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const
+{
+	btRigidBodyData* rbd = (btRigidBodyData*) dataBuffer;
+
+	btCollisionObject::serialize(&rbd->m_collisionObjectData, serializer);
+
+	m_invInertiaTensorWorld.serialize(rbd->m_invInertiaTensorWorld);
+	m_linearVelocity.serialize(rbd->m_linearVelocity);
+	m_angularVelocity.serialize(rbd->m_angularVelocity);
+	rbd->m_inverseMass = m_inverseMass;
+	m_angularFactor.serialize(rbd->m_angularFactor);
+	m_linearFactor.serialize(rbd->m_linearFactor);
+	m_gravity.serialize(rbd->m_gravity);
+	m_gravity_acceleration.serialize(rbd->m_gravity_acceleration);
+	m_invInertiaLocal.serialize(rbd->m_invInertiaLocal);
+	m_totalForce.serialize(rbd->m_totalForce);
+	m_totalTorque.serialize(rbd->m_totalTorque);
+	rbd->m_linearDamping = m_linearDamping;
+	rbd->m_angularDamping = m_angularDamping;
+	rbd->m_additionalDamping = m_additionalDamping;
+	rbd->m_additionalDampingFactor = m_additionalDampingFactor;
+	rbd->m_additionalLinearDampingThresholdSqr = m_additionalLinearDampingThresholdSqr;
+	rbd->m_additionalAngularDampingThresholdSqr = m_additionalAngularDampingThresholdSqr;
+	rbd->m_additionalAngularDampingFactor = m_additionalAngularDampingFactor;
+	rbd->m_linearSleepingThreshold=m_linearSleepingThreshold;
+	rbd->m_angularSleepingThreshold = m_angularSleepingThreshold;
+
+	return btRigidBodyDataName;
+}
+
+
+
+void btRigidBody::serializeSingleObject(class btSerializer* serializer) const
+{
+	btChunk* chunk = serializer->allocate(calculateSerializeBufferSize(),1);
+	const char* structType = serialize(chunk->m_oldPtr, serializer);
+	serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,(void*)this);
+}
+
+
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 8284)
@@ -29,4 +29,18 @@
 extern btScalar gDeactivationTime;
 extern bool gDisableDeactivation;
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btRigidBodyData	btRigidBodyDoubleData
+#define btRigidBodyDataName	"btRigidBodyDoubleData"
+#else
+#define btRigidBodyData	btRigidBodyFloatData
+#define btRigidBodyDataName	"btRigidBodyFloatData"
+#endif //BT_USE_DOUBLE_PRECISION
+
+
+enum	btRigidBodyFlags
+{
+	BT_DISABLE_WORLD_GRAVITY = 1
+};
 
 
@@ -46,5 +60,5 @@
 	btVector3		m_angularVelocity;
 	btScalar		m_inverseMass;
-	btScalar		m_angularFactor;
+	btVector3		m_linearFactor;
 
 	btVector3		m_gravity;	
@@ -72,4 +86,19 @@
 	//keep track of typed constraints referencing this rigid body
 	btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
+
+	int				m_rigidbodyFlags;
+	
+	int				m_debugBodyId;
+
+
+protected:
+
+	ATTRIBUTE_ALIGNED64(btVector3		m_deltaLinearVelocity);
+	btVector3		m_deltaAngularVelocity;
+	btVector3		m_angularFactor;
+	btVector3		m_invMass;
+	btVector3		m_pushVelocity;
+	btVector3		m_turnVelocity;
+
 
 public:
@@ -111,5 +140,4 @@
 		btScalar			m_additionalAngularDampingFactor;
 
-		
 		btRigidBodyConstructionInfo(	btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)):
 		m_mass(mass),
@@ -161,5 +189,5 @@
 	static const btRigidBody*	upcast(const btCollisionObject* colObj)
 	{
-		if (colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
+		if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
 			return (const btRigidBody*)colObj;
 		return 0;
@@ -167,5 +195,5 @@
 	static btRigidBody*	upcast(btCollisionObject* colObj)
 	{
-		if (colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
+		if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
 			return (btRigidBody*)colObj;
 		return 0;
@@ -220,4 +248,13 @@
 	void			setMassProps(btScalar mass, const btVector3& inertia);
 	
+	const btVector3& getLinearFactor() const
+	{
+		return m_linearFactor;
+	}
+	void setLinearFactor(const btVector3& linearFactor)
+	{
+		m_linearFactor = linearFactor;
+		m_invMass = m_linearFactor*m_inverseMass;
+	}
 	btScalar		getInvMass() const { return m_inverseMass; }
 	const btMatrix3x3& getInvInertiaTensorWorld() const { 
@@ -231,5 +268,5 @@
 	void			applyCentralForce(const btVector3& force)
 	{
-		m_totalForce += force;
+		m_totalForce += force*m_linearFactor;
 	}
 
@@ -262,5 +299,5 @@
 	void	applyTorque(const btVector3& torque)
 	{
-		m_totalTorque += torque;
+		m_totalTorque += torque*m_angularFactor;
 	}
 	
@@ -268,15 +305,15 @@
 	{
 		applyCentralForce(force);
-		applyTorque(rel_pos.cross(force)*m_angularFactor);
+		applyTorque(rel_pos.cross(force*m_linearFactor));
 	}
 	
 	void applyCentralImpulse(const btVector3& impulse)
 	{
-		m_linearVelocity += impulse * m_inverseMass;
+		m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
 	}
 	
   	void applyTorqueImpulse(const btVector3& torque)
 	{
-			m_angularVelocity += m_invInertiaTensorWorld * torque;
+			m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
 	}
 	
@@ -288,22 +325,9 @@
 			if (m_angularFactor)
 			{
-				applyTorqueImpulse(rel_pos.cross(impulse)*m_angularFactor);
+				applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor));
 			}
 		}
 	}
 
-	//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
-	SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
-	{
-		if (m_inverseMass != btScalar(0.))
-		{
-			m_linearVelocity += linearComponent*impulseMagnitude;
-			if (m_angularFactor)
-			{
-				m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor;
-			}
-		}
-	}
-	
 	void clearForces() 
 	{
@@ -451,9 +475,14 @@
 	int	m_frictionSolverType;
 
+	void	setAngularFactor(const btVector3& angFac)
+	{
+		m_angularFactor = angFac;
+	}
+
 	void	setAngularFactor(btScalar angFac)
 	{
-		m_angularFactor = angFac;
-	}
-	btScalar	getAngularFactor() const
+		m_angularFactor.setValue(angFac,angFac,angFac);
+	}
+	const btVector3&	getAngularFactor() const
 	{
 		return m_angularFactor;
@@ -481,7 +510,179 @@
 	}
 
-	int	m_debugBodyId;
+	void	setFlags(int flags)
+	{
+		m_rigidbodyFlags = flags;
+	}
+
+	int getFlags() const
+	{
+		return m_rigidbodyFlags;
+	}
+
+	const btVector3& getDeltaLinearVelocity() const
+	{
+		return m_deltaLinearVelocity;
+	}
+
+	const btVector3& getDeltaAngularVelocity() const
+	{
+		return m_deltaAngularVelocity;
+	}
+
+	const btVector3& getPushVelocity() const 
+	{
+		return m_pushVelocity;
+	}
+
+	const btVector3& getTurnVelocity() const 
+	{
+		return m_turnVelocity;
+	}
+
+
+	////////////////////////////////////////////////
+	///some internal methods, don't use them
+		
+	btVector3& internalGetDeltaLinearVelocity()
+	{
+		return m_deltaLinearVelocity;
+	}
+
+	btVector3& internalGetDeltaAngularVelocity()
+	{
+		return m_deltaAngularVelocity;
+	}
+
+	const btVector3& internalGetAngularFactor() const
+	{
+		return m_angularFactor;
+	}
+
+	const btVector3& internalGetInvMass() const
+	{
+		return m_invMass;
+	}
+	
+	btVector3& internalGetPushVelocity()
+	{
+		return m_pushVelocity;
+	}
+
+	btVector3& internalGetTurnVelocity()
+	{
+		return m_turnVelocity;
+	}
+
+	SIMD_FORCE_INLINE void	internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
+	{
+		velocity = getLinearVelocity()+m_deltaLinearVelocity + (getAngularVelocity()+m_deltaAngularVelocity).cross(rel_pos);
+	}
+
+	SIMD_FORCE_INLINE void	internalGetAngularVelocity(btVector3& angVel) const
+	{
+		angVel = getAngularVelocity()+m_deltaAngularVelocity;
+	}
+
+
+	//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
+	SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
+	{
+		if (m_inverseMass)
+		{
+			m_deltaLinearVelocity += linearComponent*impulseMagnitude;
+			m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
+		}
+	}
+
+	SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
+	{
+		if (m_inverseMass)
+		{
+			m_pushVelocity += linearComponent*impulseMagnitude;
+			m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
+		}
+	}
+	
+	void	internalWritebackVelocity()
+	{
+		if (m_inverseMass)
+		{
+			setLinearVelocity(getLinearVelocity()+ m_deltaLinearVelocity);
+			setAngularVelocity(getAngularVelocity()+m_deltaAngularVelocity);
+			//m_deltaLinearVelocity.setZero();
+			//m_deltaAngularVelocity .setZero();
+			//m_originalBody->setCompanionId(-1);
+		}
+	}
+
+
+	void	internalWritebackVelocity(btScalar timeStep);
+	
+
+	///////////////////////////////////////////////
+
+	virtual	int	calculateSerializeBufferSize()	const;
+
+	///fills the dataBuffer and returns the struct name (and 0 on failure)
+	virtual	const char*	serialize(void* dataBuffer,  class btSerializer* serializer) const;
+
+	virtual void serializeSingleObject(class btSerializer* serializer) const;
+
 };
 
+//@todo add m_optionalMotionState and m_constraintRefs to btRigidBodyData
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btRigidBodyFloatData
+{
+	btCollisionObjectFloatData	m_collisionObjectData;
+	btMatrix3x3FloatData		m_invInertiaTensorWorld;
+	btVector3FloatData		m_linearVelocity;
+	btVector3FloatData		m_angularVelocity;
+	btVector3FloatData		m_angularFactor;
+	btVector3FloatData		m_linearFactor;
+	btVector3FloatData		m_gravity;	
+	btVector3FloatData		m_gravity_acceleration;
+	btVector3FloatData		m_invInertiaLocal;
+	btVector3FloatData		m_totalForce;
+	btVector3FloatData		m_totalTorque;
+	float					m_inverseMass;
+	float					m_linearDamping;
+	float					m_angularDamping;
+	float					m_additionalDampingFactor;
+	float					m_additionalLinearDampingThresholdSqr;
+	float					m_additionalAngularDampingThresholdSqr;
+	float					m_additionalAngularDampingFactor;
+	float					m_linearSleepingThreshold;
+	float					m_angularSleepingThreshold;
+	int						m_additionalDamping;
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct	btRigidBodyDoubleData
+{
+	btCollisionObjectDoubleData	m_collisionObjectData;
+	btMatrix3x3DoubleData		m_invInertiaTensorWorld;
+	btVector3DoubleData		m_linearVelocity;
+	btVector3DoubleData		m_angularVelocity;
+	btVector3DoubleData		m_angularFactor;
+	btVector3DoubleData		m_linearFactor;
+	btVector3DoubleData		m_gravity;	
+	btVector3DoubleData		m_gravity_acceleration;
+	btVector3DoubleData		m_invInertiaLocal;
+	btVector3DoubleData		m_totalForce;
+	btVector3DoubleData		m_totalTorque;
+	double					m_inverseMass;
+	double					m_linearDamping;
+	double					m_angularDamping;
+	double					m_additionalDampingFactor;
+	double					m_additionalLinearDampingThresholdSqr;
+	double					m_additionalAngularDampingThresholdSqr;
+	double					m_additionalAngularDampingFactor;
+	double					m_linearSleepingThreshold;
+	double					m_angularSleepingThreshold;
+	int						m_additionalDamping;
+	char	m_padding[4];
+};
+
 
 
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp	(revision 8284)
@@ -133,6 +133,16 @@
 void	btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body)
 {
-	removeCollisionObject(body);
-}
+	btCollisionWorld::removeCollisionObject(body);
+}
+
+void	btSimpleDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject)
+{
+	btRigidBody* body = btRigidBody::upcast(collisionObject);
+	if (body)
+		removeRigidBody(body);
+	else
+		btCollisionWorld::removeCollisionObject(collisionObject);
+}
+
 
 void	btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h	(revision 8284)
@@ -58,4 +58,7 @@
 
 	virtual void	removeRigidBody(btRigidBody* body);
+
+	///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject
+	virtual void	removeCollisionObject(btCollisionObject* collisionObject);
 	
 	virtual void	updateAabbs();
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp	(revision 8284)
@@ -23,5 +23,10 @@
 #include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
 
-static btRigidBody s_fixedObject( 0,0,0);
+btRigidBody& btActionInterface::getFixedBody()
+{
+	static btRigidBody s_fixed(0, 0,0);
+	s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
+	return s_fixed;
+}
 
 btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis,	btVehicleRaycaster* raycaster )
@@ -71,4 +76,5 @@
 	ci.m_bIsFrontWheel = isFrontWheel;
 	ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm;
+	ci.m_maxSuspensionForce = tuning.m_maxSuspensionForce;
 
 	m_wheelInfo.push_back( btWheelInfo(ci));
@@ -187,5 +193,5 @@
 		wheel.m_raycastInfo.m_isInContact = true;
 		
-		wheel.m_raycastInfo.m_groundObject = &s_fixedObject;///@todo for driving on dynamic/movable objects!;
+		wheel.m_raycastInfo.m_groundObject = &getFixedBody();///@todo for driving on dynamic/movable objects!;
 		//wheel.m_raycastInfo.m_groundObject = object;
 
@@ -302,8 +308,7 @@
 		btScalar suspensionForce = wheel.m_wheelsSuspensionForce;
 		
-		btScalar gMaxSuspensionForce = btScalar(6000.);
-		if (suspensionForce > gMaxSuspensionForce)
-		{
-			suspensionForce = gMaxSuspensionForce;
+		if (suspensionForce > wheel.m_maxSuspensionForce)
+		{
+			suspensionForce = wheel.m_maxSuspensionForce;
 		}
 		btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step;
@@ -690,5 +695,5 @@
 					btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
 
-					rel_pos[m_indexForwardAxis] *= wheelInfo.m_rollInfluence;
+					rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
 					m_chassisBody->applyImpulse(sideImp,rel_pos);
 
@@ -709,11 +714,11 @@
 	for (int v=0;v<this->getNumWheels();v++)
 	{
-		btVector3 wheelColor(0,255,255);
+		btVector3 wheelColor(0,1,1);
 		if (getWheelInfo(v).m_raycastInfo.m_isInContact)
 		{
-			wheelColor.setValue(0,0,255);
+			wheelColor.setValue(0,0,1);
 		} else
 		{
-			wheelColor.setValue(255,0,255);
+			wheelColor.setValue(1,0,1);
 		}
 
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.h	(revision 8284)
@@ -30,4 +30,8 @@
 		btAlignedObjectArray<btScalar>	m_forwardImpulse;
 		btAlignedObjectArray<btScalar>	m_sideImpulse;
+	
+		///backwards compatibility
+		int	m_userConstraintType;
+		int	m_userConstraintId;
 
 public:
@@ -41,5 +45,6 @@
 				m_suspensionDamping(btScalar(0.88)),
 				m_maxSuspensionTravelCm(btScalar(500.)),
-				m_frictionSlip(btScalar(10.5))
+				m_frictionSlip(btScalar(10.5)),
+				m_maxSuspensionForce(btScalar(6000.))
 			{
 			}
@@ -49,4 +54,5 @@
 			btScalar	m_maxSuspensionTravelCm;
 			btScalar	m_frictionSlip;
+			btScalar	m_maxSuspensionForce;
 
 		};
@@ -79,4 +85,5 @@
 	virtual void updateAction( btCollisionWorld* collisionWorld, btScalar step)
 	{
+        (void) collisionWorld;
 		updateVehicle(step);
 	}
@@ -189,4 +196,24 @@
 
 
+	///backwards compatibility
+	int getUserConstraintType() const
+	{
+		return m_userConstraintType ;
+	}
+
+	void	setUserConstraintType(int userConstraintType)
+	{
+		m_userConstraintType = userConstraintType;
+	};
+
+	void	setUserConstraintId(int uid)
+	{
+		m_userConstraintId = uid;
+	}
+
+	int getUserConstraintId() const
+	{
+		return m_userConstraintId;
+	}
 
 };
Index: /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.h	(revision 8284)
@@ -30,4 +30,5 @@
 	btScalar		m_wheelsDampingRelaxation;
 	btScalar		m_frictionSlip;
+	btScalar		m_maxSuspensionForce;
 	bool m_bIsFrontWheel;
 	
@@ -69,4 +70,5 @@
 	btScalar	m_deltaRotation;
 	btScalar	m_rollInfluence;
+	btScalar	m_maxSuspensionForce;
 
 	btScalar	m_engineForce;
@@ -100,4 +102,5 @@
 		m_rollInfluence = btScalar(0.1);
 		m_bIsFrontWheel = ci.m_bIsFrontWheel;
+		m_maxSuspensionForce = ci.m_maxSuspensionForce;
 
 	}
Index: /code/branches/kicklib2/src/external/bullet/BulletLicense.txt
===================================================================
--- /code/branches/kicklib2/src/external/bullet/BulletLicense.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/BulletLicense.txt	(revision 8284)
@@ -1,4 +1,4 @@
 /*
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2010 Erwin Coumans  http://continuousphysics.com/Bullet/
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -14,4 +14,5 @@
 
 
-Free for commercial use, but please mail bullet@erwincoumans.com to report projects, and join the forum at
-www.continuousphysics.com/Bullet/phpBB2
+Free for commercial use, please report projects in the forum at http://www.bulletphysics.org
+
+In case you want to display a Bullet logo in your software: you can download the Bullet logo in various vector formats and high resolution at the download section in http://bullet.googlecode.com
Index: /code/branches/kicklib2/src/external/bullet/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/src/external/bullet/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/CMakeLists.txt	(revision 8284)
@@ -31,5 +31,5 @@
   NO_DLL_INTERFACE
   VERSION
-    2.74
+    2.77
   SOURCE_FILES
     ${BULLET_FILES}
Index: /code/branches/kicklib2/src/external/bullet/ChangeLog
===================================================================
--- /code/branches/kicklib2/src/external/bullet/ChangeLog	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/ChangeLog	(revision 8284)
@@ -2,6 +2,67 @@
 Primary author and maintainer: Erwin Coumans
 
-Todo: update changelog from April - July 2008
-See http://code.google.com/p/bullet/source/list for more complete log in Subversion
+This ChangeLog is incomplete, for an up-to-date list of all fixed issues see http://bullet.googlecode.com
+using http://tinyurl.com/yabmjjj
+
+
+2010 September 21
+	- Bullet 2.77 release based on revision 2218
+	- Added Visual Studio project files for OpenCL and Direct Compute in msvc folder
+	
+2010 September 7
+	- autotools now uses CamelCase naming for libraryes just like cmake:
+	libbulletdynamics -> libBulletDynamics, libbulletmath -> libLinearMath
+
+2010 July 21
+	- Preparing for Bullet 2.77 release, around revision r2135
+	- Added an OpenCL particle demo, running on NVidia, AMD and MiniCL
+	Thanks to NVidia for the original particle demo from their OpenCL SDK
+	- Added GPU deformable object solvers for OpenCL and DirectCompute, and a DirectX 11 cloth demo
+	Thanks to AMD
+	- Create a separate library for MiniCL, 
+	MiniCL is a rudimentary OpenCL wrapper that allows to compile OpenCL kernels for multi-core CPU, using Win32 Threads or Posix
+	- Moved vectormath into Bullet/src, and added a SSE implementation
+	- Added a btParallelConstraintSolver, mainly for PlayStation 3 Cell SPUs (although it runs fine on CPU too)
+
+2010 March 6
+	- Dynamica Maya plugin (and COLLADA support) is moved to http://dynamica.googlecode.com
+
+2010 February
+	- Bullet 2.76 release, revision 2010
+	- support for the .bullet binary file format
+	- btInternalEdgeUtility to adjust unwanted collisions against internal triangle edges
+	- Improved Maya Dynamica plugin with better constraint authoring and .bullet file export
+
+
+2009 September 17
+	- Minor update to Bullet 2.75 release, revision 1776
+	- Support for btConvex2dShape, check out Bullet/Demos/Box2dDemo
+	- Fixes in build systems
+	- Minor fix in btGjkPairDetector
+	- Initialize world transform for btCollisionShape in constructor
+
+
+2009 September 6
+	- Bullet 2.75 release
+	- Added SPH fluid simulation in Extras, not integrated with rigid body / soft body yet
+	Thanks to Rama Hoetzlein to make this contribution available under the ZLib license
+	- add special capsule-capsule collider code in btConvexConvexCollisionAlgorithm, to speed up capsule-ragdolls
+	- soft body improvement: faster building of bending constraints
+	- soft body improvement: allow to disable/enable cluster self-collision
+	- soft body fix: 'exploding' soft bodies when using cluster collision
+	- fix some degenerate cases in continuous convex cast, could impact ray cast/convex cast
+	Thanks to Jacob Langford for the report and reproduction cases, see http://code.google.com/p/bullet/issues/detail?id=250&can=1&start=200
+	- re-enabled split impulse
+	- added btHinge2Constraint, btUniversalConstraint, btGeneric6DofSpringConstraint
+	- demonstrate 2D physics with 2D/3D object interaction
+	
+
+2008 December 2
+	- Fix contact refresh issues with btCompoundShape, introduced with btDbvt acceleration structure in btCompoundCollisionAlgorithm
+	- Made btSequentialImpulseConstraintSolver 100% compatible with ODE quickstep
+	constraints can use 'solveConstraint' method or 'getInfo/getInfo2'
+
+2008 November 30
+	- Add highly optimized SIMD branchless PGS/SI solver innerloop 
 
 2008 November 12
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/CMakeLists.txt	(revision 8284)
@@ -2,32 +2,34 @@
 
 COMPILATION_BEGIN BulletLinearMathCompilation.cpp
-		btConvexHull.cpp
-		btQuickprof.cpp
-		btGeometryUtil.cpp
-		btAlignedAllocator.cpp
+	btAlignedAllocator.cpp
+	btConvexHull.cpp
+	btGeometryUtil.cpp
+	btQuickprof.cpp
+	btSerializer.cpp
 COMPILATION_END
 
-		# Headers
-		btAlignedObjectArray.h
-		btList.h
-		btPoolAllocator.h
-		btRandom.h
-		btVector3.h
-		btDefaultMotionState.h
-		btMatrix3x3.h
-		btQuadWord.h
-		btHashMap.h
-		btScalar.h
-		btAabbUtil2.h
-		btConvexHull.h
-		btMinMax.h
-		btQuaternion.h
-		btStackAlloc.h
-		btGeometryUtil.h
-		btMotionState.h
-		btTransform.h
-		btAlignedAllocator.h
-		btIDebugDraw.h
-		btQuickprof.h
-		btTransformUtil.h
+	# Headers
+	btAabbUtil2.h
+	btAlignedAllocator.h
+	btAlignedObjectArray.h
+	btConvexHull.h
+	btDefaultMotionState.h
+	btGeometryUtil.h
+	btHashMap.h
+	btIDebugDraw.h
+	btList.h
+	btMatrix3x3.h
+	btMinMax.h
+	btMotionState.h
+	btPoolAllocator.h
+	btQuadWord.h
+	btQuaternion.h
+	btQuickprof.h
+	btRandom.h
+	btScalar.h
+	btSerializer.h
+	btStackAlloc.h
+	btTransform.h
+	btTransformUtil.h
+	btVector3.h
 )
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btAlignedAllocator.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btAlignedAllocator.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btAlignedAllocator.cpp	(revision 8284)
@@ -161,20 +161,6 @@
 {
 	gNumAlignedAllocs++;
-  void* ptr;
-#if defined (BT_HAS_ALIGNED_ALLOCATOR) || defined(__CELLOS_LV2__)
+	void* ptr;
 	ptr = sAlignedAllocFunc(size, alignment);
-#else
-  char *real;
-  unsigned long offset;
-
-  real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
-  if (real) {
-    offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1);
-    ptr = (void *)((real + sizeof(void *)) + offset);
-    *((void **)(ptr)-1) = (void *)(real);
-  } else {
-    ptr = (void *)(real);
-  }
-#endif  // defined (BT_HAS_ALIGNED_ALLOCATOR) || defined(__CELLOS_LV2__)
 //	printf("btAlignedAllocInternal %d, %x\n",size,ptr);
 	return ptr;
@@ -190,14 +176,5 @@
 	gNumAlignedFree++;
 //	printf("btAlignedFreeInternal %x\n",ptr);
-#if defined (BT_HAS_ALIGNED_ALLOCATOR) || defined(__CELLOS_LV2__)
 	sAlignedFreeFunc(ptr);
-#else
-  void* real;
-
-  if (ptr) {
-    real = *((void **)(ptr)-1);
-    sFreeFunc(real);
-  }
-#endif  // defined (BT_HAS_ALIGNED_ALLOCATOR) || defined(__CELLOS_LV2__)
 }
 
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btAlignedObjectArray.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btAlignedObjectArray.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btAlignedObjectArray.h	(revision 8284)
@@ -139,4 +139,14 @@
 		}
 		
+		SIMD_FORCE_INLINE const T& at(int n) const
+		{
+			return m_data[n];
+		}
+
+		SIMD_FORCE_INLINE T& at(int n)
+		{
+			return m_data[n];
+		}
+
 		SIMD_FORCE_INLINE const T& operator[](int n) const
 		{
@@ -172,7 +182,7 @@
 			int curSize = size();
 
-			if (newsize < size())
-			{
-				for(int i = curSize; i < newsize; i++)
+			if (newsize < curSize)
+			{
+				for(int i = newsize; i < curSize; i++)
 				{
 					m_data[i].~T();
@@ -196,4 +206,16 @@
 		}
 	
+		SIMD_FORCE_INLINE	T&  expandNonInitializing( )
+		{	
+			int sz = size();
+			if( sz == capacity() )
+			{
+				reserve( allocSize(size()) );
+			}
+			m_size++;
+
+			return m_data[sz];		
+		}
+
 
 		SIMD_FORCE_INLINE	T&  expand( const T& fillValue=T())
@@ -438,4 +460,11 @@
 	}
 
+	void copyFromArray(const btAlignedObjectArray& otherArray)
+	{
+		int otherSize = otherArray.size();
+		resize (otherSize);
+		otherArray.copy(0, otherSize, m_data);
+	}
+
 };
 
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btConvexHull.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btConvexHull.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btConvexHull.cpp	(revision 8284)
@@ -17,7 +17,7 @@
 
 #include "btConvexHull.h"
-#include "LinearMath/btAlignedObjectArray.h"
-#include "LinearMath/btMinMax.h"
-#include "LinearMath/btVector3.h"
+#include "btAlignedObjectArray.h"
+#include "btMinMax.h"
+#include "btVector3.h"
 
 
@@ -97,6 +97,6 @@
 				static btVector3 dif;
 		dif = p1-p0;
-				btScalar dn= dot(plane.normal,dif);
-				btScalar t = -(plane.dist+dot(plane.normal,p0) )/dn;
+				btScalar dn= btDot(plane.normal,dif);
+				btScalar t = -(plane.dist+btDot(plane.normal,p0) )/dn;
 				return p0 + (dif*t);
 }
@@ -104,5 +104,5 @@
 btVector3 PlaneProject(const btPlane &plane, const btVector3 &point)
 {
-	return point - plane.normal * (dot(point,plane.normal)+plane.dist);
+	return point - plane.normal * (btDot(point,plane.normal)+plane.dist);
 }
 
@@ -111,5 +111,5 @@
 	// return the normal of the triangle
 	// inscribed by v0, v1, and v2
-	btVector3 cp=cross(v1-v0,v2-v1);
+	btVector3 cp=btCross(v1-v0,v2-v1);
 	btScalar m=cp.length();
 	if(m==0) return btVector3(1,0,0);
@@ -121,14 +121,14 @@
 {
 	static btVector3 cp;
-	cp = cross(udir,vdir).normalized();
-
-	btScalar distu = -dot(cp,ustart);
-	btScalar distv = -dot(cp,vstart);
+	cp = btCross(udir,vdir).normalized();
+
+	btScalar distu = -btDot(cp,ustart);
+	btScalar distv = -btDot(cp,vstart);
 	btScalar dist = (btScalar)fabs(distu-distv);
 	if(upoint) 
 		{
 		btPlane plane;
-		plane.normal = cross(vdir,cp).normalized();
-		plane.dist = -dot(plane.normal,vstart);
+		plane.normal = btCross(vdir,cp).normalized();
+		plane.dist = -btDot(plane.normal,vstart);
 		*upoint = PlaneLineIntersection(plane,ustart,ustart+udir);
 	}
@@ -136,6 +136,6 @@
 		{
 		btPlane plane;
-		plane.normal = cross(udir,cp).normalized();
-		plane.dist = -dot(plane.normal,ustart);
+		plane.normal = btCross(udir,cp).normalized();
+		plane.dist = -btDot(plane.normal,ustart);
 		*vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir);
 	}
@@ -171,5 +171,5 @@
 int PlaneTest(const btPlane &p, const btVector3 &v);
 int PlaneTest(const btPlane &p, const btVector3 &v) {
-	btScalar a  = dot(v,p.normal)+p.dist;
+	btScalar a  = btDot(v,p.normal)+p.dist;
 	int   flag = (a>planetestepsilon)?OVER:((a<-planetestepsilon)?UNDER:COPLANAR);
 	return flag;
@@ -229,5 +229,5 @@
 		if(allow[i])
 		{
-			if(m==-1 || dot(p[i],dir)>dot(p[m],dir))
+			if(m==-1 || btDot(p[i],dir)>btDot(p[m],dir))
 				m=i;
 		}
@@ -239,6 +239,6 @@
 btVector3 orth(const btVector3 &v)
 {
-	btVector3 a=cross(v,btVector3(0,0,1));
-	btVector3 b=cross(v,btVector3(0,1,0));
+	btVector3 a=btCross(v,btVector3(0,0,1));
+	btVector3 b=btCross(v,btVector3(0,1,0));
 	if (a.length() > b.length())
 	{
@@ -259,5 +259,5 @@
 		if(allow[m]==3) return m;
 		T u = orth(dir);
-		T v = cross(u,dir);
+		T v = btCross(u,dir);
 		int ma=-1;
 		for(btScalar x = btScalar(0.0) ; x<= btScalar(360.0) ; x+= btScalar(45.0))
@@ -314,5 +314,5 @@
 {
 	btVector3 n=TriNormal(vertices[t[0]],vertices[t[1]],vertices[t[2]]);
-	return (dot(n,p-vertices[t[0]]) > epsilon); // EPSILON???
+	return (btDot(n,p-vertices[t[0]]) > epsilon); // EPSILON???
 }
 int hasedge(const int3 &t, int a,int b);
@@ -496,6 +496,6 @@
 	if(p0==p1 || basis[0]==btVector3(0,0,0)) 
 		return int4(-1,-1,-1,-1);
-	basis[1] = cross(btVector3(     btScalar(1),btScalar(0.02), btScalar(0)),basis[0]);
-	basis[2] = cross(btVector3(btScalar(-0.02),     btScalar(1), btScalar(0)),basis[0]);
+	basis[1] = btCross(btVector3(     btScalar(1),btScalar(0.02), btScalar(0)),basis[0]);
+	basis[2] = btCross(btVector3(btScalar(-0.02),     btScalar(1), btScalar(0)),basis[0]);
 	if (basis[1].length() > basis[2].length())
 	{
@@ -513,5 +513,5 @@
 		return int4(-1,-1,-1,-1);
 	basis[1] = verts[p2] - verts[p0];
-	basis[2] = cross(basis[1],basis[0]).normalized();
+	basis[2] = btCross(basis[1],basis[0]).normalized();
 	int p3 = maxdirsterid(verts,verts_count,basis[2],allow);
 	if(p3==p0||p3==p1||p3==p2) p3 = maxdirsterid(verts,verts_count,-basis[2],allow);
@@ -519,5 +519,5 @@
 		return int4(-1,-1,-1,-1);
 	btAssert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3));
-	if(dot(verts[p3]-verts[p0],cross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {Swap(p2,p3);}
+	if(btDot(verts[p3]-verts[p0],btCross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {Swap(p2,p3);}
 	return int4(p0,p1,p2,p3);
 }
@@ -565,5 +565,5 @@
 		btVector3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]);
 		t->vmax = maxdirsterid(verts,verts_count,n,allow);
-		t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]);
+		t->rise = btDot(n,verts[t->vmax]-verts[(*t)[0]]);
 	}
 	btHullTriangle *te;
@@ -593,5 +593,5 @@
 			if(!hasvert(*m_tris[j],v)) break;
 			int3 nt=*m_tris[j];
-			if(above(verts,nt,center,btScalar(0.01)*epsilon)  || cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]).length()< epsilon*epsilon*btScalar(0.1) )
+			if(above(verts,nt,center,btScalar(0.01)*epsilon)  || btCross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]).length()< epsilon*epsilon*btScalar(0.1) )
 			{
 				btHullTriangle *nb = m_tris[m_tris[j]->n[0]];
@@ -615,5 +615,5 @@
 			else
 			{
-				t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]);
+				t->rise = btDot(n,verts[t->vmax]-verts[(*t)[0]]);
 			}
 		}
@@ -877,5 +877,5 @@
 	vcount = 0;
 
-	btScalar recip[3];
+	btScalar recip[3]={0.f,0.f,0.f};
 
 	if ( scale )
@@ -1012,7 +1012,7 @@
 				btScalar z = v[2];
 
-				btScalar dx = fabsf(x - px );
-				btScalar dy = fabsf(y - py );
-				btScalar dz = fabsf(z - pz );
+				btScalar dx = btFabs(x - px );
+				btScalar dy = btFabs(y - py );
+				btScalar dz = btFabs(z - pz );
 
 				if ( dx < normalepsilon && dy < normalepsilon && dz < normalepsilon )
@@ -1136,5 +1136,5 @@
 	ocount = 0;
 
-	for (i=0; i<indexcount; i++)
+	for (i=0; i<int (indexcount); i++)
 	{
 		unsigned int v = indices[i]; // original array index
@@ -1157,5 +1157,5 @@
 			for (int k=0;k<m_vertexIndexMapping.size();k++)
 			{
-				if (tmpIndices[k]==v)
+				if (tmpIndices[k]==int(v))
 					m_vertexIndexMapping[k]=ocount;
 			}
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btConvexHull.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btConvexHull.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btConvexHull.h	(revision 8284)
@@ -20,6 +20,6 @@
 #define CD_HULL_H
 
-#include "LinearMath/btVector3.h"
-#include "LinearMath/btAlignedObjectArray.h"
+#include "btVector3.h"
+#include "btAlignedObjectArray.h"
 
 typedef btAlignedObjectArray<unsigned int> TUIntArray;
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btDefaultMotionState.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btDefaultMotionState.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btDefaultMotionState.h	(revision 8284)
@@ -1,4 +1,6 @@
 #ifndef DEFAULT_MOTION_STATE_H
 #define DEFAULT_MOTION_STATE_H
+
+#include "btMotionState.h"
 
 ///The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets.
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btHashMap.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btHashMap.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btHashMap.h	(revision 8284)
@@ -4,5 +4,168 @@
 #include "btAlignedObjectArray.h"
 
+///very basic hashable string implementation, compatible with btHashMap
+struct btHashString
+{
+	const char* m_string;
+	unsigned int	m_hash;
+
+	SIMD_FORCE_INLINE	unsigned int getHash()const
+	{
+		return m_hash;
+	}
+
+	btHashString(const char* name)
+		:m_string(name)
+	{
+		/* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */
+		static const unsigned int  InitialFNV = 2166136261u;
+		static const unsigned int FNVMultiple = 16777619u;
+
+		/* Fowler / Noll / Vo (FNV) Hash */
+		unsigned int hash = InitialFNV;
+		
+		for(int i = 0; m_string[i]; i++)
+		{
+			hash = hash ^ (m_string[i]);       /* xor  the low 8 bits */
+			hash = hash * FNVMultiple;  /* multiply by the magic number */
+		}
+		m_hash = hash;
+	}
+
+	int portableStringCompare(const char* src,	const char* dst) const
+	{
+			int ret = 0 ;
+
+			while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
+					++src, ++dst;
+
+			if ( ret < 0 )
+					ret = -1 ;
+			else if ( ret > 0 )
+					ret = 1 ;
+
+			return( ret );
+	}
+
+	bool equals(const btHashString& other) const
+	{
+		return (m_string == other.m_string) ||
+			(0==portableStringCompare(m_string,other.m_string));
+
+	}
+
+};
+
 const int BT_HASH_NULL=0xffffffff;
+
+
+class btHashInt
+{
+	int	m_uid;
+public:
+	btHashInt(int uid)	:m_uid(uid)
+	{
+	}
+
+	int	getUid1() const
+	{
+		return m_uid;
+	}
+
+	void	setUid1(int uid)
+	{
+		m_uid = uid;
+	}
+
+	bool equals(const btHashInt& other) const
+	{
+		return getUid1() == other.getUid1();
+	}
+	//to our success
+	SIMD_FORCE_INLINE	unsigned int getHash()const
+	{
+		int key = m_uid;
+		// Thomas Wang's hash
+		key += ~(key << 15);	key ^=  (key >> 10);	key +=  (key << 3);	key ^=  (key >> 6);	key += ~(key << 11);	key ^=  (key >> 16);
+		return key;
+	}
+};
+
+
+
+class btHashPtr
+{
+
+	union
+	{
+		const void*	m_pointer;
+		int	m_hashValues[2];
+	};
+
+public:
+
+	btHashPtr(const void* ptr)
+		:m_pointer(ptr)
+	{
+	}
+
+	const void*	getPointer() const
+	{
+		return m_pointer;
+	}
+
+	bool equals(const btHashPtr& other) const
+	{
+		return getPointer() == other.getPointer();
+	}
+
+	//to our success
+	SIMD_FORCE_INLINE	unsigned int getHash()const
+	{
+		const bool VOID_IS_8 = ((sizeof(void*)==8));
+		
+		int key = VOID_IS_8? m_hashValues[0]+m_hashValues[1] : m_hashValues[0];
+	
+		// Thomas Wang's hash
+		key += ~(key << 15);	key ^=  (key >> 10);	key +=  (key << 3);	key ^=  (key >> 6);	key += ~(key << 11);	key ^=  (key >> 16);
+		return key;
+	}
+
+	
+};
+
+
+template <class Value>
+class btHashKeyPtr
+{
+        int     m_uid;
+public:
+
+        btHashKeyPtr(int uid)    :m_uid(uid)
+        {
+        }
+
+        int     getUid1() const
+        {
+                return m_uid;
+        }
+
+        bool equals(const btHashKeyPtr<Value>& other) const
+        {
+                return getUid1() == other.getUid1();
+        }
+
+        //to our success
+        SIMD_FORCE_INLINE       unsigned int getHash()const
+        {
+                int key = m_uid;
+                // Thomas Wang's hash
+                key += ~(key << 15);	key ^=  (key >> 10);	key +=  (key << 3);	key ^=  (key >> 6);	key += ~(key << 11);	key ^=  (key >> 16);
+                return key;
+        }
+
+        
+};
+
 
 template <class Value>
@@ -12,14 +175,17 @@
 public:
 
-	btHashKey(int uid)
-		:m_uid(uid)
-	{
-	}
-
-	int	getUid() const
+	btHashKey(int uid)	:m_uid(uid)
+	{
+	}
+
+	int	getUid1() const
 	{
 		return m_uid;
 	}
 
+	bool equals(const btHashKey<Value>& other) const
+	{
+		return getUid1() == other.getUid1();
+	}
 	//to our success
 	SIMD_FORCE_INLINE	unsigned int getHash()const
@@ -27,55 +193,9 @@
 		int key = m_uid;
 		// Thomas Wang's hash
-		key += ~(key << 15);
-		key ^=  (key >> 10);
-		key +=  (key << 3);
-		key ^=  (key >> 6);
-		key += ~(key << 11);
-		key ^=  (key >> 16);
+		key += ~(key << 15);	key ^=  (key >> 10);	key +=  (key << 3);	key ^=  (key >> 6);	key += ~(key << 11);	key ^=  (key >> 16);
 		return key;
 	}
-
-	btHashKey	getKey(const Value& value) const
-	{
-		return btHashKey(value.getUid());
-	}
-};
-
-
-template <class Value>
-class btHashKeyPtr
-{
-	int	m_uid;
-public:
-
-	btHashKeyPtr(int uid)
-		:m_uid(uid)
-	{
-	}
-
-	int	getUid() const
-	{
-		return m_uid;
-	}
-
-	//to our success
-	SIMD_FORCE_INLINE	unsigned int getHash()const
-	{
-		int key = m_uid;
-		// Thomas Wang's hash
-		key += ~(key << 15);
-		key ^=  (key >> 10);
-		key +=  (key << 3);
-		key ^=  (key >> 6);
-		key += ~(key << 11);
-		key ^=  (key >> 16);
-		return key;
-	}
-
-	btHashKeyPtr	getKey(const Value& value) const
-	{
-		return btHashKeyPtr(value->getUid());
-	}
-};
+};
+
 
 ///The btHashMap template class implements a generic and lightweight hashmap.
@@ -85,11 +205,12 @@
 {
 
+protected:
 	btAlignedObjectArray<int>		m_hashTable;
 	btAlignedObjectArray<int>		m_next;
+	
 	btAlignedObjectArray<Value>		m_valueArray;
-
-
-
-	void	growTables(const Key& key)
+	btAlignedObjectArray<Key>		m_keyArray;
+
+	void	growTables(const Key& /*key*/)
 	{
 		int newCapacity = m_valueArray.capacity();
@@ -116,7 +237,8 @@
 			for(i=0;i<curHashtableSize;i++)
 			{
-				const Value& value = m_valueArray[i];
-
-				int	hashValue = key.getKey(value).getHash() & (m_valueArray.capacity()-1);	// New hash value with new mask
+				//const Value& value = m_valueArray[i];
+				//const Key& key = m_keyArray[i];
+
+				int	hashValue = m_keyArray[i].getHash() & (m_valueArray.capacity()-1);	// New hash value with new mask
 				m_next[i] = m_hashTable[hashValue];
 				m_hashTable[hashValue] = i;
@@ -131,12 +253,18 @@
 	void insert(const Key& key, const Value& value) {
 		int hash = key.getHash() & (m_valueArray.capacity()-1);
-		//don't add it if it is already there
-		if (find(key))
-		{
+
+		//replace value if the key is already there
+		int index = findIndex(key);
+		if (index != BT_HASH_NULL)
+		{
+			m_valueArray[index]=value;
 			return;
 		}
+
 		int count = m_valueArray.size();
 		int oldCapacity = m_valueArray.capacity();
 		m_valueArray.push_back(value);
+		m_keyArray.push_back(key);
+
 		int newCapacity = m_valueArray.capacity();
 		if (oldCapacity < newCapacity)
@@ -192,10 +320,10 @@
 		{
 			m_valueArray.pop_back();
+			m_keyArray.pop_back();
 			return;
 		}
 
 		// Remove the last pair from the hash table.
-		const Value* lastValue = &m_valueArray[lastPairIndex];
-		int lastHash = key.getKey(*lastValue).getHash() & (m_valueArray.capacity()-1);
+		int lastHash = m_keyArray[lastPairIndex].getHash() & (m_valueArray.capacity()-1);
 
 		index = m_hashTable[lastHash];
@@ -221,4 +349,5 @@
 		// Copy the last pair into the remove pair's spot.
 		m_valueArray[pairIndex] = m_valueArray[lastPairIndex];
+		m_keyArray[pairIndex] = m_keyArray[lastPairIndex];
 
 		// Insert the last pair into the hash table
@@ -227,4 +356,5 @@
 
 		m_valueArray.pop_back();
+		m_keyArray.pop_back();
 
 	}
@@ -277,7 +407,7 @@
 	int	findIndex(const Key& key) const
 	{
-		int hash = key.getHash() & (m_valueArray.capacity()-1);
-
-		if (hash >= m_hashTable.size())
+		unsigned int hash = key.getHash() & (m_valueArray.capacity()-1);
+
+		if (hash >= (unsigned int)m_hashTable.size())
 		{
 			return BT_HASH_NULL;
@@ -285,5 +415,5 @@
 
 		int index = m_hashTable[hash];
-		while ((index != BT_HASH_NULL) && (key.getUid() == key.getKey(m_valueArray[index]).getUid()) == false)
+		while ((index != BT_HASH_NULL) && key.equals(m_keyArray[index]) == false)
 		{
 			index = m_next[index];
@@ -297,4 +427,5 @@
 		m_next.clear();
 		m_valueArray.clear();
+		m_keyArray.clear();
 	}
 
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btIDebugDraw.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btIDebugDraw.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btIDebugDraw.h	(revision 8284)
@@ -1,26 +1,15 @@
 /*
-Copyright (c) 2005 Gino van den Bergen / Erwin Coumans http://continuousphysics.com
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2009 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.
 */
 
@@ -36,4 +25,5 @@
 ///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld.
 ///A class that implements the btIDebugDraw interface has to implement the drawLine method at a minimum.
+///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1]
 class	btIDebugDraw
 {
@@ -56,4 +46,5 @@
 		DBG_DrawConstraints = (1 << 11),
 		DBG_DrawConstraintLimits = (1 << 12),
+		DBG_FastWireframe = (1<<13),
 		DBG_MAX_DEBUG_DRAW_MODE
 	};
@@ -61,18 +52,46 @@
 	virtual ~btIDebugDraw() {};
 
+	virtual void	drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
+		
 	virtual void    drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
 	{
+        (void) toColor;
 		drawLine (from, to, fromColor);
 	}
 
-	virtual void	drawBox (const btVector3& boxMin, const btVector3& boxMax, const btVector3& color, btScalar alpha)
-	{
-	}
-
+	virtual void	drawSphere(btScalar radius, const btTransform& transform, const btVector3& color)
+	{
+		btVector3 start = transform.getOrigin();
+
+		const btVector3 xoffs = transform.getBasis() * btVector3(radius,0,0);
+		const btVector3 yoffs = transform.getBasis() * btVector3(0,radius,0);
+		const btVector3 zoffs = transform.getBasis() * btVector3(0,0,radius);
+
+		// XY 
+		drawLine(start-xoffs, start+yoffs, color);
+		drawLine(start+yoffs, start+xoffs, color);
+		drawLine(start+xoffs, start-yoffs, color);
+		drawLine(start-yoffs, start-xoffs, color);
+
+		// XZ
+		drawLine(start-xoffs, start+zoffs, color);
+		drawLine(start+zoffs, start+xoffs, color);
+		drawLine(start+xoffs, start-zoffs, color);
+		drawLine(start-zoffs, start-xoffs, color);
+
+		// YZ
+		drawLine(start-yoffs, start+zoffs, color);
+		drawLine(start+zoffs, start+yoffs, color);
+		drawLine(start+yoffs, start-zoffs, color);
+		drawLine(start-zoffs, start-yoffs, color);
+	}
+	
 	virtual void	drawSphere (const btVector3& p, btScalar radius, const btVector3& color)
 	{
-	}
-
-	virtual void	drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
+		btTransform tr;
+		tr.setIdentity();
+		tr.setOrigin(p);
+		drawSphere(radius,tr,color);
+	}
 	
 	virtual	void	drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha)
@@ -97,5 +116,5 @@
 	virtual int		getDebugMode() const = 0;
 
-	inline void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color)
+	virtual void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color)
 	{
 
@@ -126,5 +145,5 @@
 		}
 	}
-	void drawTransform(const btTransform& transform, btScalar orthoLen)
+	virtual void drawTransform(const btTransform& transform, btScalar orthoLen)
 	{
 		btVector3 start = transform.getOrigin();
@@ -134,5 +153,5 @@
 	}
 
-	void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle, 
+	virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle, 
 				const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f))
 	{
@@ -159,5 +178,5 @@
 		}
 	}
-	void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius, 
+	virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius, 
 		btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f))
 	{
@@ -261,5 +280,5 @@
 	}
 	
-	void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
+	virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
 	{
 		drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
@@ -276,5 +295,5 @@
 		drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
 	}
-	void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btTransform& trans, const btVector3& color)
+	virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btTransform& trans, const btVector3& color)
 	{
 		drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btMatrix3x3.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btMatrix3x3.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btMatrix3x3.h	(revision 8284)
@@ -14,160 +14,167 @@
 
 
-#ifndef btMatrix3x3_H
-#define btMatrix3x3_H
-
-#include "btScalar.h"
+#ifndef	BT_MATRIX3x3_H
+#define BT_MATRIX3x3_H
 
 #include "btVector3.h"
 #include "btQuaternion.h"
 
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btMatrix3x3Data	btMatrix3x3DoubleData 
+#else
+#define btMatrix3x3Data	btMatrix3x3FloatData
+#endif //BT_USE_DOUBLE_PRECISION
 
 
 /**@brief The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3.
- * Make sure to only include a pure orthogonal matrix without scaling. */
+* Make sure to only include a pure orthogonal matrix without scaling. */
 class btMatrix3x3 {
-	public:
-  /** @brief No initializaion constructor */
-		btMatrix3x3 () {}
-		
-//		explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); }
-		
-  /**@brief Constructor from Quaternion */
-		explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); }
-		/*
-		template <typename btScalar>
-		Matrix3x3(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
-		{ 
-			setEulerYPR(yaw, pitch, roll);
-		}
-		*/
-  /** @brief Constructor with row major formatting */
-		btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz,
-				  const btScalar& yx, const btScalar& yy, const btScalar& yz,
-				  const btScalar& zx, const btScalar& zy, const btScalar& zz)
-		{ 
-			setValue(xx, xy, xz, 
-					 yx, yy, yz, 
-					 zx, zy, zz);
-		}
-  /** @brief Copy constructor */
-		SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other)
-		{
-			m_el[0] = other.m_el[0];
-			m_el[1] = other.m_el[1];
-			m_el[2] = other.m_el[2];
-		}
-  /** @brief Assignment Operator */
-		SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other)
-		{
-			m_el[0] = other.m_el[0];
-			m_el[1] = other.m_el[1];
-			m_el[2] = other.m_el[2];
-			return *this;
-		}
-
-  /** @brief Get a column of the matrix as a vector 
-   *  @param i Column number 0 indexed */
-		SIMD_FORCE_INLINE btVector3 getColumn(int i) const
-		{
-			return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
-		}
-		
-
-  /** @brief Get a row of the matrix as a vector 
-   *  @param i Row number 0 indexed */
-		SIMD_FORCE_INLINE const btVector3& getRow(int i) const
-		{
-			btFullAssert(0 <= i && i < 3);
-			return m_el[i];
-		}
-
-  /** @brief Get a mutable reference to a row of the matrix as a vector 
-   *  @param i Row number 0 indexed */
-		SIMD_FORCE_INLINE btVector3&  operator[](int i)
-		{ 
-			btFullAssert(0 <= i && i < 3);
-			return m_el[i]; 
-		}
-		
-  /** @brief Get a const reference to a row of the matrix as a vector 
-   *  @param i Row number 0 indexed */
-		SIMD_FORCE_INLINE const btVector3& operator[](int i) const
-		{
-			btFullAssert(0 <= i && i < 3);
-			return m_el[i]; 
-		}
-		
-  /** @brief Multiply by the target matrix on the right
-   *  @param m Rotation matrix to be applied 
-   * Equivilant to this = this * m */
-		btMatrix3x3& operator*=(const btMatrix3x3& m); 
-		
-  /** @brief Set from a carray of btScalars 
-   *  @param m A pointer to the beginning of an array of 9 btScalars */
+
+	///Data storage for the matrix, each vector is a row of the matrix
+	btVector3 m_el[3];
+
+public:
+	/** @brief No initializaion constructor */
+	btMatrix3x3 () {}
+
+	//		explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); }
+
+	/**@brief Constructor from Quaternion */
+	explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); }
+	/*
+	template <typename btScalar>
+	Matrix3x3(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+	{ 
+	setEulerYPR(yaw, pitch, roll);
+	}
+	*/
+	/** @brief Constructor with row major formatting */
+	btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz,
+		const btScalar& yx, const btScalar& yy, const btScalar& yz,
+		const btScalar& zx, const btScalar& zy, const btScalar& zz)
+	{ 
+		setValue(xx, xy, xz, 
+			yx, yy, yz, 
+			zx, zy, zz);
+	}
+	/** @brief Copy constructor */
+	SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other)
+	{
+		m_el[0] = other.m_el[0];
+		m_el[1] = other.m_el[1];
+		m_el[2] = other.m_el[2];
+	}
+	/** @brief Assignment Operator */
+	SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other)
+	{
+		m_el[0] = other.m_el[0];
+		m_el[1] = other.m_el[1];
+		m_el[2] = other.m_el[2];
+		return *this;
+	}
+
+	/** @brief Get a column of the matrix as a vector 
+	*  @param i Column number 0 indexed */
+	SIMD_FORCE_INLINE btVector3 getColumn(int i) const
+	{
+		return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
+	}
+
+
+	/** @brief Get a row of the matrix as a vector 
+	*  @param i Row number 0 indexed */
+	SIMD_FORCE_INLINE const btVector3& getRow(int i) const
+	{
+		btFullAssert(0 <= i && i < 3);
+		return m_el[i];
+	}
+
+	/** @brief Get a mutable reference to a row of the matrix as a vector 
+	*  @param i Row number 0 indexed */
+	SIMD_FORCE_INLINE btVector3&  operator[](int i)
+	{ 
+		btFullAssert(0 <= i && i < 3);
+		return m_el[i]; 
+	}
+
+	/** @brief Get a const reference to a row of the matrix as a vector 
+	*  @param i Row number 0 indexed */
+	SIMD_FORCE_INLINE const btVector3& operator[](int i) const
+	{
+		btFullAssert(0 <= i && i < 3);
+		return m_el[i]; 
+	}
+
+	/** @brief Multiply by the target matrix on the right
+	*  @param m Rotation matrix to be applied 
+	* Equivilant to this = this * m */
+	btMatrix3x3& operator*=(const btMatrix3x3& m); 
+
+	/** @brief Set from a carray of btScalars 
+	*  @param m A pointer to the beginning of an array of 9 btScalars */
 	void setFromOpenGLSubMatrix(const btScalar *m)
-		{
-			m_el[0].setValue(m[0],m[4],m[8]);
-			m_el[1].setValue(m[1],m[5],m[9]);
-			m_el[2].setValue(m[2],m[6],m[10]);
-
-		}
-  /** @brief Set the values of the matrix explicitly (row major)
-   *  @param xx Top left
-   *  @param xy Top Middle
-   *  @param xz Top Right
-   *  @param yx Middle Left
-   *  @param yy Middle Middle
-   *  @param yz Middle Right
-   *  @param zx Bottom Left
-   *  @param zy Bottom Middle
-   *  @param zz Bottom Right*/
-		void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, 
-					  const btScalar& yx, const btScalar& yy, const btScalar& yz, 
-					  const btScalar& zx, const btScalar& zy, const btScalar& zz)
-		{
-			m_el[0].setValue(xx,xy,xz);
-			m_el[1].setValue(yx,yy,yz);
-			m_el[2].setValue(zx,zy,zz);
-		}
-
-  /** @brief Set the matrix from a quaternion
-   *  @param q The Quaternion to match */  
-		void setRotation(const btQuaternion& q) 
-		{
-			btScalar d = q.length2();
-			btFullAssert(d != btScalar(0.0));
-			btScalar s = btScalar(2.0) / d;
-			btScalar xs = q.x() * s,   ys = q.y() * s,   zs = q.z() * s;
-			btScalar wx = q.w() * xs,  wy = q.w() * ys,  wz = q.w() * zs;
-			btScalar xx = q.x() * xs,  xy = q.x() * ys,  xz = q.x() * zs;
-			btScalar yy = q.y() * ys,  yz = q.y() * zs,  zz = q.z() * zs;
-			setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy,
-					 xy + wz, btScalar(1.0) - (xx + zz), yz - wx,
-					 xz - wy, yz + wx, btScalar(1.0) - (xx + yy));
-		}
-		
-
-  /** @brief Set the matrix from euler angles using YPR around YXZ respectively
-   *  @param yaw Yaw about Y axis
-   *  @param pitch Pitch about X axis
-   *  @param roll Roll about Z axis 
-   */
-		void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 
-		{
-			setEulerZYX(roll, pitch, yaw);
-		}
+	{
+		m_el[0].setValue(m[0],m[4],m[8]);
+		m_el[1].setValue(m[1],m[5],m[9]);
+		m_el[2].setValue(m[2],m[6],m[10]);
+
+	}
+	/** @brief Set the values of the matrix explicitly (row major)
+	*  @param xx Top left
+	*  @param xy Top Middle
+	*  @param xz Top Right
+	*  @param yx Middle Left
+	*  @param yy Middle Middle
+	*  @param yz Middle Right
+	*  @param zx Bottom Left
+	*  @param zy Bottom Middle
+	*  @param zz Bottom Right*/
+	void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, 
+		const btScalar& yx, const btScalar& yy, const btScalar& yz, 
+		const btScalar& zx, const btScalar& zy, const btScalar& zz)
+	{
+		m_el[0].setValue(xx,xy,xz);
+		m_el[1].setValue(yx,yy,yz);
+		m_el[2].setValue(zx,zy,zz);
+	}
+
+	/** @brief Set the matrix from a quaternion
+	*  @param q The Quaternion to match */  
+	void setRotation(const btQuaternion& q) 
+	{
+		btScalar d = q.length2();
+		btFullAssert(d != btScalar(0.0));
+		btScalar s = btScalar(2.0) / d;
+		btScalar xs = q.x() * s,   ys = q.y() * s,   zs = q.z() * s;
+		btScalar wx = q.w() * xs,  wy = q.w() * ys,  wz = q.w() * zs;
+		btScalar xx = q.x() * xs,  xy = q.x() * ys,  xz = q.x() * zs;
+		btScalar yy = q.y() * ys,  yz = q.y() * zs,  zz = q.z() * zs;
+		setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy,
+			xy + wz, btScalar(1.0) - (xx + zz), yz - wx,
+			xz - wy, yz + wx, btScalar(1.0) - (xx + yy));
+	}
+
+
+	/** @brief Set the matrix from euler angles using YPR around YXZ respectively
+	*  @param yaw Yaw about Y axis
+	*  @param pitch Pitch about X axis
+	*  @param roll Roll about Z axis 
+	*/
+	void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 
+	{
+		setEulerZYX(roll, pitch, yaw);
+	}
 
 	/** @brief Set the matrix from euler angles YPR around ZYX axes
-	 * @param eulerX Roll about X axis
-         * @param eulerY Pitch around Y axis
-         * @param eulerZ Yaw aboud Z axis
-         * 
-	 * These angles are used to produce a rotation matrix. The euler
-	 * angles are applied in ZYX order. I.e a vector is first rotated 
-	 * about X then Y and then Z
-	 **/
+	* @param eulerX Roll about X axis
+	* @param eulerY Pitch around Y axis
+	* @param eulerZ Yaw aboud Z axis
+	* 
+	* These angles are used to produce a rotation matrix. The euler
+	* angles are applied in ZYX order. I.e a vector is first rotated 
+	* about X then Y and then Z
+	**/
 	void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { 
-  ///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code
+		///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code
 		btScalar ci ( btCos(eulerX)); 
 		btScalar cj ( btCos(eulerY)); 
@@ -180,225 +187,231 @@
 		btScalar sc = si * ch; 
 		btScalar ss = si * sh;
-		
+
 		setValue(cj * ch, sj * sc - cs, sj * cc + ss,
-				 cj * sh, sj * ss + cc, sj * cs - sc, 
-	       			 -sj,      cj * si,      cj * ci);
-	}
-
-  /**@brief Set the matrix to the identity */
-		void setIdentity()
+			cj * sh, sj * ss + cc, sj * cs - sc, 
+			-sj,      cj * si,      cj * ci);
+	}
+
+	/**@brief Set the matrix to the identity */
+	void setIdentity()
+	{ 
+		setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0), 
+			btScalar(0.0), btScalar(1.0), btScalar(0.0), 
+			btScalar(0.0), btScalar(0.0), btScalar(1.0)); 
+	}
+
+	static const btMatrix3x3&	getIdentity()
+	{
+		static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0), 
+			btScalar(0.0), btScalar(1.0), btScalar(0.0), 
+			btScalar(0.0), btScalar(0.0), btScalar(1.0));
+		return identityMatrix;
+	}
+
+	/**@brief Fill the values of the matrix into a 9 element array 
+	* @param m The array to be filled */
+	void getOpenGLSubMatrix(btScalar *m) const 
+	{
+		m[0]  = btScalar(m_el[0].x()); 
+		m[1]  = btScalar(m_el[1].x());
+		m[2]  = btScalar(m_el[2].x());
+		m[3]  = btScalar(0.0); 
+		m[4]  = btScalar(m_el[0].y());
+		m[5]  = btScalar(m_el[1].y());
+		m[6]  = btScalar(m_el[2].y());
+		m[7]  = btScalar(0.0); 
+		m[8]  = btScalar(m_el[0].z()); 
+		m[9]  = btScalar(m_el[1].z());
+		m[10] = btScalar(m_el[2].z());
+		m[11] = btScalar(0.0); 
+	}
+
+	/**@brief Get the matrix represented as a quaternion 
+	* @param q The quaternion which will be set */
+	void getRotation(btQuaternion& q) const
+	{
+		btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
+		btScalar temp[4];
+
+		if (trace > btScalar(0.0)) 
+		{
+			btScalar s = btSqrt(trace + btScalar(1.0));
+			temp[3]=(s * btScalar(0.5));
+			s = btScalar(0.5) / s;
+
+			temp[0]=((m_el[2].y() - m_el[1].z()) * s);
+			temp[1]=((m_el[0].z() - m_el[2].x()) * s);
+			temp[2]=((m_el[1].x() - m_el[0].y()) * s);
+		} 
+		else 
+		{
+			int i = m_el[0].x() < m_el[1].y() ? 
+				(m_el[1].y() < m_el[2].z() ? 2 : 1) :
+				(m_el[0].x() < m_el[2].z() ? 2 : 0); 
+			int j = (i + 1) % 3;  
+			int k = (i + 2) % 3;
+
+			btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0));
+			temp[i] = s * btScalar(0.5);
+			s = btScalar(0.5) / s;
+
+			temp[3] = (m_el[k][j] - m_el[j][k]) * s;
+			temp[j] = (m_el[j][i] + m_el[i][j]) * s;
+			temp[k] = (m_el[k][i] + m_el[i][k]) * s;
+		}
+		q.setValue(temp[0],temp[1],temp[2],temp[3]);
+	}
+
+	/**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR
+	* @param yaw Yaw around Y axis
+	* @param pitch Pitch around X axis
+	* @param roll around Z axis */	
+	void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const
+	{
+
+		// first use the normal calculus
+		yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
+		pitch = btScalar(btAsin(-m_el[2].x()));
+		roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
+
+		// on pitch = +/-HalfPI
+		if (btFabs(pitch)==SIMD_HALF_PI)
+		{
+			if (yaw>0)
+				yaw-=SIMD_PI;
+			else
+				yaw+=SIMD_PI;
+
+			if (roll>0)
+				roll-=SIMD_PI;
+			else
+				roll+=SIMD_PI;
+		}
+	};
+
+
+	/**@brief Get the matrix represented as euler angles around ZYX
+	* @param yaw Yaw around X axis
+	* @param pitch Pitch around Y axis
+	* @param roll around X axis 
+	* @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/	
+	void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
+	{
+		struct Euler
+		{
+			btScalar yaw;
+			btScalar pitch;
+			btScalar roll;
+		};
+
+		Euler euler_out;
+		Euler euler_out2; //second solution
+		//get the pointer to the raw data
+
+		// Check that pitch is not at a singularity
+		if (btFabs(m_el[2].x()) >= 1)
+		{
+			euler_out.yaw = 0;
+			euler_out2.yaw = 0;
+
+			// From difference of angles formula
+			btScalar delta = btAtan2(m_el[0].x(),m_el[0].z());
+			if (m_el[2].x() > 0)  //gimbal locked up
+			{
+				euler_out.pitch = SIMD_PI / btScalar(2.0);
+				euler_out2.pitch = SIMD_PI / btScalar(2.0);
+				euler_out.roll = euler_out.pitch + delta;
+				euler_out2.roll = euler_out.pitch + delta;
+			}
+			else // gimbal locked down
+			{
+				euler_out.pitch = -SIMD_PI / btScalar(2.0);
+				euler_out2.pitch = -SIMD_PI / btScalar(2.0);
+				euler_out.roll = -euler_out.pitch + delta;
+				euler_out2.roll = -euler_out.pitch + delta;
+			}
+		}
+		else
+		{
+			euler_out.pitch = - btAsin(m_el[2].x());
+			euler_out2.pitch = SIMD_PI - euler_out.pitch;
+
+			euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch), 
+				m_el[2].z()/btCos(euler_out.pitch));
+			euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch), 
+				m_el[2].z()/btCos(euler_out2.pitch));
+
+			euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch), 
+				m_el[0].x()/btCos(euler_out.pitch));
+			euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch), 
+				m_el[0].x()/btCos(euler_out2.pitch));
+		}
+
+		if (solution_number == 1)
 		{ 
-			setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0), 
-					 btScalar(0.0), btScalar(1.0), btScalar(0.0), 
-					 btScalar(0.0), btScalar(0.0), btScalar(1.0)); 
+			yaw = euler_out.yaw; 
+			pitch = euler_out.pitch;
+			roll = euler_out.roll;
 		}
-
-		static const btMatrix3x3&	getIdentity()
+		else
+		{ 
+			yaw = euler_out2.yaw; 
+			pitch = euler_out2.pitch;
+			roll = euler_out2.roll;
+		}
+	}
+
+	/**@brief Create a scaled copy of the matrix 
+	* @param s Scaling vector The elements of the vector will scale each column */
+
+	btMatrix3x3 scaled(const btVector3& s) const
+	{
+		return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(),
+			m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(),
+			m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z());
+	}
+
+	/**@brief Return the determinant of the matrix */
+	btScalar            determinant() const;
+	/**@brief Return the adjoint of the matrix */
+	btMatrix3x3 adjoint() const;
+	/**@brief Return the matrix with all values non negative */
+	btMatrix3x3 absolute() const;
+	/**@brief Return the transpose of the matrix */
+	btMatrix3x3 transpose() const;
+	/**@brief Return the inverse of the matrix */
+	btMatrix3x3 inverse() const; 
+
+	btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
+	btMatrix3x3 timesTranspose(const btMatrix3x3& m) const;
+
+	SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const 
+	{
+		return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z();
+	}
+	SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const 
+	{
+		return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z();
+	}
+	SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const 
+	{
+		return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z();
+	}
+
+
+	/**@brief diagonalizes this matrix by the Jacobi method.
+	* @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original
+	* coordinate system, i.e., old_this = rot * new_this * rot^T. 
+	* @param threshold See iteration
+	* @param iteration The iteration stops when all off-diagonal elements are less than the threshold multiplied 
+	* by the sum of the absolute values of the diagonal, or when maxSteps have been executed. 
+	* 
+	* Note that this matrix is assumed to be symmetric. 
+	*/
+	void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)
+	{
+		rot.setIdentity();
+		for (int step = maxSteps; step > 0; step--)
 		{
-			static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0), 
-					 btScalar(0.0), btScalar(1.0), btScalar(0.0), 
-					 btScalar(0.0), btScalar(0.0), btScalar(1.0));
-			return identityMatrix;
-		}
-
-  /**@brief Fill the values of the matrix into a 9 element array 
-   * @param m The array to be filled */
-		void getOpenGLSubMatrix(btScalar *m) const 
-		{
-			m[0]  = btScalar(m_el[0].x()); 
-			m[1]  = btScalar(m_el[1].x());
-			m[2]  = btScalar(m_el[2].x());
-			m[3]  = btScalar(0.0); 
-			m[4]  = btScalar(m_el[0].y());
-			m[5]  = btScalar(m_el[1].y());
-			m[6]  = btScalar(m_el[2].y());
-			m[7]  = btScalar(0.0); 
-			m[8]  = btScalar(m_el[0].z()); 
-			m[9]  = btScalar(m_el[1].z());
-			m[10] = btScalar(m_el[2].z());
-			m[11] = btScalar(0.0); 
-		}
-
-  /**@brief Get the matrix represented as a quaternion 
-   * @param q The quaternion which will be set */
-		void getRotation(btQuaternion& q) const
-		{
-			btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
-			btScalar temp[4];
-			
-			if (trace > btScalar(0.0)) 
-			{
-				btScalar s = btSqrt(trace + btScalar(1.0));
-				temp[3]=(s * btScalar(0.5));
-				s = btScalar(0.5) / s;
-				
-				temp[0]=((m_el[2].y() - m_el[1].z()) * s);
-				temp[1]=((m_el[0].z() - m_el[2].x()) * s);
-				temp[2]=((m_el[1].x() - m_el[0].y()) * s);
-			} 
-			else 
-			{
-				int i = m_el[0].x() < m_el[1].y() ? 
-					(m_el[1].y() < m_el[2].z() ? 2 : 1) :
-					(m_el[0].x() < m_el[2].z() ? 2 : 0); 
-				int j = (i + 1) % 3;  
-				int k = (i + 2) % 3;
-				
-				btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0));
-				temp[i] = s * btScalar(0.5);
-				s = btScalar(0.5) / s;
-				
-				temp[3] = (m_el[k][j] - m_el[j][k]) * s;
-				temp[j] = (m_el[j][i] + m_el[i][j]) * s;
-				temp[k] = (m_el[k][i] + m_el[i][k]) * s;
-			}
-			q.setValue(temp[0],temp[1],temp[2],temp[3]);
-		}
-
-  /**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR
-   * @param yaw Yaw around Y axis
-   * @param pitch Pitch around X axis
-   * @param roll around Z axis */	
-		void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const
-		{
-			
-			// first use the normal calculus
-			yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
-			pitch = btScalar(btAsin(-m_el[2].x()));
-			roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
-
-			// on pitch = +/-HalfPI
-			if (btFabs(pitch)==SIMD_HALF_PI)
-			{
-				if (yaw>0)
-					yaw-=SIMD_PI;
-				else
-					yaw+=SIMD_PI;
-
-				if (roll>0)
-					roll-=SIMD_PI;
-				else
-					roll+=SIMD_PI;
-			}
-		};
-
-
-  /**@brief Get the matrix represented as euler angles around ZYX
-   * @param yaw Yaw around X axis
-   * @param pitch Pitch around Y axis
-   * @param roll around X axis 
-   * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/	
-  void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
-  {
-    struct Euler{btScalar yaw, pitch, roll;};
-    Euler euler_out;
-    Euler euler_out2; //second solution
-    //get the pointer to the raw data
-    
-    // Check that pitch is not at a singularity
-    if (btFabs(m_el[2].x()) >= 1)
-    {
-      euler_out.yaw = 0;
-      euler_out2.yaw = 0;
-	
-      // From difference of angles formula
-      btScalar delta = btAtan2(m_el[0].x(),m_el[0].z());
-      if (m_el[2].x() > 0)  //gimbal locked up
-      {
-        euler_out.pitch = SIMD_PI / btScalar(2.0);
-        euler_out2.pitch = SIMD_PI / btScalar(2.0);
-        euler_out.roll = euler_out.pitch + delta;
-        euler_out2.roll = euler_out.pitch + delta;
-      }
-      else // gimbal locked down
-      {
-        euler_out.pitch = -SIMD_PI / btScalar(2.0);
-        euler_out2.pitch = -SIMD_PI / btScalar(2.0);
-        euler_out.roll = -euler_out.pitch + delta;
-        euler_out2.roll = -euler_out.pitch + delta;
-      }
-    }
-    else
-    {
-      euler_out.pitch = - btAsin(m_el[2].x());
-      euler_out2.pitch = SIMD_PI - euler_out.pitch;
-	
-      euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch), 
-			       m_el[2].z()/btCos(euler_out.pitch));
-      euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch), 
-				m_el[2].z()/btCos(euler_out2.pitch));
-	
-      euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch), 
-			      m_el[0].x()/btCos(euler_out.pitch));
-      euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch), 
-                               m_el[0].x()/btCos(euler_out2.pitch));
-    }
-    
-    if (solution_number == 1)
-    { 
-		yaw = euler_out.yaw; 
-		pitch = euler_out.pitch;
-		roll = euler_out.roll;
-    }
-    else
-    { 
-		yaw = euler_out2.yaw; 
-		pitch = euler_out2.pitch;
-		roll = euler_out2.roll;
-    }
-  }
-
-  /**@brief Create a scaled copy of the matrix 
-   * @param s Scaling vector The elements of the vector will scale each column */
-		
-		btMatrix3x3 scaled(const btVector3& s) const
-		{
-			return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(),
-									 m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(),
-									 m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z());
-		}
-
-  /**@brief Return the determinant of the matrix */
-		btScalar            determinant() const;
-  /**@brief Return the adjoint of the matrix */
-		btMatrix3x3 adjoint() const;
-  /**@brief Return the matrix with all values non negative */
-		btMatrix3x3 absolute() const;
-  /**@brief Return the transpose of the matrix */
-		btMatrix3x3 transpose() const;
-  /**@brief Return the inverse of the matrix */
-		btMatrix3x3 inverse() const; 
-		
-		btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
-		btMatrix3x3 timesTranspose(const btMatrix3x3& m) const;
-		
-		SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const 
-		{
-			return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z();
-		}
-		SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const 
-		{
-			return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z();
-		}
-		SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const 
-		{
-			return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z();
-		}
-		
-
-  /**@brief diagonalizes this matrix by the Jacobi method.
-   * @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original
-   * coordinate system, i.e., old_this = rot * new_this * rot^T. 
-   * @param threshold See iteration
-   * @param iteration The iteration stops when all off-diagonal elements are less than the threshold multiplied 
-   * by the sum of the absolute values of the diagonal, or when maxSteps have been executed. 
-   * 
-   * Note that this matrix is assumed to be symmetric. 
-   */
-		void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)
-		{
-		 rot.setIdentity();
-		 for (int step = maxSteps; step > 0; step--)
-		 {
 			// find off-diagonal element [p][q] with largest magnitude
 			int p = 0;
@@ -409,15 +422,15 @@
 			if (v > max)
 			{
-			   q = 2;
-			   r = 1;
-			   max = v;
+				q = 2;
+				r = 1;
+				max = v;
 			}
 			v = btFabs(m_el[1][2]);
 			if (v > max)
 			{
-			   p = 1;
-			   q = 2;
-			   r = 0;
-			   max = v;
+				p = 1;
+				q = 2;
+				r = 0;
+				max = v;
 			}
 
@@ -425,9 +438,9 @@
 			if (max <= t)
 			{
-			   if (max <= SIMD_EPSILON * t)
-			   {
-				  return;
-			   }
-			   step = 1;
+				if (max <= SIMD_EPSILON * t)
+				{
+					return;
+				}
+				step = 1;
 			}
 
@@ -440,15 +453,15 @@
 			if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON))
 			{
-			   t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2))
-										: 1 / (theta - btSqrt(1 + theta2));
-			   cos = 1 / btSqrt(1 + t * t);
-			   sin = cos * t;
+				t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2))
+					: 1 / (theta - btSqrt(1 + theta2));
+				cos = 1 / btSqrt(1 + t * t);
+				sin = cos * t;
 			}
 			else
 			{
-			   // approximation for large theta-value, i.e., a nearly diagonal matrix
-			   t = 1 / (theta * (2 + btScalar(0.5) / theta2));
-			   cos = 1 - btScalar(0.5) * t * t;
-			   sin = cos * t;
+				// approximation for large theta-value, i.e., a nearly diagonal matrix
+				t = 1 / (theta * (2 + btScalar(0.5) / theta2));
+				cos = 1 - btScalar(0.5) * t * t;
+				sin = cos * t;
 			}
 
@@ -465,154 +478,211 @@
 			for (int i = 0; i < 3; i++)
 			{
-			   btVector3& row = rot[i];
-			   mrp = row[p];
-			   mrq = row[q];
-			   row[p] = cos * mrp - sin * mrq;
-			   row[q] = cos * mrq + sin * mrp;
-			}
-		 }
+				btVector3& row = rot[i];
+				mrp = row[p];
+				mrq = row[q];
+				row[p] = cos * mrp - sin * mrq;
+				row[q] = cos * mrq + sin * mrp;
+			}
 		}
-
-
-		
-	protected:
-  /**@brief Calculate the matrix cofactor 
-   * @param r1 The first row to use for calculating the cofactor
-   * @param c1 The first column to use for calculating the cofactor
-   * @param r1 The second row to use for calculating the cofactor
-   * @param c1 The second column to use for calculating the cofactor
-   * See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details
-   */
-		btScalar cofac(int r1, int c1, int r2, int c2) const 
-		{
-			return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
-		}
-  ///Data storage for the matrix, each vector is a row of the matrix
-		btVector3 m_el[3];
-	};
+	}
+
+
+
+
+	/**@brief Calculate the matrix cofactor 
+	* @param r1 The first row to use for calculating the cofactor
+	* @param c1 The first column to use for calculating the cofactor
+	* @param r1 The second row to use for calculating the cofactor
+	* @param c1 The second column to use for calculating the cofactor
+	* See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details
+	*/
+	btScalar cofac(int r1, int c1, int r2, int c2) const 
+	{
+		return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
+	}
+
+	void	serialize(struct	btMatrix3x3Data& dataOut) const;
+
+	void	serializeFloat(struct	btMatrix3x3FloatData& dataOut) const;
+
+	void	deSerialize(const struct	btMatrix3x3Data& dataIn);
+
+	void	deSerializeFloat(const struct	btMatrix3x3FloatData& dataIn);
+
+	void	deSerializeDouble(const struct	btMatrix3x3DoubleData& dataIn);
+
+};
+
+
+SIMD_FORCE_INLINE btMatrix3x3& 
+btMatrix3x3::operator*=(const btMatrix3x3& m)
+{
+	setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),
+		m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),
+		m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]));
+	return *this;
+}
+
+SIMD_FORCE_INLINE btScalar 
+btMatrix3x3::determinant() const
+{ 
+	return btTriple((*this)[0], (*this)[1], (*this)[2]);
+}
+
+
+SIMD_FORCE_INLINE btMatrix3x3 
+btMatrix3x3::absolute() const
+{
+	return btMatrix3x3(
+		btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()),
+		btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()),
+		btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z()));
+}
+
+SIMD_FORCE_INLINE btMatrix3x3 
+btMatrix3x3::transpose() const 
+{
+	return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(),
+		m_el[0].y(), m_el[1].y(), m_el[2].y(),
+		m_el[0].z(), m_el[1].z(), m_el[2].z());
+}
+
+SIMD_FORCE_INLINE btMatrix3x3 
+btMatrix3x3::adjoint() const 
+{
+	return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
+		cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
+		cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
+}
+
+SIMD_FORCE_INLINE btMatrix3x3 
+btMatrix3x3::inverse() const
+{
+	btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
+	btScalar det = (*this)[0].dot(co);
+	btFullAssert(det != btScalar(0.0));
+	btScalar s = btScalar(1.0) / det;
+	return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
+		co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
+		co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
+}
+
+SIMD_FORCE_INLINE btMatrix3x3 
+btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
+{
+	return btMatrix3x3(
+		m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(),
+		m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(),
+		m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(),
+		m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(),
+		m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(),
+		m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(),
+		m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(),
+		m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(),
+		m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z());
+}
+
+SIMD_FORCE_INLINE btMatrix3x3 
+btMatrix3x3::timesTranspose(const btMatrix3x3& m) const
+{
+	return btMatrix3x3(
+		m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
+		m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
+		m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
+
+}
+
+SIMD_FORCE_INLINE btVector3 
+operator*(const btMatrix3x3& m, const btVector3& v) 
+{
+	return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
+}
+
+
+SIMD_FORCE_INLINE btVector3
+operator*(const btVector3& v, const btMatrix3x3& m)
+{
+	return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
+}
+
+SIMD_FORCE_INLINE btMatrix3x3 
+operator*(const btMatrix3x3& m1, const btMatrix3x3& m2)
+{
+	return btMatrix3x3(
+		m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]),
+		m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]),
+		m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2]));
+}
+
+/*
+SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) {
+return btMatrix3x3(
+m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0],
+m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1],
+m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2],
+m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0],
+m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1],
+m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2],
+m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0],
+m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1],
+m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]);
+}
+*/
+
+/**@brief Equality operator between two matrices
+* It will test all elements are equal.  */
+SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
+{
+	return ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
+		m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] &&
+		m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] );
+}
+
+///for serialization
+struct	btMatrix3x3FloatData
+{
+	btVector3FloatData m_el[3];
+};
+
+///for serialization
+struct	btMatrix3x3DoubleData
+{
+	btVector3DoubleData m_el[3];
+};
+
+
 	
-	SIMD_FORCE_INLINE btMatrix3x3& 
-	btMatrix3x3::operator*=(const btMatrix3x3& m)
-	{
-		setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),
-				 m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),
-				 m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]));
-		return *this;
-	}
-	
-	SIMD_FORCE_INLINE btScalar 
-	btMatrix3x3::determinant() const
-	{ 
-		return triple((*this)[0], (*this)[1], (*this)[2]);
-	}
-	
-
-	SIMD_FORCE_INLINE btMatrix3x3 
-	btMatrix3x3::absolute() const
-	{
-		return btMatrix3x3(
-			btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()),
-			btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()),
-			btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z()));
-	}
-
-	SIMD_FORCE_INLINE btMatrix3x3 
-	btMatrix3x3::transpose() const 
-	{
-		return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(),
-								 m_el[0].y(), m_el[1].y(), m_el[2].y(),
-								 m_el[0].z(), m_el[1].z(), m_el[2].z());
-	}
-	
-	SIMD_FORCE_INLINE btMatrix3x3 
-	btMatrix3x3::adjoint() const 
-	{
-		return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
-								 cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
-								 cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
-	}
-	
-	SIMD_FORCE_INLINE btMatrix3x3 
-	btMatrix3x3::inverse() const
-	{
-		btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1));
-		btScalar det = (*this)[0].dot(co);
-		btFullAssert(det != btScalar(0.0));
-		btScalar s = btScalar(1.0) / det;
-		return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s,
-								 co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s,
-								 co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s);
-	}
-	
-	SIMD_FORCE_INLINE btMatrix3x3 
-	btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
-	{
-		return btMatrix3x3(
-			m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(),
-			m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(),
-			m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(),
-			m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(),
-			m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(),
-			m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(),
-			m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(),
-			m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(),
-			m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z());
-	}
-	
-	SIMD_FORCE_INLINE btMatrix3x3 
-	btMatrix3x3::timesTranspose(const btMatrix3x3& m) const
-	{
-		return btMatrix3x3(
-			m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
-			m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
-			m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
-		
-	}
-
-	SIMD_FORCE_INLINE btVector3 
-	operator*(const btMatrix3x3& m, const btVector3& v) 
-	{
-		return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
-	}
-	
-
-	SIMD_FORCE_INLINE btVector3
-	operator*(const btVector3& v, const btMatrix3x3& m)
-	{
-		return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
-	}
-
-	SIMD_FORCE_INLINE btMatrix3x3 
-	operator*(const btMatrix3x3& m1, const btMatrix3x3& m2)
-	{
-		return btMatrix3x3(
-			m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]),
-			m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]),
-			m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2]));
-	}
-
-/*
-	SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) {
-    return btMatrix3x3(
-        m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0],
-        m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1],
-        m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2],
-        m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0],
-        m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1],
-        m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2],
-        m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0],
-        m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1],
-        m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]);
-}
-*/
-
-/**@brief Equality operator between two matrices
- * It will test all elements are equal.  */
-SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
-{
-   return ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
-            m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] &&
-            m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] );
-}
-
-#endif
+
+SIMD_FORCE_INLINE	void	btMatrix3x3::serialize(struct	btMatrix3x3Data& dataOut) const
+{
+	for (int i=0;i<3;i++)
+		m_el[i].serialize(dataOut.m_el[i]);
+}
+
+SIMD_FORCE_INLINE	void	btMatrix3x3::serializeFloat(struct	btMatrix3x3FloatData& dataOut) const
+{
+	for (int i=0;i<3;i++)
+		m_el[i].serializeFloat(dataOut.m_el[i]);
+}
+
+
+SIMD_FORCE_INLINE	void	btMatrix3x3::deSerialize(const struct	btMatrix3x3Data& dataIn)
+{
+	for (int i=0;i<3;i++)
+		m_el[i].deSerialize(dataIn.m_el[i]);
+}
+
+SIMD_FORCE_INLINE	void	btMatrix3x3::deSerializeFloat(const struct	btMatrix3x3FloatData& dataIn)
+{
+	for (int i=0;i<3;i++)
+		m_el[i].deSerializeFloat(dataIn.m_el[i]);
+}
+
+SIMD_FORCE_INLINE	void	btMatrix3x3::deSerializeDouble(const struct	btMatrix3x3DoubleData& dataIn)
+{
+	for (int i=0;i<3;i++)
+		m_el[i].deSerializeDouble(dataIn.m_el[i]);
+}
+
+#endif //BT_MATRIX3x3_H
+
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btMinMax.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btMinMax.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btMinMax.h	(revision 8284)
@@ -18,4 +18,6 @@
 #define GEN_MINMAX_H
 
+#include "LinearMath/btScalar.h"
+
 template <class T>
 SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) 
@@ -31,5 +33,5 @@
 
 template <class T>
-SIMD_FORCE_INLINE const T& GEN_clamped(const T& a, const T& lb, const T& ub) 
+SIMD_FORCE_INLINE const T& btClamped(const T& a, const T& lb, const T& ub) 
 {
 	return a < lb ? lb : (ub < a ? ub : a); 
@@ -55,5 +57,5 @@
 
 template <class T>
-SIMD_FORCE_INLINE void GEN_clamp(T& a, const T& lb, const T& ub) 
+SIMD_FORCE_INLINE void btClamp(T& a, const T& lb, const T& ub) 
 {
 	if (a < lb) 
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btPoolAllocator.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btPoolAllocator.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btPoolAllocator.h	(revision 8284)
@@ -58,4 +58,9 @@
 	}
 
+	int getUsedCount() const
+	{
+		return m_maxElements - m_freeCount;
+	}
+
 	void*	allocate(int size)
 	{
@@ -97,4 +102,13 @@
 	}
 
+	unsigned char*	getPoolAddress()
+	{
+		return m_pool;
+	}
+
+	const unsigned char*	getPoolAddress() const
+	{
+		return m_pool;
+	}
 
 };
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btQuaternion.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btQuaternion.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btQuaternion.h	(revision 8284)
@@ -210,6 +210,15 @@
 	}
 
-
-  /**@brief Return the inverse of this quaternion */
+	/**@brief Return the axis of the rotation represented by this quaternion */
+	btVector3 getAxis() const
+	{
+		btScalar s_squared = btScalar(1.) - btPow(m_floats[3], btScalar(2.));
+		if (s_squared < btScalar(10.) * SIMD_EPSILON) //Check for divide by zero
+			return btVector3(1.0, 0.0, 0.0);  // Arbitrary
+		btScalar s = btSqrt(s_squared);
+		return btVector3(m_floats[0] / s, m_floats[1] / s, m_floats[2] / s);
+	}
+
+	/**@brief Return the inverse of this quaternion */
 	btQuaternion inverse() const
 	{
@@ -253,4 +262,16 @@
 	}
 
+	/**@todo document this and it's use */
+	SIMD_FORCE_INLINE btQuaternion nearest( const btQuaternion& qd) const 
+	{
+		btQuaternion diff,sum;
+		diff = *this - qd;
+		sum = *this + qd;
+		if( diff.dot(diff) < sum.dot(sum) )
+			return qd;
+		return (-qd);
+	}
+
+
   /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion
    * @param q The other quaternion to interpolate with 
@@ -265,8 +286,15 @@
 			btScalar s0 = btSin((btScalar(1.0) - t) * theta);
 			btScalar s1 = btSin(t * theta);   
-			return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d,
-				(m_floats[1] * s0 + q.y() * s1) * d,
-				(m_floats[2] * s0 + q.z() * s1) * d,
-				(m_floats[3] * s0 + q.m_floats[3] * s1) * d);
+                        if (dot(q) < 0) // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp
+                          return btQuaternion((m_floats[0] * s0 + -q.x() * s1) * d,
+                                              (m_floats[1] * s0 + -q.y() * s1) * d,
+                                              (m_floats[2] * s0 + -q.z() * s1) * d,
+                                              (m_floats[3] * s0 + -q.m_floats[3] * s1) * d);
+                        else
+                          return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d,
+                                              (m_floats[1] * s0 + q.y() * s1) * d,
+                                              (m_floats[2] * s0 + q.z() * s1) * d,
+                                              (m_floats[3] * s0 + q.m_floats[3] * s1) * d);
+                        
 		}
 		else
@@ -379,5 +407,9 @@
 
 	if (d < -1.0 + SIMD_EPSILON)
-		return btQuaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector
+	{
+		btVector3 n,unused;
+		btPlaneSpace1(v0,n,unused);
+		return btQuaternion(n.x(),n.y(),n.z(),0.0f); // just pick any vector that is orthogonal to v0
+	}
 
 	btScalar  s = btSqrt((1.0f + d) * 2.0f);
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btQuickprof.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btQuickprof.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btQuickprof.cpp	(revision 8284)
@@ -1,5 +1,5 @@
 /*
 
-/***************************************************************************************************
+***************************************************************************************************
 **
 ** profile.cpp
@@ -14,10 +14,229 @@
 // Ogre (www.ogre3d.org).
 
-#include "LinearMath/btQuickprof.h"
-
-
-#ifdef USE_BT_CLOCK
+#include "btQuickprof.h"
+
+#ifndef BT_NO_PROFILE
+
 
 static btClock gProfileClock;
+
+
+#ifdef __CELLOS_LV2__
+#include <sys/sys_time.h>
+#include <sys/time_util.h>
+#include <stdio.h>
+#endif
+
+#if defined (SUNOS) || defined (__SUNOS__) 
+#include <stdio.h> 
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+
+#define BT_USE_WINDOWS_TIMERS
+#define WIN32_LEAN_AND_MEAN
+#define NOWINRES
+#define NOMCX
+#define NOIME 
+
+#ifdef _XBOX
+	#include <Xtl.h>
+#else //_XBOX
+	#include <windows.h>
+#endif //_XBOX
+
+#include <time.h>
+
+
+#else //_WIN32
+#include <sys/time.h>
+#endif //_WIN32
+
+#define mymin(a,b) (a > b ? a : b)
+
+struct btClockData
+{
+
+#ifdef BT_USE_WINDOWS_TIMERS
+	LARGE_INTEGER mClockFrequency;
+	DWORD mStartTick;
+	LONGLONG mPrevElapsedTime;
+	LARGE_INTEGER mStartTime;
+#else
+#ifdef __CELLOS_LV2__
+	uint64_t	mStartTime;
+#else
+	struct timeval mStartTime;
+#endif
+#endif //__CELLOS_LV2__
+
+};
+
+///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
+btClock::btClock()
+{
+	m_data = new btClockData;
+#ifdef BT_USE_WINDOWS_TIMERS
+	QueryPerformanceFrequency(&m_data->mClockFrequency);
+#endif
+	reset();
+}
+
+btClock::~btClock()
+{
+	delete m_data;
+}
+
+btClock::btClock(const btClock& other)
+{
+	m_data = new btClockData;
+	*m_data = *other.m_data;
+}
+
+btClock& btClock::operator=(const btClock& other)
+{
+	*m_data = *other.m_data;
+	return *this;
+}
+
+
+	/// Resets the initial reference time.
+void btClock::reset()
+{
+#ifdef BT_USE_WINDOWS_TIMERS
+	QueryPerformanceCounter(&m_data->mStartTime);
+	m_data->mStartTick = GetTickCount();
+	m_data->mPrevElapsedTime = 0;
+#else
+#ifdef __CELLOS_LV2__
+
+	typedef uint64_t  ClockSize;
+	ClockSize newTime;
+	//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
+	SYS_TIMEBASE_GET( newTime );
+	m_data->mStartTime = newTime;
+#else
+	gettimeofday(&m_data->mStartTime, 0);
+#endif
+#endif
+}
+
+/// Returns the time in ms since the last call to reset or since 
+/// the btClock was created.
+unsigned long int btClock::getTimeMilliseconds()
+{
+#ifdef BT_USE_WINDOWS_TIMERS
+	LARGE_INTEGER currentTime;
+	QueryPerformanceCounter(&currentTime);
+	LONGLONG elapsedTime = currentTime.QuadPart - 
+		m_data->mStartTime.QuadPart;
+		// Compute the number of millisecond ticks elapsed.
+	unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
+		m_data->mClockFrequency.QuadPart);
+		// Check for unexpected leaps in the Win32 performance counter.  
+	// (This is caused by unexpected data across the PCI to ISA 
+		// bridge, aka south bridge.  See Microsoft KB274323.)
+		unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick;
+		signed long msecOff = (signed long)(msecTicks - elapsedTicks);
+		if (msecOff < -100 || msecOff > 100)
+		{
+			// Adjust the starting time forwards.
+			LONGLONG msecAdjustment = mymin(msecOff * 
+				m_data->mClockFrequency.QuadPart / 1000, elapsedTime - 
+				m_data->mPrevElapsedTime);
+			m_data->mStartTime.QuadPart += msecAdjustment;
+			elapsedTime -= msecAdjustment;
+
+			// Recompute the number of millisecond ticks elapsed.
+			msecTicks = (unsigned long)(1000 * elapsedTime / 
+				m_data->mClockFrequency.QuadPart);
+		}
+
+		// Store the current elapsed time for adjustments next time.
+		m_data->mPrevElapsedTime = elapsedTime;
+
+		return msecTicks;
+#else
+
+#ifdef __CELLOS_LV2__
+		uint64_t freq=sys_time_get_timebase_frequency();
+		double dFreq=((double) freq) / 1000.0;
+		typedef uint64_t  ClockSize;
+		ClockSize newTime;
+		SYS_TIMEBASE_GET( newTime );
+		//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
+
+		return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
+#else
+
+		struct timeval currentTime;
+		gettimeofday(&currentTime, 0);
+		return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + 
+			(currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000;
+#endif //__CELLOS_LV2__
+#endif
+}
+
+	/// Returns the time in us since the last call to reset or since 
+	/// the Clock was created.
+unsigned long int btClock::getTimeMicroseconds()
+{
+#ifdef BT_USE_WINDOWS_TIMERS
+		LARGE_INTEGER currentTime;
+		QueryPerformanceCounter(&currentTime);
+		LONGLONG elapsedTime = currentTime.QuadPart - 
+			m_data->mStartTime.QuadPart;
+
+		// Compute the number of millisecond ticks elapsed.
+		unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
+			m_data->mClockFrequency.QuadPart);
+
+		// Check for unexpected leaps in the Win32 performance counter.  
+		// (This is caused by unexpected data across the PCI to ISA 
+		// bridge, aka south bridge.  See Microsoft KB274323.)
+		unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick;
+		signed long msecOff = (signed long)(msecTicks - elapsedTicks);
+		if (msecOff < -100 || msecOff > 100)
+		{
+			// Adjust the starting time forwards.
+			LONGLONG msecAdjustment = mymin(msecOff * 
+				m_data->mClockFrequency.QuadPart / 1000, elapsedTime - 
+				m_data->mPrevElapsedTime);
+			m_data->mStartTime.QuadPart += msecAdjustment;
+			elapsedTime -= msecAdjustment;
+		}
+
+		// Store the current elapsed time for adjustments next time.
+		m_data->mPrevElapsedTime = elapsedTime;
+
+		// Convert to microseconds.
+		unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / 
+			m_data->mClockFrequency.QuadPart);
+
+		return usecTicks;
+#else
+
+#ifdef __CELLOS_LV2__
+		uint64_t freq=sys_time_get_timebase_frequency();
+		double dFreq=((double) freq)/ 1000000.0;
+		typedef uint64_t  ClockSize;
+		ClockSize newTime;
+		//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
+		SYS_TIMEBASE_GET( newTime );
+
+		return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq);
+#else
+
+		struct timeval currentTime;
+		gettimeofday(&currentTime, 0);
+		return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + 
+			(currentTime.tv_usec - m_data->mStartTime.tv_usec);
+#endif//__CELLOS_LV2__
+#endif 
+}
+
+
+
+
 
 inline void Profile_Get_Ticks(unsigned long int * ticks)
@@ -343,4 +562,4 @@
 
 
-#endif //USE_BT_CLOCK
-
+
+#endif //BT_NO_PROFILE
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btQuickprof.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btQuickprof.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btQuickprof.h	(revision 8284)
@@ -19,7 +19,7 @@
 //#define BT_NO_PROFILE 1
 #ifndef BT_NO_PROFILE
-
+#include <stdio.h>//@todo remove this, backwards compatibility
 #include "btScalar.h"
-#include "LinearMath/btAlignedAllocator.h"
+#include "btAlignedAllocator.h"
 #include <new>
 
@@ -27,37 +27,8 @@
 
 
-//if you don't need btClock, you can comment next line
+
 #define USE_BT_CLOCK 1
 
 #ifdef USE_BT_CLOCK
-#ifdef __CELLOS_LV2__
-#include <sys/sys_time.h>
-#include <sys/time_util.h>
-#include <stdio.h>
-#endif
-
-#if defined (SUNOS) || defined (__SUNOS__) 
-#include <stdio.h> 
-#endif
-
-#if defined(WIN32) || defined(_WIN32)
-
-#define USE_WINDOWS_TIMERS 
-#define WIN32_LEAN_AND_MEAN 
-#define NOWINRES 
-#define NOMCX 
-#define NOIME 
-#ifdef _XBOX
-#include <Xtl.h>
-#else
-#include <windows.h>
-#endif
-#include <time.h>
-
-#else
-#include <sys/time.h>
-#endif
-
-#define mymin(a,b) (a > b ? a : b)
 
 ///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling.
@@ -65,168 +36,23 @@
 {
 public:
-	btClock()
-	{
-#ifdef USE_WINDOWS_TIMERS
-		QueryPerformanceFrequency(&mClockFrequency);
-#endif
-		reset();
-	}
+	btClock();
 
-	~btClock()
-	{
-	}
+	btClock(const btClock& other);
+	btClock& operator=(const btClock& other);
+
+	~btClock();
 
 	/// Resets the initial reference time.
-	void reset()
-	{
-#ifdef USE_WINDOWS_TIMERS
-		QueryPerformanceCounter(&mStartTime);
-		mStartTick = GetTickCount();
-		mPrevElapsedTime = 0;
-#else
-#ifdef __CELLOS_LV2__
-
-		typedef uint64_t  ClockSize;
-		ClockSize newTime;
-		//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
-		SYS_TIMEBASE_GET( newTime );
-		mStartTime = newTime;
-#else
-		gettimeofday(&mStartTime, 0);
-#endif
-
-#endif
-	}
+	void reset();
 
 	/// Returns the time in ms since the last call to reset or since 
 	/// the btClock was created.
-	unsigned long int getTimeMilliseconds()
-	{
-#ifdef USE_WINDOWS_TIMERS
-		LARGE_INTEGER currentTime;
-		QueryPerformanceCounter(&currentTime);
-		LONGLONG elapsedTime = currentTime.QuadPart - 
-			mStartTime.QuadPart;
-
-		// Compute the number of millisecond ticks elapsed.
-		unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
-			mClockFrequency.QuadPart);
-
-		// Check for unexpected leaps in the Win32 performance counter.  
-		// (This is caused by unexpected data across the PCI to ISA 
-		// bridge, aka south bridge.  See Microsoft KB274323.)
-		unsigned long elapsedTicks = GetTickCount() - mStartTick;
-		signed long msecOff = (signed long)(msecTicks - elapsedTicks);
-		if (msecOff < -100 || msecOff > 100)
-		{
-			// Adjust the starting time forwards.
-			LONGLONG msecAdjustment = mymin(msecOff * 
-				mClockFrequency.QuadPart / 1000, elapsedTime - 
-				mPrevElapsedTime);
-			mStartTime.QuadPart += msecAdjustment;
-			elapsedTime -= msecAdjustment;
-
-			// Recompute the number of millisecond ticks elapsed.
-			msecTicks = (unsigned long)(1000 * elapsedTime / 
-				mClockFrequency.QuadPart);
-		}
-
-		// Store the current elapsed time for adjustments next time.
-		mPrevElapsedTime = elapsedTime;
-
-		return msecTicks;
-#else
-
-#ifdef __CELLOS_LV2__
-		uint64_t freq=sys_time_get_timebase_frequency();
-		double dFreq=((double) freq) / 1000.0;
-		typedef uint64_t  ClockSize;
-		ClockSize newTime;
-		SYS_TIMEBASE_GET( newTime );
-		//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
-
-		return (unsigned long int)((double(newTime-mStartTime)) / dFreq);
-#else
-
-		struct timeval currentTime;
-		gettimeofday(&currentTime, 0);
-		return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 + 
-			(currentTime.tv_usec - mStartTime.tv_usec) / 1000;
-#endif //__CELLOS_LV2__
-#endif
-	}
+	unsigned long int getTimeMilliseconds();
 
 	/// Returns the time in us since the last call to reset or since 
 	/// the Clock was created.
-	unsigned long int getTimeMicroseconds()
-	{
-#ifdef USE_WINDOWS_TIMERS
-		LARGE_INTEGER currentTime;
-		QueryPerformanceCounter(&currentTime);
-		LONGLONG elapsedTime = currentTime.QuadPart - 
-			mStartTime.QuadPart;
-
-		// Compute the number of millisecond ticks elapsed.
-		unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / 
-			mClockFrequency.QuadPart);
-
-		// Check for unexpected leaps in the Win32 performance counter.  
-		// (This is caused by unexpected data across the PCI to ISA 
-		// bridge, aka south bridge.  See Microsoft KB274323.)
-		unsigned long elapsedTicks = GetTickCount() - mStartTick;
-		signed long msecOff = (signed long)(msecTicks - elapsedTicks);
-		if (msecOff < -100 || msecOff > 100)
-		{
-			// Adjust the starting time forwards.
-			LONGLONG msecAdjustment = mymin(msecOff * 
-				mClockFrequency.QuadPart / 1000, elapsedTime - 
-				mPrevElapsedTime);
-			mStartTime.QuadPart += msecAdjustment;
-			elapsedTime -= msecAdjustment;
-		}
-
-		// Store the current elapsed time for adjustments next time.
-		mPrevElapsedTime = elapsedTime;
-
-		// Convert to microseconds.
-		unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / 
-			mClockFrequency.QuadPart);
-
-		return usecTicks;
-#else
-
-#ifdef __CELLOS_LV2__
-		uint64_t freq=sys_time_get_timebase_frequency();
-		double dFreq=((double) freq)/ 1000000.0;
-		typedef uint64_t  ClockSize;
-		ClockSize newTime;
-		//__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
-		SYS_TIMEBASE_GET( newTime );
-
-		return (unsigned long int)((double(newTime-mStartTime)) / dFreq);
-#else
-
-		struct timeval currentTime;
-		gettimeofday(&currentTime, 0);
-		return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 + 
-			(currentTime.tv_usec - mStartTime.tv_usec);
-#endif//__CELLOS_LV2__
-#endif 
-	}
-
+	unsigned long int getTimeMicroseconds();
 private:
-#ifdef USE_WINDOWS_TIMERS
-	LARGE_INTEGER mClockFrequency;
-	DWORD mStartTick;
-	LONGLONG mPrevElapsedTime;
-	LARGE_INTEGER mStartTime;
-#else
-#ifdef __CELLOS_LV2__
-	uint64_t	mStartTime;
-#else
-	struct timeval mStartTime;
-#endif
-#endif //__CELLOS_LV2__
-
+	struct btClockData* m_data;
 };
 
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btScalar.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btScalar.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btScalar.h	(revision 8284)
@@ -1,4 +1,4 @@
 /*
-Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2009 Erwin Coumans  http://bullet.googlecode.com
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -18,13 +18,18 @@
 #define SIMD___SCALAR_H
 
+#ifdef BT_MANAGED_CODE
+//Aligned data types not supported in managed code
+#pragma unmanaged
+#endif
+
+
 #include <math.h>
-
 #include <stdlib.h>//size_t for MSVC 6.0
-
 #include <cstdlib>
 #include <cfloat>
 #include <float.h>
 
-#define BT_BULLET_VERSION 274
+/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
+#define BT_BULLET_VERSION 277
 
 inline int	btGetVersion()
@@ -38,5 +43,5 @@
 
 
-#ifdef WIN32
+#ifdef _WIN32
 
 		#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
@@ -44,4 +49,5 @@
 			#define SIMD_FORCE_INLINE inline
 			#define ATTRIBUTE_ALIGNED16(a) a
+			#define ATTRIBUTE_ALIGNED64(a) a
 			#define ATTRIBUTE_ALIGNED128(a) a
 		#else
@@ -54,4 +60,5 @@
 			#define SIMD_FORCE_INLINE __forceinline
 			#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
+			#define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a
 			#define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
 		#ifdef _XBOX
@@ -63,5 +70,5 @@
 		#else
 
-#if (defined (WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
+#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
 			#define BT_USE_SSE
 			#include <emmintrin.h>
@@ -87,6 +94,36 @@
 	
 #if defined	(__CELLOS_LV2__)
-		#define SIMD_FORCE_INLINE inline
+		#define SIMD_FORCE_INLINE inline __attribute__((always_inline))
 		#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
+		#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
+		#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
+		#ifndef assert
+		#include <assert.h>
+		#endif
+#ifdef BT_DEBUG
+#ifdef __SPU__
+#include <spu_printf.h>
+#define printf spu_printf
+	#define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
+#else
+	#define btAssert assert
+#endif
+	
+#else
+		#define btAssert(x)
+#endif
+		//btFullAssert is optional, slows down a lot
+		#define btFullAssert(x)
+
+		#define btLikely(_c)  _c
+		#define btUnlikely(_c) _c
+
+#else
+
+#ifdef USE_LIBSPE2
+
+		#define SIMD_FORCE_INLINE __inline
+		#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
+		#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
 		#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
 		#ifndef assert
@@ -101,25 +138,4 @@
 		#define btFullAssert(x)
 
-		#define btLikely(_c)  _c
-		#define btUnlikely(_c) _c
-
-#else
-
-#ifdef USE_LIBSPE2
-
-		#define SIMD_FORCE_INLINE __inline
-		#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
-		#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
-		#ifndef assert
-		#include <assert.h>
-		#endif
-#ifdef BT_DEBUG
-		#define btAssert assert
-#else
-		#define btAssert(x)
-#endif
-		//btFullAssert is optional, slows down a lot
-		#define btFullAssert(x)
-
 
 		#define btLikely(_c)   __builtin_expect((_c), 1)
@@ -130,9 +146,37 @@
 	//non-windows systems
 
+#if (defined (__APPLE__) && defined (__i386__) && (!defined (BT_USE_DOUBLE_PRECISION)))
+	#define BT_USE_SSE
+	#include <emmintrin.h>
+
+	#define SIMD_FORCE_INLINE inline
+///@todo: check out alignment methods for other platforms/compilers
+	#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
+	#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
+	#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
+	#ifndef assert
+	#include <assert.h>
+	#endif
+
+	#if defined(DEBUG) || defined (_DEBUG)
+		#define btAssert assert
+	#else
+		#define btAssert(x)
+	#endif
+
+	//btFullAssert is optional, slows down a lot
+	#define btFullAssert(x)
+	#define btLikely(_c)  _c
+	#define btUnlikely(_c) _c
+
+#else
+
 		#define SIMD_FORCE_INLINE inline
 		///@todo: check out alignment methods for other platforms/compilers
 		///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
+		///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
 		///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
 		#define ATTRIBUTE_ALIGNED16(a) a
+		#define ATTRIBUTE_ALIGNED64(a) a
 		#define ATTRIBUTE_ALIGNED128(a) a
 		#ifndef assert
@@ -150,5 +194,5 @@
 		#define btLikely(_c)  _c
 		#define btUnlikely(_c) _c
-
+#endif //__APPLE__ 
 
 #endif // LIBSPE2
@@ -157,18 +201,14 @@
 #endif
 
-/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc.
-/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor)
-#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__))
-//use slow double float precision operation on those platforms
-#ifndef BT_USE_DOUBLE_PRECISION
-#define BT_FORCE_DOUBLE_FUNCTIONS
-#endif
-#endif
 
 ///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision.
 #if defined(BT_USE_DOUBLE_PRECISION)
 typedef double btScalar;
+//this number could be bigger in double precision
+#define BT_LARGE_FLOAT 1e30
 #else
 typedef float btScalar;
+//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX
+#define BT_LARGE_FLOAT 1e18f
 #endif
 
@@ -194,6 +234,6 @@
 SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
-SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acos(x); }
-SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asin(x); }
+SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { if (x<btScalar(-1))	x=btScalar(-1); if (x>btScalar(1))	x=btScalar(1); return acos(x); }
+SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { if (x<btScalar(-1))	x=btScalar(-1); if (x>btScalar(1))	x=btScalar(1); return asin(x); }
 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
@@ -201,4 +241,5 @@
 SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
 SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
+SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); }
 
 #else
@@ -213,5 +254,5 @@
 	*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
 	x =  tempf;
-	z =  y*btScalar(0.5);                        /* hoist out the /2    */
+	z =  y*btScalar(0.5);
 	x = (btScalar(1.5)*x)-(x*x)*(x*z);         /* iteration formula     */
 	x = (btScalar(1.5)*x)-(x*x)*(x*z);
@@ -229,8 +270,17 @@
 SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
 SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 
-	btAssert(x <= btScalar(1.));
+	if (x<btScalar(-1))	
+		x=btScalar(-1); 
+	if (x>btScalar(1))	
+		x=btScalar(1);
 	return acosf(x); 
 }
-SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); }
+SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { 
+	if (x<btScalar(-1))	
+		x=btScalar(-1); 
+	if (x>btScalar(1))	
+		x=btScalar(1);
+	return asinf(x); 
+}
 SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
 SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
@@ -242,4 +292,5 @@
   SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
   #endif
+SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); }
 	
 #endif
@@ -250,4 +301,8 @@
 #define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
 #define SIMD_DEGS_PER_RAD  (btScalar(360.0) / SIMD_2_PI)
+#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
+
+#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x))))		/* reciprocal square root */
+
 
 #ifdef BT_USE_DOUBLE_PRECISION
@@ -440,4 +495,34 @@
 }
 
-
+// returns normalized value in range [-SIMD_PI, SIMD_PI]
+SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians) 
+{
+	angleInRadians = btFmod(angleInRadians, SIMD_2_PI);
+	if(angleInRadians < -SIMD_PI)
+	{
+		return angleInRadians + SIMD_2_PI;
+	}
+	else if(angleInRadians > SIMD_PI)
+	{
+		return angleInRadians - SIMD_2_PI;
+	}
+	else
+	{
+		return angleInRadians;
+	}
+}
+
+///rudimentary class to provide type info
+struct btTypedObject
+{
+	btTypedObject(int objectType)
+		:m_objectType(objectType)
+	{
+	}
+	int	m_objectType;
+	inline int getObjectType() const
+	{
+		return m_objectType;
+	}
+};
 #endif //SIMD___SCALAR_H
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btSerializer.cpp
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btSerializer.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btSerializer.cpp	(revision 8284)
@@ -0,0 +1,577 @@
+unsigned char sBulletDNAstr64[]= {
+83,68,78,65,78,65,77,69,-79,0,0,0,109,95,115,105,122,101,0,109,
+95,99,97,112,97,99,105,116,121,0,42,109,95,100,97,116,97,0,109,95,
+99,111,108,108,105,115,105,111,110,83,104,97,112,101,115,0,109,95,99,111,
+108,108,105,115,105,111,110,79,98,106,101,99,116,115,0,109,95,99,111,110,
+115,116,114,97,105,110,116,115,0,42,102,105,114,115,116,0,42,108,97,115,
+116,0,109,95,102,108,111,97,116,115,91,52,93,0,109,95,101,108,91,51,
+93,0,109,95,98,97,115,105,115,0,109,95,111,114,105,103,105,110,0,109,
+95,114,111,111,116,78,111,100,101,73,110,100,101,120,0,109,95,115,117,98,
+116,114,101,101,83,105,122,101,0,109,95,113,117,97,110,116,105,122,101,100,
+65,97,98,98,77,105,110,91,51,93,0,109,95,113,117,97,110,116,105,122,
+101,100,65,97,98,98,77,97,120,91,51,93,0,109,95,97,97,98,98,77,
+105,110,79,114,103,0,109,95,97,97,98,98,77,97,120,79,114,103,0,109,
+95,101,115,99,97,112,101,73,110,100,101,120,0,109,95,115,117,98,80,97,
+114,116,0,109,95,116,114,105,97,110,103,108,101,73,110,100,101,120,0,109,
+95,112,97,100,91,52,93,0,109,95,101,115,99,97,112,101,73,110,100,101,
+120,79,114,84,114,105,97,110,103,108,101,73,110,100,101,120,0,109,95,98,
+118,104,65,97,98,98,77,105,110,0,109,95,98,118,104,65,97,98,98,77,
+97,120,0,109,95,98,118,104,81,117,97,110,116,105,122,97,116,105,111,110,
+0,109,95,99,117,114,78,111,100,101,73,110,100,101,120,0,109,95,117,115,
+101,81,117,97,110,116,105,122,97,116,105,111,110,0,109,95,110,117,109,67,
+111,110,116,105,103,117,111,117,115,76,101,97,102,78,111,100,101,115,0,109,
+95,110,117,109,81,117,97,110,116,105,122,101,100,67,111,110,116,105,103,117,
+111,117,115,78,111,100,101,115,0,42,109,95,99,111,110,116,105,103,117,111,
+117,115,78,111,100,101,115,80,116,114,0,42,109,95,113,117,97,110,116,105,
+122,101,100,67,111,110,116,105,103,117,111,117,115,78,111,100,101,115,80,116,
+114,0,42,109,95,115,117,98,84,114,101,101,73,110,102,111,80,116,114,0,
+109,95,116,114,97,118,101,114,115,97,108,77,111,100,101,0,109,95,110,117,
+109,83,117,98,116,114,101,101,72,101,97,100,101,114,115,0,42,109,95,110,
+97,109,101,0,109,95,115,104,97,112,101,84,121,112,101,0,109,95,112,97,
+100,100,105,110,103,91,52,93,0,109,95,99,111,108,108,105,115,105,111,110,
+83,104,97,112,101,68,97,116,97,0,109,95,108,111,99,97,108,83,99,97,
+108,105,110,103,0,109,95,112,108,97,110,101,78,111,114,109,97,108,0,109,
+95,112,108,97,110,101,67,111,110,115,116,97,110,116,0,109,95,105,109,112,
+108,105,99,105,116,83,104,97,112,101,68,105,109,101,110,115,105,111,110,115,
+0,109,95,99,111,108,108,105,115,105,111,110,77,97,114,103,105,110,0,109,
+95,112,97,100,100,105,110,103,0,109,95,112,111,115,0,109,95,114,97,100,
+105,117,115,0,109,95,99,111,110,118,101,120,73,110,116,101,114,110,97,108,
+83,104,97,112,101,68,97,116,97,0,42,109,95,108,111,99,97,108,80,111,
+115,105,116,105,111,110,65,114,114,97,121,80,116,114,0,109,95,108,111,99,
+97,108,80,111,115,105,116,105,111,110,65,114,114,97,121,83,105,122,101,0,
+109,95,118,97,108,117,101,0,109,95,112,97,100,91,50,93,0,109,95,118,
+97,108,117,101,115,91,51,93,0,42,109,95,118,101,114,116,105,99,101,115,
+51,102,0,42,109,95,118,101,114,116,105,99,101,115,51,100,0,42,109,95,
+105,110,100,105,99,101,115,51,50,0,42,109,95,51,105,110,100,105,99,101,
+115,49,54,0,42,109,95,105,110,100,105,99,101,115,49,54,0,109,95,110,
+117,109,84,114,105,97,110,103,108,101,115,0,109,95,110,117,109,86,101,114,
+116,105,99,101,115,0,42,109,95,109,101,115,104,80,97,114,116,115,80,116,
+114,0,109,95,115,99,97,108,105,110,103,0,109,95,110,117,109,77,101,115,
+104,80,97,114,116,115,0,109,95,109,101,115,104,73,110,116,101,114,102,97,
+99,101,0,42,109,95,113,117,97,110,116,105,122,101,100,70,108,111,97,116,
+66,118,104,0,42,109,95,113,117,97,110,116,105,122,101,100,68,111,117,98,
+108,101,66,118,104,0,42,109,95,116,114,105,97,110,103,108,101,73,110,102,
+111,77,97,112,0,109,95,112,97,100,51,91,52,93,0,109,95,116,114,97,
+110,115,102,111,114,109,0,42,109,95,99,104,105,108,100,83,104,97,112,101,
+0,109,95,99,104,105,108,100,83,104,97,112,101,84,121,112,101,0,109,95,
+99,104,105,108,100,77,97,114,103,105,110,0,42,109,95,99,104,105,108,100,
+83,104,97,112,101,80,116,114,0,109,95,110,117,109,67,104,105,108,100,83,
+104,97,112,101,115,0,109,95,117,112,65,120,105,115,0,109,95,102,108,97,
+103,115,0,109,95,101,100,103,101,86,48,86,49,65,110,103,108,101,0,109,
+95,101,100,103,101,86,49,86,50,65,110,103,108,101,0,109,95,101,100,103,
+101,86,50,86,48,65,110,103,108,101,0,42,109,95,104,97,115,104,84,97,
+98,108,101,80,116,114,0,42,109,95,110,101,120,116,80,116,114,0,42,109,
+95,118,97,108,117,101,65,114,114,97,121,80,116,114,0,42,109,95,107,101,
+121,65,114,114,97,121,80,116,114,0,109,95,99,111,110,118,101,120,69,112,
+115,105,108,111,110,0,109,95,112,108,97,110,97,114,69,112,115,105,108,111,
+110,0,109,95,101,113,117,97,108,86,101,114,116,101,120,84,104,114,101,115,
+104,111,108,100,0,109,95,101,100,103,101,68,105,115,116,97,110,99,101,84,
+104,114,101,115,104,111,108,100,0,109,95,122,101,114,111,65,114,101,97,84,
+104,114,101,115,104,111,108,100,0,109,95,110,101,120,116,83,105,122,101,0,
+109,95,104,97,115,104,84,97,98,108,101,83,105,122,101,0,109,95,110,117,
+109,86,97,108,117,101,115,0,109,95,110,117,109,75,101,121,115,0,109,95,
+103,105,109,112,97,99,116,83,117,98,84,121,112,101,0,42,109,95,117,110,
+115,99,97,108,101,100,80,111,105,110,116,115,70,108,111,97,116,80,116,114,
+0,42,109,95,117,110,115,99,97,108,101,100,80,111,105,110,116,115,68,111,
+117,98,108,101,80,116,114,0,109,95,110,117,109,85,110,115,99,97,108,101,
+100,80,111,105,110,116,115,0,109,95,112,97,100,100,105,110,103,51,91,52,
+93,0,42,109,95,98,114,111,97,100,112,104,97,115,101,72,97,110,100,108,
+101,0,42,109,95,99,111,108,108,105,115,105,111,110,83,104,97,112,101,0,
+42,109,95,114,111,111,116,67,111,108,108,105,115,105,111,110,83,104,97,112,
+101,0,109,95,119,111,114,108,100,84,114,97,110,115,102,111,114,109,0,109,
+95,105,110,116,101,114,112,111,108,97,116,105,111,110,87,111,114,108,100,84,
+114,97,110,115,102,111,114,109,0,109,95,105,110,116,101,114,112,111,108,97,
+116,105,111,110,76,105,110,101,97,114,86,101,108,111,99,105,116,121,0,109,
+95,105,110,116,101,114,112,111,108,97,116,105,111,110,65,110,103,117,108,97,
+114,86,101,108,111,99,105,116,121,0,109,95,97,110,105,115,111,116,114,111,
+112,105,99,70,114,105,99,116,105,111,110,0,109,95,99,111,110,116,97,99,
+116,80,114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,
+0,109,95,100,101,97,99,116,105,118,97,116,105,111,110,84,105,109,101,0,
+109,95,102,114,105,99,116,105,111,110,0,109,95,114,101,115,116,105,116,117,
+116,105,111,110,0,109,95,104,105,116,70,114,97,99,116,105,111,110,0,109,
+95,99,99,100,83,119,101,112,116,83,112,104,101,114,101,82,97,100,105,117,
+115,0,109,95,99,99,100,77,111,116,105,111,110,84,104,114,101,115,104,111,
+108,100,0,109,95,104,97,115,65,110,105,115,111,116,114,111,112,105,99,70,
+114,105,99,116,105,111,110,0,109,95,99,111,108,108,105,115,105,111,110,70,
+108,97,103,115,0,109,95,105,115,108,97,110,100,84,97,103,49,0,109,95,
+99,111,109,112,97,110,105,111,110,73,100,0,109,95,97,99,116,105,118,97,
+116,105,111,110,83,116,97,116,101,49,0,109,95,105,110,116,101,114,110,97,
+108,84,121,112,101,0,109,95,99,104,101,99,107,67,111,108,108,105,100,101,
+87,105,116,104,0,109,95,99,111,108,108,105,115,105,111,110,79,98,106,101,
+99,116,68,97,116,97,0,109,95,105,110,118,73,110,101,114,116,105,97,84,
+101,110,115,111,114,87,111,114,108,100,0,109,95,108,105,110,101,97,114,86,
+101,108,111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,86,101,108,
+111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,70,97,99,116,111,
+114,0,109,95,108,105,110,101,97,114,70,97,99,116,111,114,0,109,95,103,
+114,97,118,105,116,121,0,109,95,103,114,97,118,105,116,121,95,97,99,99,
+101,108,101,114,97,116,105,111,110,0,109,95,105,110,118,73,110,101,114,116,
+105,97,76,111,99,97,108,0,109,95,116,111,116,97,108,70,111,114,99,101,
+0,109,95,116,111,116,97,108,84,111,114,113,117,101,0,109,95,105,110,118,
+101,114,115,101,77,97,115,115,0,109,95,108,105,110,101,97,114,68,97,109,
+112,105,110,103,0,109,95,97,110,103,117,108,97,114,68,97,109,112,105,110,
+103,0,109,95,97,100,100,105,116,105,111,110,97,108,68,97,109,112,105,110,
+103,70,97,99,116,111,114,0,109,95,97,100,100,105,116,105,111,110,97,108,
+76,105,110,101,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,
+108,100,83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,
+103,117,108,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,108,
+100,83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,103,
+117,108,97,114,68,97,109,112,105,110,103,70,97,99,116,111,114,0,109,95,
+108,105,110,101,97,114,83,108,101,101,112,105,110,103,84,104,114,101,115,104,
+111,108,100,0,109,95,97,110,103,117,108,97,114,83,108,101,101,112,105,110,
+103,84,104,114,101,115,104,111,108,100,0,109,95,97,100,100,105,116,105,111,
+110,97,108,68,97,109,112,105,110,103,0,109,95,110,117,109,67,111,110,115,
+116,114,97,105,110,116,82,111,119,115,0,110,117,98,0,42,109,95,114,98,
+65,0,42,109,95,114,98,66,0,109,95,111,98,106,101,99,116,84,121,112,
+101,0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,84,121,
+112,101,0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,73,
+100,0,109,95,110,101,101,100,115,70,101,101,100,98,97,99,107,0,109,95,
+97,112,112,108,105,101,100,73,109,112,117,108,115,101,0,109,95,100,98,103,
+68,114,97,119,83,105,122,101,0,109,95,100,105,115,97,98,108,101,67,111,
+108,108,105,115,105,111,110,115,66,101,116,119,101,101,110,76,105,110,107,101,
+100,66,111,100,105,101,115,0,109,95,112,97,100,52,91,52,93,0,109,95,
+116,121,112,101,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,109,
+95,112,105,118,111,116,73,110,65,0,109,95,112,105,118,111,116,73,110,66,
+0,109,95,114,98,65,70,114,97,109,101,0,109,95,114,98,66,70,114,97,
+109,101,0,109,95,117,115,101,82,101,102,101,114,101,110,99,101,70,114,97,
+109,101,65,0,109,95,97,110,103,117,108,97,114,79,110,108,121,0,109,95,
+101,110,97,98,108,101,65,110,103,117,108,97,114,77,111,116,111,114,0,109,
+95,109,111,116,111,114,84,97,114,103,101,116,86,101,108,111,99,105,116,121,
+0,109,95,109,97,120,77,111,116,111,114,73,109,112,117,108,115,101,0,109,
+95,108,111,119,101,114,76,105,109,105,116,0,109,95,117,112,112,101,114,76,
+105,109,105,116,0,109,95,108,105,109,105,116,83,111,102,116,110,101,115,115,
+0,109,95,98,105,97,115,70,97,99,116,111,114,0,109,95,114,101,108,97,
+120,97,116,105,111,110,70,97,99,116,111,114,0,109,95,115,119,105,110,103,
+83,112,97,110,49,0,109,95,115,119,105,110,103,83,112,97,110,50,0,109,
+95,116,119,105,115,116,83,112,97,110,0,109,95,100,97,109,112,105,110,103,
+0,109,95,108,105,110,101,97,114,85,112,112,101,114,76,105,109,105,116,0,
+109,95,108,105,110,101,97,114,76,111,119,101,114,76,105,109,105,116,0,109,
+95,97,110,103,117,108,97,114,85,112,112,101,114,76,105,109,105,116,0,109,
+95,97,110,103,117,108,97,114,76,111,119,101,114,76,105,109,105,116,0,109,
+95,117,115,101,76,105,110,101,97,114,82,101,102,101,114,101,110,99,101,70,
+114,97,109,101,65,0,109,95,117,115,101,79,102,102,115,101,116,70,111,114,
+67,111,110,115,116,114,97,105,110,116,70,114,97,109,101,0,84,89,80,69,
+58,0,0,0,99,104,97,114,0,117,99,104,97,114,0,115,104,111,114,116,
+0,117,115,104,111,114,116,0,105,110,116,0,108,111,110,103,0,117,108,111,
+110,103,0,102,108,111,97,116,0,100,111,117,98,108,101,0,118,111,105,100,
+0,80,111,105,110,116,101,114,65,114,114,97,121,0,98,116,80,104,121,115,
+105,99,115,83,121,115,116,101,109,0,76,105,115,116,66,97,115,101,0,98,
+116,86,101,99,116,111,114,51,70,108,111,97,116,68,97,116,97,0,98,116,
+86,101,99,116,111,114,51,68,111,117,98,108,101,68,97,116,97,0,98,116,
+77,97,116,114,105,120,51,120,51,70,108,111,97,116,68,97,116,97,0,98,
+116,77,97,116,114,105,120,51,120,51,68,111,117,98,108,101,68,97,116,97,
+0,98,116,84,114,97,110,115,102,111,114,109,70,108,111,97,116,68,97,116,
+97,0,98,116,84,114,97,110,115,102,111,114,109,68,111,117,98,108,101,68,
+97,116,97,0,98,116,66,118,104,83,117,98,116,114,101,101,73,110,102,111,
+68,97,116,97,0,98,116,79,112,116,105,109,105,122,101,100,66,118,104,78,
+111,100,101,70,108,111,97,116,68,97,116,97,0,98,116,79,112,116,105,109,
+105,122,101,100,66,118,104,78,111,100,101,68,111,117,98,108,101,68,97,116,
+97,0,98,116,81,117,97,110,116,105,122,101,100,66,118,104,78,111,100,101,
+68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,100,66,118,104,70,
+108,111,97,116,68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,100,
+66,118,104,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,108,
+105,115,105,111,110,83,104,97,112,101,68,97,116,97,0,98,116,83,116,97,
+116,105,99,80,108,97,110,101,83,104,97,112,101,68,97,116,97,0,98,116,
+67,111,110,118,101,120,73,110,116,101,114,110,97,108,83,104,97,112,101,68,
+97,116,97,0,98,116,80,111,115,105,116,105,111,110,65,110,100,82,97,100,
+105,117,115,0,98,116,77,117,108,116,105,83,112,104,101,114,101,83,104,97,
+112,101,68,97,116,97,0,98,116,73,110,116,73,110,100,101,120,68,97,116,
+97,0,98,116,83,104,111,114,116,73,110,116,73,110,100,101,120,68,97,116,
+97,0,98,116,83,104,111,114,116,73,110,116,73,110,100,101,120,84,114,105,
+112,108,101,116,68,97,116,97,0,98,116,77,101,115,104,80,97,114,116,68,
+97,116,97,0,98,116,83,116,114,105,100,105,110,103,77,101,115,104,73,110,
+116,101,114,102,97,99,101,68,97,116,97,0,98,116,84,114,105,97,110,103,
+108,101,77,101,115,104,83,104,97,112,101,68,97,116,97,0,98,116,84,114,
+105,97,110,103,108,101,73,110,102,111,77,97,112,68,97,116,97,0,98,116,
+67,111,109,112,111,117,110,100,83,104,97,112,101,67,104,105,108,100,68,97,
+116,97,0,98,116,67,111,109,112,111,117,110,100,83,104,97,112,101,68,97,
+116,97,0,98,116,67,121,108,105,110,100,101,114,83,104,97,112,101,68,97,
+116,97,0,98,116,67,97,112,115,117,108,101,83,104,97,112,101,68,97,116,
+97,0,98,116,84,114,105,97,110,103,108,101,73,110,102,111,68,97,116,97,
+0,98,116,71,73,109,112,97,99,116,77,101,115,104,83,104,97,112,101,68,
+97,116,97,0,98,116,67,111,110,118,101,120,72,117,108,108,83,104,97,112,
+101,68,97,116,97,0,98,116,67,111,108,108,105,115,105,111,110,79,98,106,
+101,99,116,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,108,
+105,115,105,111,110,79,98,106,101,99,116,70,108,111,97,116,68,97,116,97,
+0,98,116,82,105,103,105,100,66,111,100,121,70,108,111,97,116,68,97,116,
+97,0,98,116,82,105,103,105,100,66,111,100,121,68,111,117,98,108,101,68,
+97,116,97,0,98,116,67,111,110,115,116,114,97,105,110,116,73,110,102,111,
+49,0,98,116,84,121,112,101,100,67,111,110,115,116,114,97,105,110,116,68,
+97,116,97,0,98,116,82,105,103,105,100,66,111,100,121,68,97,116,97,0,
+98,116,80,111,105,110,116,50,80,111,105,110,116,67,111,110,115,116,114,97,
+105,110,116,70,108,111,97,116,68,97,116,97,0,98,116,80,111,105,110,116,
+50,80,111,105,110,116,67,111,110,115,116,114,97,105,110,116,68,111,117,98,
+108,101,68,97,116,97,0,98,116,72,105,110,103,101,67,111,110,115,116,114,
+97,105,110,116,68,111,117,98,108,101,68,97,116,97,0,98,116,72,105,110,
+103,101,67,111,110,115,116,114,97,105,110,116,70,108,111,97,116,68,97,116,
+97,0,98,116,67,111,110,101,84,119,105,115,116,67,111,110,115,116,114,97,
+105,110,116,68,97,116,97,0,98,116,71,101,110,101,114,105,99,54,68,111,
+102,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,98,116,83,108,
+105,100,101,114,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,0,
+84,76,69,78,1,0,1,0,2,0,2,0,4,0,4,0,4,0,4,0,
+8,0,0,0,16,0,48,0,16,0,16,0,32,0,48,0,96,0,64,0,
+-128,0,20,0,48,0,80,0,16,0,96,0,-112,0,16,0,56,0,56,0,
+20,0,72,0,4,0,4,0,8,0,48,0,32,0,80,0,72,0,80,0,
+32,0,64,0,64,0,16,0,72,0,80,0,-40,1,8,1,-16,1,-88,3,
+8,0,56,0,0,0,88,0,120,0,96,1,-32,0,-40,0,0,1,-48,0,
+83,84,82,67,47,0,0,0,10,0,3,0,4,0,0,0,4,0,1,0,
+9,0,2,0,11,0,3,0,10,0,3,0,10,0,4,0,10,0,5,0,
+12,0,2,0,9,0,6,0,9,0,7,0,13,0,1,0,7,0,8,0,
+14,0,1,0,8,0,8,0,15,0,1,0,13,0,9,0,16,0,1,0,
+14,0,9,0,17,0,2,0,15,0,10,0,13,0,11,0,18,0,2,0,
+16,0,10,0,14,0,11,0,19,0,4,0,4,0,12,0,4,0,13,0,
+2,0,14,0,2,0,15,0,20,0,6,0,13,0,16,0,13,0,17,0,
+4,0,18,0,4,0,19,0,4,0,20,0,0,0,21,0,21,0,6,0,
+14,0,16,0,14,0,17,0,4,0,18,0,4,0,19,0,4,0,20,0,
+0,0,21,0,22,0,3,0,2,0,14,0,2,0,15,0,4,0,22,0,
+23,0,12,0,13,0,23,0,13,0,24,0,13,0,25,0,4,0,26,0,
+4,0,27,0,4,0,28,0,4,0,29,0,20,0,30,0,22,0,31,0,
+19,0,32,0,4,0,33,0,4,0,34,0,24,0,12,0,14,0,23,0,
+14,0,24,0,14,0,25,0,4,0,26,0,4,0,27,0,4,0,28,0,
+4,0,29,0,21,0,30,0,22,0,31,0,4,0,33,0,4,0,34,0,
+19,0,32,0,25,0,3,0,0,0,35,0,4,0,36,0,0,0,37,0,
+26,0,5,0,25,0,38,0,13,0,39,0,13,0,40,0,7,0,41,0,
+0,0,21,0,27,0,5,0,25,0,38,0,13,0,39,0,13,0,42,0,
+7,0,43,0,4,0,44,0,28,0,2,0,13,0,45,0,7,0,46,0,
+29,0,4,0,27,0,47,0,28,0,48,0,4,0,49,0,0,0,37,0,
+30,0,1,0,4,0,50,0,31,0,2,0,2,0,50,0,0,0,51,0,
+32,0,2,0,2,0,52,0,0,0,51,0,33,0,7,0,13,0,53,0,
+14,0,54,0,30,0,55,0,32,0,56,0,31,0,57,0,4,0,58,0,
+4,0,59,0,34,0,4,0,33,0,60,0,13,0,61,0,4,0,62,0,
+0,0,37,0,35,0,7,0,25,0,38,0,34,0,63,0,23,0,64,0,
+24,0,65,0,36,0,66,0,7,0,43,0,0,0,67,0,37,0,4,0,
+17,0,68,0,25,0,69,0,4,0,70,0,7,0,71,0,38,0,4,0,
+25,0,38,0,37,0,72,0,4,0,73,0,7,0,43,0,39,0,3,0,
+27,0,47,0,4,0,74,0,0,0,37,0,40,0,3,0,27,0,47,0,
+4,0,74,0,0,0,37,0,41,0,4,0,4,0,75,0,7,0,76,0,
+7,0,77,0,7,0,78,0,36,0,14,0,4,0,79,0,4,0,80,0,
+41,0,81,0,4,0,82,0,7,0,83,0,7,0,84,0,7,0,85,0,
+7,0,86,0,7,0,87,0,4,0,88,0,4,0,89,0,4,0,90,0,
+4,0,91,0,0,0,37,0,42,0,5,0,25,0,38,0,34,0,63,0,
+13,0,39,0,7,0,43,0,4,0,92,0,43,0,5,0,27,0,47,0,
+13,0,93,0,14,0,94,0,4,0,95,0,0,0,96,0,44,0,24,0,
+9,0,97,0,9,0,98,0,25,0,99,0,0,0,35,0,18,0,100,0,
+18,0,101,0,14,0,102,0,14,0,103,0,14,0,104,0,8,0,105,0,
+8,0,106,0,8,0,107,0,8,0,108,0,8,0,109,0,8,0,110,0,
+8,0,111,0,4,0,112,0,4,0,113,0,4,0,114,0,4,0,115,0,
+4,0,116,0,4,0,117,0,4,0,118,0,0,0,37,0,45,0,23,0,
+9,0,97,0,9,0,98,0,25,0,99,0,0,0,35,0,17,0,100,0,
+17,0,101,0,13,0,102,0,13,0,103,0,13,0,104,0,7,0,105,0,
+7,0,106,0,7,0,107,0,7,0,108,0,7,0,109,0,7,0,110,0,
+7,0,111,0,4,0,112,0,4,0,113,0,4,0,114,0,4,0,115,0,
+4,0,116,0,4,0,117,0,4,0,118,0,46,0,21,0,45,0,119,0,
+15,0,120,0,13,0,121,0,13,0,122,0,13,0,123,0,13,0,124,0,
+13,0,125,0,13,0,126,0,13,0,127,0,13,0,-128,0,13,0,-127,0,
+7,0,-126,0,7,0,-125,0,7,0,-124,0,7,0,-123,0,7,0,-122,0,
+7,0,-121,0,7,0,-120,0,7,0,-119,0,7,0,-118,0,4,0,-117,0,
+47,0,22,0,44,0,119,0,16,0,120,0,14,0,121,0,14,0,122,0,
+14,0,123,0,14,0,124,0,14,0,125,0,14,0,126,0,14,0,127,0,
+14,0,-128,0,14,0,-127,0,8,0,-126,0,8,0,-125,0,8,0,-124,0,
+8,0,-123,0,8,0,-122,0,8,0,-121,0,8,0,-120,0,8,0,-119,0,
+8,0,-118,0,4,0,-117,0,0,0,37,0,48,0,2,0,4,0,-116,0,
+4,0,-115,0,49,0,11,0,50,0,-114,0,50,0,-113,0,0,0,35,0,
+4,0,-112,0,4,0,-111,0,4,0,-110,0,4,0,-109,0,7,0,-108,0,
+7,0,-107,0,4,0,-106,0,0,0,-105,0,51,0,3,0,49,0,-104,0,
+13,0,-103,0,13,0,-102,0,52,0,3,0,49,0,-104,0,14,0,-103,0,
+14,0,-102,0,53,0,13,0,49,0,-104,0,18,0,-101,0,18,0,-100,0,
+4,0,-99,0,4,0,-98,0,4,0,-97,0,7,0,-96,0,7,0,-95,0,
+7,0,-94,0,7,0,-93,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,
+54,0,13,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,4,0,-99,0,
+4,0,-98,0,4,0,-97,0,7,0,-96,0,7,0,-95,0,7,0,-94,0,
+7,0,-93,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,55,0,11,0,
+49,0,-104,0,17,0,-101,0,17,0,-100,0,7,0,-89,0,7,0,-88,0,
+7,0,-87,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,7,0,-86,0,
+0,0,21,0,56,0,9,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,
+13,0,-85,0,13,0,-84,0,13,0,-83,0,13,0,-82,0,4,0,-81,0,
+4,0,-80,0,57,0,9,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,
+7,0,-85,0,7,0,-84,0,7,0,-83,0,7,0,-82,0,4,0,-81,0,
+4,0,-80,0,};
+int sBulletDNAlen64= sizeof(sBulletDNAstr64);
+
+unsigned char sBulletDNAstr[]= {
+83,68,78,65,78,65,77,69,-79,0,0,0,109,95,115,105,122,101,0,109,
+95,99,97,112,97,99,105,116,121,0,42,109,95,100,97,116,97,0,109,95,
+99,111,108,108,105,115,105,111,110,83,104,97,112,101,115,0,109,95,99,111,
+108,108,105,115,105,111,110,79,98,106,101,99,116,115,0,109,95,99,111,110,
+115,116,114,97,105,110,116,115,0,42,102,105,114,115,116,0,42,108,97,115,
+116,0,109,95,102,108,111,97,116,115,91,52,93,0,109,95,101,108,91,51,
+93,0,109,95,98,97,115,105,115,0,109,95,111,114,105,103,105,110,0,109,
+95,114,111,111,116,78,111,100,101,73,110,100,101,120,0,109,95,115,117,98,
+116,114,101,101,83,105,122,101,0,109,95,113,117,97,110,116,105,122,101,100,
+65,97,98,98,77,105,110,91,51,93,0,109,95,113,117,97,110,116,105,122,
+101,100,65,97,98,98,77,97,120,91,51,93,0,109,95,97,97,98,98,77,
+105,110,79,114,103,0,109,95,97,97,98,98,77,97,120,79,114,103,0,109,
+95,101,115,99,97,112,101,73,110,100,101,120,0,109,95,115,117,98,80,97,
+114,116,0,109,95,116,114,105,97,110,103,108,101,73,110,100,101,120,0,109,
+95,112,97,100,91,52,93,0,109,95,101,115,99,97,112,101,73,110,100,101,
+120,79,114,84,114,105,97,110,103,108,101,73,110,100,101,120,0,109,95,98,
+118,104,65,97,98,98,77,105,110,0,109,95,98,118,104,65,97,98,98,77,
+97,120,0,109,95,98,118,104,81,117,97,110,116,105,122,97,116,105,111,110,
+0,109,95,99,117,114,78,111,100,101,73,110,100,101,120,0,109,95,117,115,
+101,81,117,97,110,116,105,122,97,116,105,111,110,0,109,95,110,117,109,67,
+111,110,116,105,103,117,111,117,115,76,101,97,102,78,111,100,101,115,0,109,
+95,110,117,109,81,117,97,110,116,105,122,101,100,67,111,110,116,105,103,117,
+111,117,115,78,111,100,101,115,0,42,109,95,99,111,110,116,105,103,117,111,
+117,115,78,111,100,101,115,80,116,114,0,42,109,95,113,117,97,110,116,105,
+122,101,100,67,111,110,116,105,103,117,111,117,115,78,111,100,101,115,80,116,
+114,0,42,109,95,115,117,98,84,114,101,101,73,110,102,111,80,116,114,0,
+109,95,116,114,97,118,101,114,115,97,108,77,111,100,101,0,109,95,110,117,
+109,83,117,98,116,114,101,101,72,101,97,100,101,114,115,0,42,109,95,110,
+97,109,101,0,109,95,115,104,97,112,101,84,121,112,101,0,109,95,112,97,
+100,100,105,110,103,91,52,93,0,109,95,99,111,108,108,105,115,105,111,110,
+83,104,97,112,101,68,97,116,97,0,109,95,108,111,99,97,108,83,99,97,
+108,105,110,103,0,109,95,112,108,97,110,101,78,111,114,109,97,108,0,109,
+95,112,108,97,110,101,67,111,110,115,116,97,110,116,0,109,95,105,109,112,
+108,105,99,105,116,83,104,97,112,101,68,105,109,101,110,115,105,111,110,115,
+0,109,95,99,111,108,108,105,115,105,111,110,77,97,114,103,105,110,0,109,
+95,112,97,100,100,105,110,103,0,109,95,112,111,115,0,109,95,114,97,100,
+105,117,115,0,109,95,99,111,110,118,101,120,73,110,116,101,114,110,97,108,
+83,104,97,112,101,68,97,116,97,0,42,109,95,108,111,99,97,108,80,111,
+115,105,116,105,111,110,65,114,114,97,121,80,116,114,0,109,95,108,111,99,
+97,108,80,111,115,105,116,105,111,110,65,114,114,97,121,83,105,122,101,0,
+109,95,118,97,108,117,101,0,109,95,112,97,100,91,50,93,0,109,95,118,
+97,108,117,101,115,91,51,93,0,42,109,95,118,101,114,116,105,99,101,115,
+51,102,0,42,109,95,118,101,114,116,105,99,101,115,51,100,0,42,109,95,
+105,110,100,105,99,101,115,51,50,0,42,109,95,51,105,110,100,105,99,101,
+115,49,54,0,42,109,95,105,110,100,105,99,101,115,49,54,0,109,95,110,
+117,109,84,114,105,97,110,103,108,101,115,0,109,95,110,117,109,86,101,114,
+116,105,99,101,115,0,42,109,95,109,101,115,104,80,97,114,116,115,80,116,
+114,0,109,95,115,99,97,108,105,110,103,0,109,95,110,117,109,77,101,115,
+104,80,97,114,116,115,0,109,95,109,101,115,104,73,110,116,101,114,102,97,
+99,101,0,42,109,95,113,117,97,110,116,105,122,101,100,70,108,111,97,116,
+66,118,104,0,42,109,95,113,117,97,110,116,105,122,101,100,68,111,117,98,
+108,101,66,118,104,0,42,109,95,116,114,105,97,110,103,108,101,73,110,102,
+111,77,97,112,0,109,95,112,97,100,51,91,52,93,0,109,95,116,114,97,
+110,115,102,111,114,109,0,42,109,95,99,104,105,108,100,83,104,97,112,101,
+0,109,95,99,104,105,108,100,83,104,97,112,101,84,121,112,101,0,109,95,
+99,104,105,108,100,77,97,114,103,105,110,0,42,109,95,99,104,105,108,100,
+83,104,97,112,101,80,116,114,0,109,95,110,117,109,67,104,105,108,100,83,
+104,97,112,101,115,0,109,95,117,112,65,120,105,115,0,109,95,102,108,97,
+103,115,0,109,95,101,100,103,101,86,48,86,49,65,110,103,108,101,0,109,
+95,101,100,103,101,86,49,86,50,65,110,103,108,101,0,109,95,101,100,103,
+101,86,50,86,48,65,110,103,108,101,0,42,109,95,104,97,115,104,84,97,
+98,108,101,80,116,114,0,42,109,95,110,101,120,116,80,116,114,0,42,109,
+95,118,97,108,117,101,65,114,114,97,121,80,116,114,0,42,109,95,107,101,
+121,65,114,114,97,121,80,116,114,0,109,95,99,111,110,118,101,120,69,112,
+115,105,108,111,110,0,109,95,112,108,97,110,97,114,69,112,115,105,108,111,
+110,0,109,95,101,113,117,97,108,86,101,114,116,101,120,84,104,114,101,115,
+104,111,108,100,0,109,95,101,100,103,101,68,105,115,116,97,110,99,101,84,
+104,114,101,115,104,111,108,100,0,109,95,122,101,114,111,65,114,101,97,84,
+104,114,101,115,104,111,108,100,0,109,95,110,101,120,116,83,105,122,101,0,
+109,95,104,97,115,104,84,97,98,108,101,83,105,122,101,0,109,95,110,117,
+109,86,97,108,117,101,115,0,109,95,110,117,109,75,101,121,115,0,109,95,
+103,105,109,112,97,99,116,83,117,98,84,121,112,101,0,42,109,95,117,110,
+115,99,97,108,101,100,80,111,105,110,116,115,70,108,111,97,116,80,116,114,
+0,42,109,95,117,110,115,99,97,108,101,100,80,111,105,110,116,115,68,111,
+117,98,108,101,80,116,114,0,109,95,110,117,109,85,110,115,99,97,108,101,
+100,80,111,105,110,116,115,0,109,95,112,97,100,100,105,110,103,51,91,52,
+93,0,42,109,95,98,114,111,97,100,112,104,97,115,101,72,97,110,100,108,
+101,0,42,109,95,99,111,108,108,105,115,105,111,110,83,104,97,112,101,0,
+42,109,95,114,111,111,116,67,111,108,108,105,115,105,111,110,83,104,97,112,
+101,0,109,95,119,111,114,108,100,84,114,97,110,115,102,111,114,109,0,109,
+95,105,110,116,101,114,112,111,108,97,116,105,111,110,87,111,114,108,100,84,
+114,97,110,115,102,111,114,109,0,109,95,105,110,116,101,114,112,111,108,97,
+116,105,111,110,76,105,110,101,97,114,86,101,108,111,99,105,116,121,0,109,
+95,105,110,116,101,114,112,111,108,97,116,105,111,110,65,110,103,117,108,97,
+114,86,101,108,111,99,105,116,121,0,109,95,97,110,105,115,111,116,114,111,
+112,105,99,70,114,105,99,116,105,111,110,0,109,95,99,111,110,116,97,99,
+116,80,114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,
+0,109,95,100,101,97,99,116,105,118,97,116,105,111,110,84,105,109,101,0,
+109,95,102,114,105,99,116,105,111,110,0,109,95,114,101,115,116,105,116,117,
+116,105,111,110,0,109,95,104,105,116,70,114,97,99,116,105,111,110,0,109,
+95,99,99,100,83,119,101,112,116,83,112,104,101,114,101,82,97,100,105,117,
+115,0,109,95,99,99,100,77,111,116,105,111,110,84,104,114,101,115,104,111,
+108,100,0,109,95,104,97,115,65,110,105,115,111,116,114,111,112,105,99,70,
+114,105,99,116,105,111,110,0,109,95,99,111,108,108,105,115,105,111,110,70,
+108,97,103,115,0,109,95,105,115,108,97,110,100,84,97,103,49,0,109,95,
+99,111,109,112,97,110,105,111,110,73,100,0,109,95,97,99,116,105,118,97,
+116,105,111,110,83,116,97,116,101,49,0,109,95,105,110,116,101,114,110,97,
+108,84,121,112,101,0,109,95,99,104,101,99,107,67,111,108,108,105,100,101,
+87,105,116,104,0,109,95,99,111,108,108,105,115,105,111,110,79,98,106,101,
+99,116,68,97,116,97,0,109,95,105,110,118,73,110,101,114,116,105,97,84,
+101,110,115,111,114,87,111,114,108,100,0,109,95,108,105,110,101,97,114,86,
+101,108,111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,86,101,108,
+111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,70,97,99,116,111,
+114,0,109,95,108,105,110,101,97,114,70,97,99,116,111,114,0,109,95,103,
+114,97,118,105,116,121,0,109,95,103,114,97,118,105,116,121,95,97,99,99,
+101,108,101,114,97,116,105,111,110,0,109,95,105,110,118,73,110,101,114,116,
+105,97,76,111,99,97,108,0,109,95,116,111,116,97,108,70,111,114,99,101,
+0,109,95,116,111,116,97,108,84,111,114,113,117,101,0,109,95,105,110,118,
+101,114,115,101,77,97,115,115,0,109,95,108,105,110,101,97,114,68,97,109,
+112,105,110,103,0,109,95,97,110,103,117,108,97,114,68,97,109,112,105,110,
+103,0,109,95,97,100,100,105,116,105,111,110,97,108,68,97,109,112,105,110,
+103,70,97,99,116,111,114,0,109,95,97,100,100,105,116,105,111,110,97,108,
+76,105,110,101,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,
+108,100,83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,
+103,117,108,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,108,
+100,83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,103,
+117,108,97,114,68,97,109,112,105,110,103,70,97,99,116,111,114,0,109,95,
+108,105,110,101,97,114,83,108,101,101,112,105,110,103,84,104,114,101,115,104,
+111,108,100,0,109,95,97,110,103,117,108,97,114,83,108,101,101,112,105,110,
+103,84,104,114,101,115,104,111,108,100,0,109,95,97,100,100,105,116,105,111,
+110,97,108,68,97,109,112,105,110,103,0,109,95,110,117,109,67,111,110,115,
+116,114,97,105,110,116,82,111,119,115,0,110,117,98,0,42,109,95,114,98,
+65,0,42,109,95,114,98,66,0,109,95,111,98,106,101,99,116,84,121,112,
+101,0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,84,121,
+112,101,0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,73,
+100,0,109,95,110,101,101,100,115,70,101,101,100,98,97,99,107,0,109,95,
+97,112,112,108,105,101,100,73,109,112,117,108,115,101,0,109,95,100,98,103,
+68,114,97,119,83,105,122,101,0,109,95,100,105,115,97,98,108,101,67,111,
+108,108,105,115,105,111,110,115,66,101,116,119,101,101,110,76,105,110,107,101,
+100,66,111,100,105,101,115,0,109,95,112,97,100,52,91,52,93,0,109,95,
+116,121,112,101,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,109,
+95,112,105,118,111,116,73,110,65,0,109,95,112,105,118,111,116,73,110,66,
+0,109,95,114,98,65,70,114,97,109,101,0,109,95,114,98,66,70,114,97,
+109,101,0,109,95,117,115,101,82,101,102,101,114,101,110,99,101,70,114,97,
+109,101,65,0,109,95,97,110,103,117,108,97,114,79,110,108,121,0,109,95,
+101,110,97,98,108,101,65,110,103,117,108,97,114,77,111,116,111,114,0,109,
+95,109,111,116,111,114,84,97,114,103,101,116,86,101,108,111,99,105,116,121,
+0,109,95,109,97,120,77,111,116,111,114,73,109,112,117,108,115,101,0,109,
+95,108,111,119,101,114,76,105,109,105,116,0,109,95,117,112,112,101,114,76,
+105,109,105,116,0,109,95,108,105,109,105,116,83,111,102,116,110,101,115,115,
+0,109,95,98,105,97,115,70,97,99,116,111,114,0,109,95,114,101,108,97,
+120,97,116,105,111,110,70,97,99,116,111,114,0,109,95,115,119,105,110,103,
+83,112,97,110,49,0,109,95,115,119,105,110,103,83,112,97,110,50,0,109,
+95,116,119,105,115,116,83,112,97,110,0,109,95,100,97,109,112,105,110,103,
+0,109,95,108,105,110,101,97,114,85,112,112,101,114,76,105,109,105,116,0,
+109,95,108,105,110,101,97,114,76,111,119,101,114,76,105,109,105,116,0,109,
+95,97,110,103,117,108,97,114,85,112,112,101,114,76,105,109,105,116,0,109,
+95,97,110,103,117,108,97,114,76,111,119,101,114,76,105,109,105,116,0,109,
+95,117,115,101,76,105,110,101,97,114,82,101,102,101,114,101,110,99,101,70,
+114,97,109,101,65,0,109,95,117,115,101,79,102,102,115,101,116,70,111,114,
+67,111,110,115,116,114,97,105,110,116,70,114,97,109,101,0,84,89,80,69,
+58,0,0,0,99,104,97,114,0,117,99,104,97,114,0,115,104,111,114,116,
+0,117,115,104,111,114,116,0,105,110,116,0,108,111,110,103,0,117,108,111,
+110,103,0,102,108,111,97,116,0,100,111,117,98,108,101,0,118,111,105,100,
+0,80,111,105,110,116,101,114,65,114,114,97,121,0,98,116,80,104,121,115,
+105,99,115,83,121,115,116,101,109,0,76,105,115,116,66,97,115,101,0,98,
+116,86,101,99,116,111,114,51,70,108,111,97,116,68,97,116,97,0,98,116,
+86,101,99,116,111,114,51,68,111,117,98,108,101,68,97,116,97,0,98,116,
+77,97,116,114,105,120,51,120,51,70,108,111,97,116,68,97,116,97,0,98,
+116,77,97,116,114,105,120,51,120,51,68,111,117,98,108,101,68,97,116,97,
+0,98,116,84,114,97,110,115,102,111,114,109,70,108,111,97,116,68,97,116,
+97,0,98,116,84,114,97,110,115,102,111,114,109,68,111,117,98,108,101,68,
+97,116,97,0,98,116,66,118,104,83,117,98,116,114,101,101,73,110,102,111,
+68,97,116,97,0,98,116,79,112,116,105,109,105,122,101,100,66,118,104,78,
+111,100,101,70,108,111,97,116,68,97,116,97,0,98,116,79,112,116,105,109,
+105,122,101,100,66,118,104,78,111,100,101,68,111,117,98,108,101,68,97,116,
+97,0,98,116,81,117,97,110,116,105,122,101,100,66,118,104,78,111,100,101,
+68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,100,66,118,104,70,
+108,111,97,116,68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,100,
+66,118,104,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,108,
+105,115,105,111,110,83,104,97,112,101,68,97,116,97,0,98,116,83,116,97,
+116,105,99,80,108,97,110,101,83,104,97,112,101,68,97,116,97,0,98,116,
+67,111,110,118,101,120,73,110,116,101,114,110,97,108,83,104,97,112,101,68,
+97,116,97,0,98,116,80,111,115,105,116,105,111,110,65,110,100,82,97,100,
+105,117,115,0,98,116,77,117,108,116,105,83,112,104,101,114,101,83,104,97,
+112,101,68,97,116,97,0,98,116,73,110,116,73,110,100,101,120,68,97,116,
+97,0,98,116,83,104,111,114,116,73,110,116,73,110,100,101,120,68,97,116,
+97,0,98,116,83,104,111,114,116,73,110,116,73,110,100,101,120,84,114,105,
+112,108,101,116,68,97,116,97,0,98,116,77,101,115,104,80,97,114,116,68,
+97,116,97,0,98,116,83,116,114,105,100,105,110,103,77,101,115,104,73,110,
+116,101,114,102,97,99,101,68,97,116,97,0,98,116,84,114,105,97,110,103,
+108,101,77,101,115,104,83,104,97,112,101,68,97,116,97,0,98,116,84,114,
+105,97,110,103,108,101,73,110,102,111,77,97,112,68,97,116,97,0,98,116,
+67,111,109,112,111,117,110,100,83,104,97,112,101,67,104,105,108,100,68,97,
+116,97,0,98,116,67,111,109,112,111,117,110,100,83,104,97,112,101,68,97,
+116,97,0,98,116,67,121,108,105,110,100,101,114,83,104,97,112,101,68,97,
+116,97,0,98,116,67,97,112,115,117,108,101,83,104,97,112,101,68,97,116,
+97,0,98,116,84,114,105,97,110,103,108,101,73,110,102,111,68,97,116,97,
+0,98,116,71,73,109,112,97,99,116,77,101,115,104,83,104,97,112,101,68,
+97,116,97,0,98,116,67,111,110,118,101,120,72,117,108,108,83,104,97,112,
+101,68,97,116,97,0,98,116,67,111,108,108,105,115,105,111,110,79,98,106,
+101,99,116,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,108,
+105,115,105,111,110,79,98,106,101,99,116,70,108,111,97,116,68,97,116,97,
+0,98,116,82,105,103,105,100,66,111,100,121,70,108,111,97,116,68,97,116,
+97,0,98,116,82,105,103,105,100,66,111,100,121,68,111,117,98,108,101,68,
+97,116,97,0,98,116,67,111,110,115,116,114,97,105,110,116,73,110,102,111,
+49,0,98,116,84,121,112,101,100,67,111,110,115,116,114,97,105,110,116,68,
+97,116,97,0,98,116,82,105,103,105,100,66,111,100,121,68,97,116,97,0,
+98,116,80,111,105,110,116,50,80,111,105,110,116,67,111,110,115,116,114,97,
+105,110,116,70,108,111,97,116,68,97,116,97,0,98,116,80,111,105,110,116,
+50,80,111,105,110,116,67,111,110,115,116,114,97,105,110,116,68,111,117,98,
+108,101,68,97,116,97,0,98,116,72,105,110,103,101,67,111,110,115,116,114,
+97,105,110,116,68,111,117,98,108,101,68,97,116,97,0,98,116,72,105,110,
+103,101,67,111,110,115,116,114,97,105,110,116,70,108,111,97,116,68,97,116,
+97,0,98,116,67,111,110,101,84,119,105,115,116,67,111,110,115,116,114,97,
+105,110,116,68,97,116,97,0,98,116,71,101,110,101,114,105,99,54,68,111,
+102,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,98,116,83,108,
+105,100,101,114,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,0,
+84,76,69,78,1,0,1,0,2,0,2,0,4,0,4,0,4,0,4,0,
+8,0,0,0,12,0,36,0,8,0,16,0,32,0,48,0,96,0,64,0,
+-128,0,20,0,48,0,80,0,16,0,84,0,-124,0,12,0,52,0,52,0,
+20,0,64,0,4,0,4,0,8,0,28,0,28,0,60,0,56,0,76,0,
+24,0,60,0,60,0,16,0,64,0,68,0,-56,1,-8,0,-32,1,-104,3,
+8,0,44,0,0,0,76,0,108,0,84,1,-44,0,-52,0,-12,0,-60,0,
+83,84,82,67,47,0,0,0,10,0,3,0,4,0,0,0,4,0,1,0,
+9,0,2,0,11,0,3,0,10,0,3,0,10,0,4,0,10,0,5,0,
+12,0,2,0,9,0,6,0,9,0,7,0,13,0,1,0,7,0,8,0,
+14,0,1,0,8,0,8,0,15,0,1,0,13,0,9,0,16,0,1,0,
+14,0,9,0,17,0,2,0,15,0,10,0,13,0,11,0,18,0,2,0,
+16,0,10,0,14,0,11,0,19,0,4,0,4,0,12,0,4,0,13,0,
+2,0,14,0,2,0,15,0,20,0,6,0,13,0,16,0,13,0,17,0,
+4,0,18,0,4,0,19,0,4,0,20,0,0,0,21,0,21,0,6,0,
+14,0,16,0,14,0,17,0,4,0,18,0,4,0,19,0,4,0,20,0,
+0,0,21,0,22,0,3,0,2,0,14,0,2,0,15,0,4,0,22,0,
+23,0,12,0,13,0,23,0,13,0,24,0,13,0,25,0,4,0,26,0,
+4,0,27,0,4,0,28,0,4,0,29,0,20,0,30,0,22,0,31,0,
+19,0,32,0,4,0,33,0,4,0,34,0,24,0,12,0,14,0,23,0,
+14,0,24,0,14,0,25,0,4,0,26,0,4,0,27,0,4,0,28,0,
+4,0,29,0,21,0,30,0,22,0,31,0,4,0,33,0,4,0,34,0,
+19,0,32,0,25,0,3,0,0,0,35,0,4,0,36,0,0,0,37,0,
+26,0,5,0,25,0,38,0,13,0,39,0,13,0,40,0,7,0,41,0,
+0,0,21,0,27,0,5,0,25,0,38,0,13,0,39,0,13,0,42,0,
+7,0,43,0,4,0,44,0,28,0,2,0,13,0,45,0,7,0,46,0,
+29,0,4,0,27,0,47,0,28,0,48,0,4,0,49,0,0,0,37,0,
+30,0,1,0,4,0,50,0,31,0,2,0,2,0,50,0,0,0,51,0,
+32,0,2,0,2,0,52,0,0,0,51,0,33,0,7,0,13,0,53,0,
+14,0,54,0,30,0,55,0,32,0,56,0,31,0,57,0,4,0,58,0,
+4,0,59,0,34,0,4,0,33,0,60,0,13,0,61,0,4,0,62,0,
+0,0,37,0,35,0,7,0,25,0,38,0,34,0,63,0,23,0,64,0,
+24,0,65,0,36,0,66,0,7,0,43,0,0,0,67,0,37,0,4,0,
+17,0,68,0,25,0,69,0,4,0,70,0,7,0,71,0,38,0,4,0,
+25,0,38,0,37,0,72,0,4,0,73,0,7,0,43,0,39,0,3,0,
+27,0,47,0,4,0,74,0,0,0,37,0,40,0,3,0,27,0,47,0,
+4,0,74,0,0,0,37,0,41,0,4,0,4,0,75,0,7,0,76,0,
+7,0,77,0,7,0,78,0,36,0,14,0,4,0,79,0,4,0,80,0,
+41,0,81,0,4,0,82,0,7,0,83,0,7,0,84,0,7,0,85,0,
+7,0,86,0,7,0,87,0,4,0,88,0,4,0,89,0,4,0,90,0,
+4,0,91,0,0,0,37,0,42,0,5,0,25,0,38,0,34,0,63,0,
+13,0,39,0,7,0,43,0,4,0,92,0,43,0,5,0,27,0,47,0,
+13,0,93,0,14,0,94,0,4,0,95,0,0,0,96,0,44,0,24,0,
+9,0,97,0,9,0,98,0,25,0,99,0,0,0,35,0,18,0,100,0,
+18,0,101,0,14,0,102,0,14,0,103,0,14,0,104,0,8,0,105,0,
+8,0,106,0,8,0,107,0,8,0,108,0,8,0,109,0,8,0,110,0,
+8,0,111,0,4,0,112,0,4,0,113,0,4,0,114,0,4,0,115,0,
+4,0,116,0,4,0,117,0,4,0,118,0,0,0,37,0,45,0,23,0,
+9,0,97,0,9,0,98,0,25,0,99,0,0,0,35,0,17,0,100,0,
+17,0,101,0,13,0,102,0,13,0,103,0,13,0,104,0,7,0,105,0,
+7,0,106,0,7,0,107,0,7,0,108,0,7,0,109,0,7,0,110,0,
+7,0,111,0,4,0,112,0,4,0,113,0,4,0,114,0,4,0,115,0,
+4,0,116,0,4,0,117,0,4,0,118,0,46,0,21,0,45,0,119,0,
+15,0,120,0,13,0,121,0,13,0,122,0,13,0,123,0,13,0,124,0,
+13,0,125,0,13,0,126,0,13,0,127,0,13,0,-128,0,13,0,-127,0,
+7,0,-126,0,7,0,-125,0,7,0,-124,0,7,0,-123,0,7,0,-122,0,
+7,0,-121,0,7,0,-120,0,7,0,-119,0,7,0,-118,0,4,0,-117,0,
+47,0,22,0,44,0,119,0,16,0,120,0,14,0,121,0,14,0,122,0,
+14,0,123,0,14,0,124,0,14,0,125,0,14,0,126,0,14,0,127,0,
+14,0,-128,0,14,0,-127,0,8,0,-126,0,8,0,-125,0,8,0,-124,0,
+8,0,-123,0,8,0,-122,0,8,0,-121,0,8,0,-120,0,8,0,-119,0,
+8,0,-118,0,4,0,-117,0,0,0,37,0,48,0,2,0,4,0,-116,0,
+4,0,-115,0,49,0,11,0,50,0,-114,0,50,0,-113,0,0,0,35,0,
+4,0,-112,0,4,0,-111,0,4,0,-110,0,4,0,-109,0,7,0,-108,0,
+7,0,-107,0,4,0,-106,0,0,0,-105,0,51,0,3,0,49,0,-104,0,
+13,0,-103,0,13,0,-102,0,52,0,3,0,49,0,-104,0,14,0,-103,0,
+14,0,-102,0,53,0,13,0,49,0,-104,0,18,0,-101,0,18,0,-100,0,
+4,0,-99,0,4,0,-98,0,4,0,-97,0,7,0,-96,0,7,0,-95,0,
+7,0,-94,0,7,0,-93,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,
+54,0,13,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,4,0,-99,0,
+4,0,-98,0,4,0,-97,0,7,0,-96,0,7,0,-95,0,7,0,-94,0,
+7,0,-93,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,55,0,11,0,
+49,0,-104,0,17,0,-101,0,17,0,-100,0,7,0,-89,0,7,0,-88,0,
+7,0,-87,0,7,0,-92,0,7,0,-91,0,7,0,-90,0,7,0,-86,0,
+0,0,21,0,56,0,9,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,
+13,0,-85,0,13,0,-84,0,13,0,-83,0,13,0,-82,0,4,0,-81,0,
+4,0,-80,0,57,0,9,0,49,0,-104,0,17,0,-101,0,17,0,-100,0,
+7,0,-85,0,7,0,-84,0,7,0,-83,0,7,0,-82,0,4,0,-81,0,
+4,0,-80,0,};
+int sBulletDNAlen= sizeof(sBulletDNAstr);
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btSerializer.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btSerializer.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btSerializer.h	(revision 8284)
@@ -0,0 +1,606 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2009 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_SERIALIZER_H
+#define BT_SERIALIZER_H
+
+#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
+#include "btStackAlloc.h"
+#include "btHashMap.h"
+
+#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__)
+#include <memory.h>
+#endif
+#include <string.h>
+
+
+
+///only the 32bit versions for now
+extern unsigned char sBulletDNAstr[];
+extern int sBulletDNAlen;
+extern unsigned char sBulletDNAstr64[];
+extern int sBulletDNAlen64;
+
+SIMD_FORCE_INLINE	int btStrLen(const char* str) 
+{
+    if (!str) 
+		return(0);
+	int len = 0;
+    
+	while (*str != 0)
+	{
+        str++;
+        len++;
+    }
+
+    return len;
+}
+
+
+class btChunk
+{
+public:
+	int		m_chunkCode;
+	int		m_length;
+	void	*m_oldPtr;
+	int		m_dna_nr;
+	int		m_number;
+};
+
+enum	btSerializationFlags
+{
+	BT_SERIALIZE_NO_BVH = 1,
+	BT_SERIALIZE_NO_TRIANGLEINFOMAP = 2,
+	BT_SERIALIZE_NO_DUPLICATE_ASSERT = 4
+};
+
+class	btSerializer
+{
+
+public:
+
+	virtual ~btSerializer() {}
+
+	virtual	const unsigned char*		getBufferPointer() const = 0;
+
+	virtual	int		getCurrentBufferSize() const = 0;
+
+	virtual	btChunk*	allocate(size_t size, int numElements) = 0;
+
+	virtual	void	finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)= 0;
+
+	virtual	 void*	findPointer(void* oldPtr)  = 0;
+
+	virtual	void*	getUniquePointer(void*oldPtr) = 0;
+
+	virtual	void	startSerialization() = 0;
+	
+	virtual	void	finishSerialization() = 0;
+
+	virtual	const char*	findNameForPointer(const void* ptr) const = 0;
+
+	virtual	void	registerNameForPointer(const void* ptr, const char* name) = 0;
+
+	virtual void	serializeName(const char* ptr) = 0;
+
+	virtual int		getSerializationFlags() const = 0;
+
+	virtual void	setSerializationFlags(int flags) = 0;
+
+
+};
+
+
+
+#define BT_HEADER_LENGTH 12
+#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
+#	define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
+#else
+#	define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
+#endif
+
+#define BT_COLLISIONOBJECT_CODE MAKE_ID('C','O','B','J')
+#define BT_RIGIDBODY_CODE		MAKE_ID('R','B','D','Y')
+#define BT_CONSTRAINT_CODE		MAKE_ID('C','O','N','S')
+#define BT_BOXSHAPE_CODE		MAKE_ID('B','O','X','S')
+#define BT_QUANTIZED_BVH_CODE	MAKE_ID('Q','B','V','H')
+#define BT_TRIANLGE_INFO_MAP	MAKE_ID('T','M','A','P')
+#define BT_SHAPE_CODE			MAKE_ID('S','H','A','P')
+#define BT_ARRAY_CODE			MAKE_ID('A','R','A','Y')
+#define BT_DNA_CODE				MAKE_ID('D','N','A','1')
+
+
+
+struct	btPointerUid
+{
+	union
+	{
+		void*	m_ptr;
+		int		m_uniqueIds[2];
+	};
+};
+
+
+class btDefaultSerializer	:	public btSerializer
+{
+
+
+	btAlignedObjectArray<char*>			mTypes;
+	btAlignedObjectArray<short*>			mStructs;
+	btAlignedObjectArray<short>			mTlens;
+	btHashMap<btHashInt, int>			mStructReverse;
+	btHashMap<btHashString,int>	mTypeLookup;
+
+	
+	btHashMap<btHashPtr,void*>	m_chunkP;
+	
+	btHashMap<btHashPtr,const char*>	m_nameMap;
+
+	btHashMap<btHashPtr,btPointerUid>	m_uniquePointers;
+	int	m_uniqueIdGenerator;
+
+	int					m_totalSize;
+	unsigned char*		m_buffer;
+	int					m_currentSize;
+	void*				m_dna;
+	int					m_dnaLength;
+
+	int					m_serializationFlags;
+
+
+	btAlignedObjectArray<btChunk*>	m_chunkPtrs;
+	
+protected:
+
+	virtual	void*	findPointer(void* oldPtr) 
+	{
+		void** ptr = m_chunkP.find(oldPtr);
+		if (ptr && *ptr)
+			return *ptr;
+		return 0;
+	}
+
+	
+
+
+
+		void	writeDNA()
+		{
+			btChunk* dnaChunk = allocate(m_dnaLength,1);
+			memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength);
+			finalizeChunk(dnaChunk,"DNA1",BT_DNA_CODE, m_dna);
+		}
+
+		int getReverseType(const char *type) const
+		{
+
+			btHashString key(type);
+			const int* valuePtr = mTypeLookup.find(key);
+			if (valuePtr)
+				return *valuePtr;
+			
+			return -1;
+		}
+
+		void initDNA(const char* bdnaOrg,int dnalen)
+		{
+			///was already initialized
+			if (m_dna)
+				return;
+
+			int littleEndian= 1;
+			littleEndian= ((char*)&littleEndian)[0];
+			
+
+			m_dna = btAlignedAlloc(dnalen,16);
+			memcpy(m_dna,bdnaOrg,dnalen);
+			m_dnaLength = dnalen;
+
+			int *intPtr=0;
+			short *shtPtr=0;
+			char *cp = 0;int dataLen =0;long nr=0;
+			intPtr = (int*)m_dna;
+
+			/*
+				SDNA (4 bytes) (magic number)
+				NAME (4 bytes)
+				<nr> (4 bytes) amount of names (int)
+				<string>
+				<string>
+			*/
+
+			if (strncmp((const char*)m_dna, "SDNA", 4)==0)
+			{
+				// skip ++ NAME
+				intPtr++; intPtr++;
+			}
+
+			// Parse names
+			if (!littleEndian)
+				*intPtr = btSwapEndian(*intPtr);
+				
+			dataLen = *intPtr;
+			
+			intPtr++;
+
+			cp = (char*)intPtr;
+			int i;
+			for ( i=0; i<dataLen; i++)
+			{
+				
+				while (*cp)cp++;
+				cp++;
+			}
+			{
+				nr= (long)cp;
+			//	long mask=3;
+				nr= ((nr+3)&~3)-nr;
+				while (nr--)
+				{
+					cp++;
+				}
+			}
+
+			/*
+				TYPE (4 bytes)
+				<nr> amount of types (int)
+				<string>
+				<string>
+			*/
+
+			intPtr = (int*)cp;
+			assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
+
+			if (!littleEndian)
+				*intPtr =  btSwapEndian(*intPtr);
+			
+			dataLen = *intPtr;
+			intPtr++;
+
+			
+			cp = (char*)intPtr;
+			for (i=0; i<dataLen; i++)
+			{
+				mTypes.push_back(cp);
+				while (*cp)cp++;
+				cp++;
+			}
+
+		{
+				nr= (long)cp;
+			//	long mask=3;
+				nr= ((nr+3)&~3)-nr;
+				while (nr--)
+				{
+					cp++;
+				}
+			}
+
+
+			/*
+				TLEN (4 bytes)
+				<len> (short) the lengths of types
+				<len>
+			*/
+
+			// Parse type lens
+			intPtr = (int*)cp;
+			assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
+
+			dataLen = (int)mTypes.size();
+
+			shtPtr = (short*)intPtr;
+			for (i=0; i<dataLen; i++, shtPtr++)
+			{
+				if (!littleEndian)
+					shtPtr[0] = btSwapEndian(shtPtr[0]);
+				mTlens.push_back(shtPtr[0]);
+			}
+
+			if (dataLen & 1) shtPtr++;
+
+			/*
+				STRC (4 bytes)
+				<nr> amount of structs (int)
+				<typenr>
+				<nr_of_elems>
+				<typenr>
+				<namenr>
+				<typenr>
+				<namenr>
+			*/
+
+			intPtr = (int*)shtPtr;
+			cp = (char*)intPtr;
+			assert(strncmp(cp, "STRC", 4)==0); intPtr++;
+
+			if (!littleEndian)
+				*intPtr = btSwapEndian(*intPtr);
+			dataLen = *intPtr ; 
+			intPtr++;
+
+
+			shtPtr = (short*)intPtr;
+			for (i=0; i<dataLen; i++)
+			{
+				mStructs.push_back (shtPtr);
+				
+				if (!littleEndian)
+				{
+					shtPtr[0]= btSwapEndian(shtPtr[0]);
+					shtPtr[1]= btSwapEndian(shtPtr[1]);
+
+					int len = shtPtr[1];
+					shtPtr+= 2;
+
+					for (int a=0; a<len; a++, shtPtr+=2)
+					{
+							shtPtr[0]= btSwapEndian(shtPtr[0]);
+							shtPtr[1]= btSwapEndian(shtPtr[1]);
+					}
+
+				} else
+				{
+					shtPtr+= (2*shtPtr[1])+2;
+				}
+			}
+
+			// build reverse lookups
+			for (i=0; i<(int)mStructs.size(); i++)
+			{
+				short *strc = mStructs.at(i);
+				mStructReverse.insert(strc[0], i);
+				mTypeLookup.insert(btHashString(mTypes[strc[0]]),i);
+			}
+		}
+
+public:	
+	
+
+	
+
+		btDefaultSerializer(int totalSize)
+			:m_totalSize(totalSize),
+			m_currentSize(0),
+			m_dna(0),
+			m_dnaLength(0),
+			m_serializationFlags(0)
+		{
+			m_buffer = (unsigned char*)btAlignedAlloc(totalSize, 16);
+			
+			const bool VOID_IS_8 = ((sizeof(void*)==8));
+
+#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
+			if (VOID_IS_8)
+			{
+#if _WIN64
+				initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
+#else
+				btAssert(0);
+#endif
+			} else
+			{
+#ifndef _WIN64
+				initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
+#else
+				btAssert(0);
+#endif
+			}
+	
+#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
+			if (VOID_IS_8)
+			{
+				initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64);
+			} else
+			{
+				initDNA((const char*)sBulletDNAstr,sBulletDNAlen);
+			}
+#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
+	
+		}
+
+		virtual ~btDefaultSerializer() 
+		{
+			if (m_buffer)
+				btAlignedFree(m_buffer);
+			if (m_dna)
+				btAlignedFree(m_dna);
+		}
+
+		virtual	void	startSerialization()
+		{
+			m_uniqueIdGenerator= 1;
+
+			m_currentSize = BT_HEADER_LENGTH;
+
+#ifdef  BT_USE_DOUBLE_PRECISION
+			memcpy(m_buffer, "BULLETd", 7);
+#else
+			memcpy(m_buffer, "BULLETf", 7);
+#endif //BT_USE_DOUBLE_PRECISION
+	
+			int littleEndian= 1;
+			littleEndian= ((char*)&littleEndian)[0];
+
+			if (sizeof(void*)==8)
+			{
+				m_buffer[7] = '-';
+			} else
+			{
+				m_buffer[7] = '_';
+			}
+
+			if (littleEndian)
+			{
+				m_buffer[8]='v';				
+			} else
+			{
+				m_buffer[8]='V';
+			}
+
+
+			m_buffer[9] = '2';
+			m_buffer[10] = '7';
+			m_buffer[11] = '7';
+
+			
+		}
+
+		virtual	void	finishSerialization()
+		{
+			writeDNA();
+
+
+			mTypes.clear();
+			mStructs.clear();
+			mTlens.clear();
+			mStructReverse.clear();
+			mTypeLookup.clear();
+			m_chunkP.clear();
+			m_nameMap.clear();
+			m_uniquePointers.clear();
+		}
+
+		virtual	void*	getUniquePointer(void*oldPtr)
+		{
+			if (!oldPtr)
+				return 0;
+
+			btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr);
+			if (uptr)
+			{
+				return uptr->m_ptr;
+			}
+			m_uniqueIdGenerator++;
+			
+			btPointerUid uid;
+			uid.m_uniqueIds[0] = m_uniqueIdGenerator;
+			uid.m_uniqueIds[1] = m_uniqueIdGenerator;
+			m_uniquePointers.insert(oldPtr,uid);
+			return uid.m_ptr;
+
+		}
+
+		virtual	const unsigned char*		getBufferPointer() const
+		{
+			return m_buffer;
+		}
+
+		virtual	int					getCurrentBufferSize() const
+		{
+			return	m_currentSize;
+		}
+
+		virtual	void	finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)
+		{
+			if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT))
+			{
+				btAssert(!findPointer(oldPtr));
+			}
+
+			chunk->m_dna_nr = getReverseType(structType);
+			
+			chunk->m_chunkCode = chunkCode;
+			
+			void* uniquePtr = getUniquePointer(oldPtr);
+			
+			m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr);
+			chunk->m_oldPtr = uniquePtr;//oldPtr;
+			
+		}
+
+		
+
+		
+
+		virtual	btChunk*	allocate(size_t size, int numElements)
+		{
+
+			unsigned char* ptr = m_buffer+m_currentSize;
+			m_currentSize += int(size)*numElements+sizeof(btChunk);
+			btAssert(m_currentSize<m_totalSize);
+
+			unsigned char* data = ptr + sizeof(btChunk);
+			
+			btChunk* chunk = (btChunk*)ptr;
+			chunk->m_chunkCode = 0;
+			chunk->m_oldPtr = data;
+			chunk->m_length = int(size)*numElements;
+			chunk->m_number = numElements;
+			
+			m_chunkPtrs.push_back(chunk);
+			
+
+			return chunk;
+		}
+
+		virtual	const char*	findNameForPointer(const void* ptr) const
+		{
+			const char*const * namePtr = m_nameMap.find(ptr);
+			if (namePtr && *namePtr)
+				return *namePtr;
+			return 0;
+
+		}
+
+		virtual	void	registerNameForPointer(const void* ptr, const char* name)
+		{
+			m_nameMap.insert(ptr,name);
+		}
+
+		virtual void	serializeName(const char* name)
+		{
+			if (name)
+			{
+				//don't serialize name twice
+				if (findPointer((void*)name))
+					return;
+
+				int len = btStrLen(name);
+				if (len)
+				{
+
+					int newLen = len+1;
+					int padding = ((newLen+3)&~3)-newLen;
+					newLen += padding;
+
+					//serialize name string now
+					btChunk* chunk = allocate(sizeof(char),newLen);
+					char* destinationName = (char*)chunk->m_oldPtr;
+					for (int i=0;i<len;i++)
+					{
+						destinationName[i] = name[i];
+					}
+					destinationName[len] = 0;
+					finalizeChunk(chunk,"char",BT_ARRAY_CODE,(void*)name);
+				}
+			}
+		}
+
+		virtual int		getSerializationFlags() const
+		{
+			return m_serializationFlags;
+		}
+
+		virtual void	setSerializationFlags(int flags)
+		{
+			m_serializationFlags = flags;
+		}
+
+};
+
+
+#endif //BT_SERIALIZER_H
+
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btTransform.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btTransform.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btTransform.h	(revision 8284)
@@ -18,6 +18,14 @@
 #define btTransform_H
 
-#include "btVector3.h"
+
 #include "btMatrix3x3.h"
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btTransformData btTransformDoubleData
+#else
+#define btTransformData btTransformFloatData
+#endif
+
+
 
 
@@ -26,4 +34,8 @@
 class btTransform {
 	
+  ///Storage for the rotation
+	btMatrix3x3 m_basis;
+  ///Storage for the translation
+	btVector3   m_origin;
 
 public:
@@ -196,10 +208,15 @@
 		return identityTransform;
 	}
-	
-private:
-  ///Storage for the rotation
-	btMatrix3x3 m_basis;
-  ///Storage for the translation
-	btVector3   m_origin;
+
+	void	serialize(struct	btTransformData& dataOut) const;
+
+	void	serializeFloat(struct	btTransformFloatData& dataOut) const;
+
+	void	deSerialize(const struct	btTransformData& dataIn);
+
+	void	deSerializeDouble(const struct	btTransformDoubleData& dataIn);
+
+	void	deSerializeFloat(const struct	btTransformFloatData& dataIn);
+
 };
 
@@ -235,4 +252,51 @@
 
 
+///for serialization
+struct	btTransformFloatData
+{
+	btMatrix3x3FloatData	m_basis;
+	btVector3FloatData	m_origin;
+};
+
+struct	btTransformDoubleData
+{
+	btMatrix3x3DoubleData	m_basis;
+	btVector3DoubleData	m_origin;
+};
+
+
+
+SIMD_FORCE_INLINE	void	btTransform::serialize(btTransformData& dataOut) const
+{
+	m_basis.serialize(dataOut.m_basis);
+	m_origin.serialize(dataOut.m_origin);
+}
+
+SIMD_FORCE_INLINE	void	btTransform::serializeFloat(btTransformFloatData& dataOut) const
+{
+	m_basis.serializeFloat(dataOut.m_basis);
+	m_origin.serializeFloat(dataOut.m_origin);
+}
+
+
+SIMD_FORCE_INLINE	void	btTransform::deSerialize(const btTransformData& dataIn)
+{
+	m_basis.deSerialize(dataIn.m_basis);
+	m_origin.deSerialize(dataIn.m_origin);
+}
+
+SIMD_FORCE_INLINE	void	btTransform::deSerializeFloat(const btTransformFloatData& dataIn)
+{
+	m_basis.deSerializeFloat(dataIn.m_basis);
+	m_origin.deSerializeFloat(dataIn.m_origin);
+}
+
+SIMD_FORCE_INLINE	void	btTransform::deSerializeDouble(const btTransformDoubleData& dataIn)
+{
+	m_basis.deSerializeDouble(dataIn.m_basis);
+	m_origin.deSerializeDouble(dataIn.m_origin);
+}
+
+
 #endif
 
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btTransformUtil.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btTransformUtil.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btTransformUtil.h	(revision 8284)
@@ -22,7 +22,4 @@
 
 
-#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
-
-#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x))))		/* reciprocal square root */
 
 SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir)
@@ -34,23 +31,5 @@
 
 
-SIMD_FORCE_INLINE void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q)
-{
-  if (btFabs(n.z()) > SIMDSQRT12) {
-    // choose p in y-z plane
-    btScalar a = n[1]*n[1] + n[2]*n[2];
-    btScalar k = btRecipSqrt (a);
-    p.setValue(0,-n[2]*k,n[1]*k);
-    // set q = n x p
-    q.setValue(a*k,-n[0]*p[2],n[0]*p[1]);
-  }
-  else {
-    // choose p in x-y plane
-    btScalar a = n.x()*n.x() + n.y()*n.y();
-    btScalar k = btRecipSqrt (a);
-    p.setValue(-n.y()*k,n.x()*k,0);
-    // set q = n x p
-    q.setValue(-n.z()*p.y(),n.z()*p.x(),a*k);
-  }
-}
+
 
 
@@ -118,8 +97,6 @@
 	static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle)
 	{
-		btQuaternion orn1 = orn0.farthest(orn1a);
+		btQuaternion orn1 = orn0.nearest(orn1a);
 		btQuaternion dorn = orn1 * orn0.inverse();
-		///floating point inaccuracy can lead to w component > 1..., which breaks 
-		dorn.normalize();
 		angle = dorn.getAngle();
 		axis = btVector3(dorn.x(),dorn.y(),dorn.z());
@@ -210,5 +187,5 @@
 			btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB;
 			btVector3 relLinVel = (linVelB-linVelA);
-			btScalar relLinVelocLength = (linVelB-linVelA).dot(m_separatingNormal);
+			btScalar relLinVelocLength = relLinVel.dot(m_separatingNormal);
 			if (relLinVelocLength<0.f)
 			{
@@ -228,15 +205,19 @@
 	void	initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB)
 	{
-		m_separatingNormal = separatingVector;
 		m_separatingDistance = separatingDistance;
-		
-		const btVector3& toPosA = transA.getOrigin();
-		const btVector3& toPosB = transB.getOrigin();
-		btQuaternion toOrnA = transA.getRotation();
-		btQuaternion toOrnB = transB.getRotation();
-		m_posA = toPosA;
-		m_posB = toPosB;
-		m_ornA = toOrnA;
-		m_ornB = toOrnB;
+
+		if (m_separatingDistance>0.f)
+		{
+			m_separatingNormal = separatingVector;
+			
+			const btVector3& toPosA = transA.getOrigin();
+			const btVector3& toPosB = transB.getOrigin();
+			btQuaternion toOrnA = transA.getRotation();
+			btQuaternion toOrnB = transB.getRotation();
+			m_posA = toPosA;
+			m_posB = toPosB;
+			m_ornA = toOrnA;
+			m_ornB = toOrnB;
+		}
 	}
 
Index: /code/branches/kicklib2/src/external/bullet/LinearMath/btVector3.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/LinearMath/btVector3.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/LinearMath/btVector3.h	(revision 8284)
@@ -20,11 +20,21 @@
 
 #include "btScalar.h"
-#include "btScalar.h"
 #include "btMinMax.h"
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btVector3Data btVector3DoubleData
+#define btVector3DataName "btVector3DoubleData"
+#else
+#define btVector3Data btVector3FloatData
+#define btVector3DataName "btVector3FloatData"
+#endif //BT_USE_DOUBLE_PRECISION
+
+
+
+
 /**@brief btVector3 can be used to represent 3D points and vectors.
  * It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user
  * Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers
  */
-
 ATTRIBUTE_ALIGNED16(class) btVector3
 {
@@ -32,16 +42,13 @@
 
 #if defined (__SPU__) && defined (__CELLOS_LV2__)
-	union {
-		vec_float4 mVec128;
 		btScalar	m_floats[4];
-	};
 public:
-	vec_float4	get128() const
-	{
-		return mVec128;
+	SIMD_FORCE_INLINE const vec_float4&	get128() const
+	{
+		return *((const vec_float4*)&m_floats[0]);
 	}
 public:
 #else //__CELLOS_LV2__ __SPU__
-#ifdef BT_USE_SSE // WIN32
+#ifdef BT_USE_SSE // _WIN32
 	union {
 		__m128 mVec128;
@@ -142,4 +149,17 @@
 	SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const;
 
+	SIMD_FORCE_INLINE btVector3& safeNormalize() 
+	{
+		btVector3 absVec = this->absolute();
+		int maxIndex = absVec.maxAxis();
+		if (absVec[maxIndex]>0)
+		{
+			*this /= absVec[maxIndex];
+			return *this /= length();
+		}
+		setValue(1,0,0);
+		return *this;
+	}
+
   /**@brief Normalize this vector 
    * x^2 + y^2 + z^2 = 1 */
@@ -152,8 +172,8 @@
 	SIMD_FORCE_INLINE btVector3 normalized() const;
 
-  /**@brief Rotate this vector 
+  /**@brief Return a rotated version of this vector
    * @param wAxis The axis to rotate about 
    * @param angle The angle to rotate by */
-	SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle );
+	SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ) const;
 
   /**@brief Return the angle between this and another vector
@@ -307,5 +327,5 @@
 			m_floats[1]=y;
 			m_floats[2]=z;
-			m_floats[3] = 0.f;
+			m_floats[3] = btScalar(0.);
 		}
 
@@ -316,4 +336,31 @@
 			v2->setValue(-y()	,x()	,0.);
 		}
+
+		void	setZero()
+		{
+			setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+		}
+
+		SIMD_FORCE_INLINE bool isZero() const 
+		{
+			return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0);
+		}
+
+		SIMD_FORCE_INLINE bool fuzzyZero() const 
+		{
+			return length2() < SIMD_EPSILON;
+		}
+
+		SIMD_FORCE_INLINE	void	serialize(struct	btVector3Data& dataOut) const;
+
+		SIMD_FORCE_INLINE	void	deSerialize(const struct	btVector3Data& dataIn);
+
+		SIMD_FORCE_INLINE	void	serializeFloat(struct	btVector3FloatData& dataOut) const;
+
+		SIMD_FORCE_INLINE	void	deSerializeFloat(const struct	btVector3FloatData& dataIn);
+
+		SIMD_FORCE_INLINE	void	serializeDouble(struct	btVector3DoubleData& dataOut) const;
+
+		SIMD_FORCE_INLINE	void	deSerializeDouble(const struct	btVector3DoubleData& dataIn);
 
 };
@@ -377,5 +424,5 @@
 /**@brief Return the dot product between two vectors */
 SIMD_FORCE_INLINE btScalar 
-dot(const btVector3& v1, const btVector3& v2) 
+btDot(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.dot(v2); 
@@ -385,5 +432,5 @@
 /**@brief Return the distance squared between two vectors */
 SIMD_FORCE_INLINE btScalar
-distance2(const btVector3& v1, const btVector3& v2) 
+btDistance2(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.distance2(v2); 
@@ -393,5 +440,5 @@
 /**@brief Return the distance between two vectors */
 SIMD_FORCE_INLINE btScalar
-distance(const btVector3& v1, const btVector3& v2) 
+btDistance(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.distance(v2); 
@@ -400,5 +447,5 @@
 /**@brief Return the angle between two vectors */
 SIMD_FORCE_INLINE btScalar
-angle(const btVector3& v1, const btVector3& v2) 
+btAngle(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.angle(v2); 
@@ -407,5 +454,5 @@
 /**@brief Return the cross product of two vectors */
 SIMD_FORCE_INLINE btVector3 
-cross(const btVector3& v1, const btVector3& v2) 
+btCross(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.cross(v2); 
@@ -413,5 +460,5 @@
 
 SIMD_FORCE_INLINE btScalar
-triple(const btVector3& v1, const btVector3& v2, const btVector3& v3)
+btTriple(const btVector3& v1, const btVector3& v2, const btVector3& v3)
 {
 	return v1.triple(v2, v3);
@@ -445,5 +492,5 @@
 } 
 
-SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle )
+SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle ) const
 {
 	// wAxis must be a unit lenght vector
@@ -489,5 +536,5 @@
 	{
 		int maxIndex = -1;
-		btScalar maxVal = btScalar(-1e30);
+		btScalar maxVal = btScalar(-BT_LARGE_FLOAT);
 		if (m_floats[0] > maxVal)
 		{
@@ -522,5 +569,5 @@
 	{
 		int minIndex = -1;
-		btScalar minVal = btScalar(1e30);
+		btScalar minVal = btScalar(BT_LARGE_FLOAT);
 		if (m_floats[0] < minVal)
 		{
@@ -585,6 +632,4 @@
 		}
 
-
- 
 
 };
@@ -636,3 +681,86 @@
 }
 
+template <class T>
+SIMD_FORCE_INLINE void btPlaneSpace1 (const T& n, T& p, T& q)
+{
+  if (btFabs(n[2]) > SIMDSQRT12) {
+    // choose p in y-z plane
+    btScalar a = n[1]*n[1] + n[2]*n[2];
+    btScalar k = btRecipSqrt (a);
+    p[0] = 0;
+	p[1] = -n[2]*k;
+	p[2] = n[1]*k;
+    // set q = n x p
+    q[0] = a*k;
+	q[1] = -n[0]*p[2];
+	q[2] = n[0]*p[1];
+  }
+  else {
+    // choose p in x-y plane
+    btScalar a = n[0]*n[0] + n[1]*n[1];
+    btScalar k = btRecipSqrt (a);
+    p[0] = -n[1]*k;
+	p[1] = n[0]*k;
+	p[2] = 0;
+    // set q = n x p
+    q[0] = -n[2]*p[1];
+	q[1] = n[2]*p[0];
+	q[2] = a*k;
+  }
+}
+
+
+struct	btVector3FloatData
+{
+	float	m_floats[4];
+};
+
+struct	btVector3DoubleData
+{
+	double	m_floats[4];
+
+};
+
+SIMD_FORCE_INLINE	void	btVector3::serializeFloat(struct	btVector3FloatData& dataOut) const
+{
+	///could also do a memcpy, check if it is worth it
+	for (int i=0;i<4;i++)
+		dataOut.m_floats[i] = float(m_floats[i]);
+}
+
+SIMD_FORCE_INLINE void	btVector3::deSerializeFloat(const struct	btVector3FloatData& dataIn)
+{
+	for (int i=0;i<4;i++)
+		m_floats[i] = btScalar(dataIn.m_floats[i]);
+}
+
+
+SIMD_FORCE_INLINE	void	btVector3::serializeDouble(struct	btVector3DoubleData& dataOut) const
+{
+	///could also do a memcpy, check if it is worth it
+	for (int i=0;i<4;i++)
+		dataOut.m_floats[i] = double(m_floats[i]);
+}
+
+SIMD_FORCE_INLINE void	btVector3::deSerializeDouble(const struct	btVector3DoubleData& dataIn)
+{
+	for (int i=0;i<4;i++)
+		m_floats[i] = btScalar(dataIn.m_floats[i]);
+}
+
+
+SIMD_FORCE_INLINE	void	btVector3::serialize(struct	btVector3Data& dataOut) const
+{
+	///could also do a memcpy, check if it is worth it
+	for (int i=0;i<4;i++)
+		dataOut.m_floats[i] = m_floats[i];
+}
+
+SIMD_FORCE_INLINE void	btVector3::deSerialize(const struct	btVector3Data& dataIn)
+{
+	for (int i=0;i<4;i++)
+		m_floats[i] = dataIn.m_floats[i];
+}
+
+
 #endif //SIMD__VECTOR3_H
Index: /code/branches/kicklib2/src/external/bullet/NEWS
===================================================================
--- /code/branches/kicklib2/src/external/bullet/NEWS	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/NEWS	(revision 8284)
@@ -1,4 +1,4 @@
 
-For news, visit the Bullet Physics Forum at
-http://www.continuousphysics.com/Bullet/phpBB2/viewforum.php?f=9
+For news, visit the Bullet Physics forums at
+http://www.bulletphysics.org
 
Index: /code/branches/kicklib2/src/external/bullet/README
===================================================================
--- /code/branches/kicklib2/src/external/bullet/README	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/README	(revision 8284)
@@ -2,6 +2,5 @@
 Bullet is a 3D Collision Detection and Rigid Body Dynamics Library for games and animation.
 Free for commercial use, including Playstation 3, open source under the ZLib License.
-Discrete and continuous collision detection, integrated into Blender 3D, and COLLADA 1.4 Physics import. 
 
 See the Bullet_User_Manual.pdf for more info and visit the Bullet Physics Forum at
-http://bulletphysics.com
+http://bulletphysics.org
Index: /code/branches/kicklib2/src/external/bullet/VERSION
===================================================================
--- /code/branches/kicklib2/src/external/bullet/VERSION	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/VERSION	(revision 8284)
@@ -1,1 +1,1 @@
-2.73
+2.77
Index: /code/branches/kicklib2/src/external/bullet/btBulletCollisionCommon.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/btBulletCollisionCommon.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/btBulletCollisionCommon.h	(revision 8284)
@@ -62,4 +62,6 @@
 #include "LinearMath/btQuickprof.h"
 #include "LinearMath/btIDebugDraw.h"
+#include "LinearMath/btSerializer.h"
+
 
 #endif //BULLET_COLLISION_COMMON_H
Index: /code/branches/kicklib2/src/external/bullet/btBulletDynamicsCommon.h
===================================================================
--- /code/branches/kicklib2/src/external/bullet/btBulletDynamicsCommon.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/btBulletDynamicsCommon.h	(revision 8284)
@@ -31,4 +31,7 @@
 #include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
 #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btUniversalConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btHinge2Constraint.h"
 
 #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
Index: /code/branches/kicklib2/src/external/bullet/changes_orxonox.diff
===================================================================
--- /code/branches/kicklib2/src/external/bullet/changes_orxonox.diff	(revision 8283)
+++ /code/branches/kicklib2/src/external/bullet/changes_orxonox.diff	(revision 8284)
@@ -1,7 +1,5 @@
-Index: btScalar.h
-===================================================================
---- btScalar.h	(revision 2882)
-+++ btScalar.h	(working copy)
-@@ -236,7 +236,11 @@
+--- LinearMath/btScalar.h	Tue Aug 10 13:19:44 2010
++++ LinearMath/btScalar.h	Sun Feb 27 01:27:34 2011
+@@ -286,7 +286,11 @@
  SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
  SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
@@ -13,5 +11,5 @@
 +  SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
 +  #endif
-
+ SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); }
+ 	
  #endif
-
Index: /code/branches/kicklib2/src/external/ogreceguirenderer/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/src/external/ogreceguirenderer/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/ogreceguirenderer/CMakeLists.txt	(revision 8284)
@@ -34,7 +34,8 @@
   DEFINE_SYMBOL
     "OGRE_GUIRENDERER_EXPORTS"
-  VERSION
-    1.4.9
   LINK_LIBRARIES
+    ${Boost_SYSTEM_LIBRARY}
+    ${Boost_THREAD_LIBRARY}
+    ${Boost_DATE_TIME_LIBRARY}
     ${OGRE_LIBRARY}
     ${CEGUI_LIBRARY}
Index: /code/branches/kicklib2/src/external/ois/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/src/external/ois/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/CMakeLists.txt	(revision 8284)
@@ -31,8 +31,9 @@
   OISKeyboard.h
   OISMouse.h
+  OISMultiTouch.h
   OISObject.h
   OISPrereqs.h
 
-COMPILATION_BEGIN OISCompilation.cpp
+#COMPILATION_BEGIN OISCompilation.cpp
   OISEffect.cpp
   OISException.cpp
@@ -42,5 +43,5 @@
   OISKeyboard.cpp
   OISObject.cpp
-COMPILATION_END
+#COMPILATION_END
 )
 IF(WIN32)
@@ -52,5 +53,11 @@
 ENDIF()
 
-INCLUDE_DIRECTORIES(.)
+# Some unexplained hackery for Visual Studio 2005
+ADD_COMPILER_FLAGS("-D_WIN32_DCOM" MSVC8)
+
+# MinGW doesn't come with some required Windows headers
+IF(MINGW)
+  INCLUDE_DIRECTORIES(${WMI_INCLUDE_DIR})
+ENDIF()
 
 ORXONOX_ADD_LIBRARY(ois_orxonox
@@ -59,5 +66,5 @@
     "OIS_NONCLIENT_BUILD"
   VERSION
-    1.2
+    1.3
   SOURCE_FILES
     ${OIS_FILES}
@@ -65,4 +72,6 @@
 
 IF(WIN32)
-  TARGET_LINK_LIBRARIES(ois_orxonox ${DIRECTX_LIBRARIES})
+  TARGET_LINK_LIBRARIES(ois_orxonox ${DIRECTX_LIBRARIES} ${WMI_LIBRARY})
+ELSEIF(APPLE)
+  TARGET_LINK_LIBRARIES(ois_orxonox "/System/Library/Frameworks/IOKit.framework" "/System/Library/Frameworks/Carbon.framework")
 ENDIF()
Index: /code/branches/kicklib2/src/external/ois/OIS.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/OIS.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/OIS.h	(revision 8284)
@@ -29,4 +29,5 @@
 #include "OISKeyboard.h"
 #include "OISJoyStick.h"
+#include "OISMultiTouch.h"
 #include "OISInputManager.h"
 #include "OISFactoryCreator.h"
Index: /code/branches/kicklib2/src/external/ois/OISConfig.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/OISConfig.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/OISConfig.h	(revision 8284)
@@ -70,6 +70,4 @@
 @remarks
 	Build in support for Win32 XInput (Xbox 360 Controller)
-@notes
-	Not Yet Implemented
 */
 //#define OIS_WIN32_XINPUT_SUPPORT
Index: /code/branches/kicklib2/src/external/ois/OISInputManager.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/OISInputManager.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/OISInputManager.cpp	(revision 8284)
@@ -37,4 +37,6 @@
 #elif defined OIS_APPLE_PLATFORM
 #  include "mac/MacInputManager.h"
+#elif defined OIS_IPHONE_PLATFORM
+#  include "iphone/iPhoneInputManager.h"
 #elif defined OIS_XBOX_PLATFORM
 #  include "xbox/XBoxInputManager.h"
@@ -59,4 +61,6 @@
 	m_wiiMoteSupport(0)
 {
+    mFactories.clear();
+    mFactoryObjects.clear();
 }
 
@@ -111,4 +115,6 @@
 #elif defined OIS_APPLE_PLATFORM
 	im = new MacInputManager();
+#elif defined OIS_IPHONE_PLATFORM
+	im = new iPhoneInputManager();
 #else
 	OIS_EXCEPT(E_General, "No platform library.. check build platform defines!");
Index: /code/branches/kicklib2/src/external/ois/OISKeyboard.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/OISKeyboard.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/OISKeyboard.h	(revision 8284)
@@ -184,5 +184,5 @@
 	{
 	public:
-		KeyEvent( Object* obj, KeyCode kc, unsigned int txt ) : EventArg(obj), key(kc), text(txt) {}
+		KeyEvent(Object* obj, KeyCode kc, unsigned int txt) : EventArg(obj), key(kc), text(txt) {}
 		virtual ~KeyEvent() {}
 
@@ -201,6 +201,6 @@
 	public:
 		virtual ~KeyListener() {}
-		virtual bool keyPressed( const KeyEvent &arg ) = 0;
-		virtual bool keyReleased( const KeyEvent &arg ) = 0;		
+		virtual bool keyPressed(const KeyEvent &arg) = 0;
+		virtual bool keyReleased(const KeyEvent &arg) = 0;		
 	};
 
@@ -220,5 +220,5 @@
 			A KeyCode to check
 		*/
-		virtual bool isKeyDown( KeyCode key ) const = 0;
+		virtual bool isKeyDown(KeyCode key) const = 0;
 
 		/**
@@ -229,5 +229,5 @@
 			Send a pointer to a class derived from KeyListener or 0 to clear the callback
 		*/
-		virtual void setEventCallback( KeyListener *keyListener ) { mListener = keyListener;}
+		virtual void setEventCallback(KeyListener *keyListener) { mListener = keyListener;}
 
 		/**
@@ -254,5 +254,5 @@
 			Off, Unicode, Ascii
 		*/
-		virtual void setTextTranslation( TextTranslationMode mode );
+		virtual void setTextTranslation(TextTranslationMode mode);
 
 		/**
@@ -272,5 +272,5 @@
 			The string as determined from the current locale
 		*/
-		virtual const std::string& getAsString( KeyCode kc ) = 0;
+		virtual const std::string& getAsString(KeyCode kc) = 0;
 
 		//! Enum of bit position of modifer
@@ -286,5 +286,5 @@
 			Check modifier status
 		*/
-		bool isModifierDown( Modifier mod ) const;
+		bool isModifierDown(Modifier mod) const;
 
 		/**
@@ -293,5 +293,5 @@
 			(in the form of 1 is down and 0 is up)
 		*/
-		virtual void copyKeyStates( char keys[256] ) const = 0;
+		virtual void copyKeyStates(char keys[256]) const = 0;
 		
 	protected:
Index: /code/branches/kicklib2/src/external/ois/OISMultiTouch.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/OISMultiTouch.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/ois/OISMultiTouch.h	(revision 8284)
@@ -0,0 +1,169 @@
+/*
+The zlib/libpng License
+
+Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+
+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 OIS_MultiTouch_H
+#define OIS_MultiTouch_H
+#include "OISObject.h"
+#include "OISEvents.h"
+
+#include <set>
+#include <vector>
+
+#define OIS_MAX_NUM_TOUCHES 4   // 4 finger touches are probably the highest we'll ever get
+
+namespace OIS
+{
+	/**
+		Represents the state of the multi-touch device
+		All members are valid for both buffered and non buffered mode
+	*/
+    
+	//! Touch Event type
+	enum MultiTypeEventTypeID
+	{
+		MT_None = 0, MT_Pressed, MT_Released, MT_Moved, MT_Cancelled
+	};
+
+	class _OISExport MultiTouchState
+	{
+	public:
+		MultiTouchState() : width(50), height(50), touchType(MT_None) {};
+
+		/** Represents the height/width of your display area.. used if touch clipping
+		or touch grabbed in case of X11 - defaults to 50.. Make sure to set this
+		and change when your size changes.. */
+		mutable int width, height;
+
+		//! X Axis component
+		Axis X;
+
+		//! Y Axis Component
+		Axis Y;
+
+		//! Z Axis Component
+		Axis Z;
+
+        int touchType;
+
+        inline bool touchIsType( MultiTypeEventTypeID touch ) const
+		{
+			return ((touchType & ( 1L << touch )) == 0) ? false : true;
+		}
+        
+		//! Clear all the values
+		void clear()
+		{
+			X.clear();
+			Y.clear();
+			Z.clear();
+            touchType = MT_None;
+		}
+	};
+
+	/** Specialised for multi-touch events */
+	class _OISExport MultiTouchEvent : public EventArg
+	{
+	public:
+		MultiTouchEvent( Object *obj, const MultiTouchState &ms ) : EventArg(obj), state(ms) {}
+		virtual ~MultiTouchEvent() {}
+
+		//! The state of the touch - including axes
+		const MultiTouchState &state;
+	};
+
+	/**
+		To receive buffered touch input, derive a class from this, and implement the
+		methods here. Then set the call back to your MultiTouch instance with MultiTouch::setEventCallback
+	*/
+	class _OISExport MultiTouchListener
+	{
+	public:
+		virtual ~MultiTouchListener() {}
+		virtual bool touchMoved( const MultiTouchEvent &arg ) = 0;
+		virtual bool touchPressed( const MultiTouchEvent &arg ) = 0;
+		virtual bool touchReleased( const MultiTouchEvent &arg ) = 0;
+		virtual bool touchCancelled( const MultiTouchEvent &arg ) = 0;
+	};
+
+	/**
+		MultiTouch base class. To be implemented by specific system (ie. iPhone UITouch)
+		This class is useful as you remain OS independent using this common interface.
+	*/
+	class _OISExport MultiTouch : public Object
+	{
+	public:
+		virtual ~MultiTouch() {}
+
+		/**
+		@remarks
+			Register/unregister a MultiTouch Listener - Only one allowed for simplicity. If broadcasting
+			is necessary, just broadcast from the callback you registered.
+		@param touchListener
+			Send a pointer to a class derived from MultiTouchListener or 0 to clear the callback
+		*/
+		virtual void setEventCallback( MultiTouchListener *touchListener ) {mListener = touchListener;}
+
+		/** @remarks Returns currently set callback.. or 0 */
+		MultiTouchListener* getEventCallback() {return mListener;}
+
+		/** @remarks Clear out the set of input states.  Should be called after input has been processed by the application */
+        void clearStates(void) { mStates.clear(); }
+
+		/** @remarks Returns the state of the touch - is valid for both buffered and non buffered mode */
+		std::vector<MultiTouchState> getMultiTouchStates() const { return mStates; }
+        
+        /** @remarks Returns the first n touch states.  Useful if you know your app only needs to 
+                process n touches.  The return value is a vector to allow random access */
+        const std::vector<MultiTouchState> getFirstNTouchStates(int n) {
+            std::vector<MultiTouchState> states;
+            for( unsigned int i = 0; i < mStates.size(); i++ ) {
+                if(!(mStates[i].touchIsType(MT_None))) {
+                    states.push_back(mStates[i]);
+                }
+            }
+            return states;
+        }
+
+        /** @remarks Returns the first n touch states.  Useful if you know your app only needs to 
+         process n touches.  The return value is a vector to allow random access */
+        const std::vector<MultiTouchState> getMultiTouchStatesOfType(MultiTypeEventTypeID type) {
+            std::vector<MultiTouchState> states;
+            for( unsigned int i = 0; i < mStates.size(); i++ ) {
+                if(mStates[i].touchIsType(type)) {
+                    states.push_back(mStates[i]);
+                }
+            }
+            return states;
+        }
+        
+	protected:
+		MultiTouch(const std::string &vendor, bool buffered, int devID, InputManager* creator)
+			: Object(vendor, OISMultiTouch, buffered, devID, creator), mListener(0) {}
+
+		//! The state of the touch device, implemented in a vector to store the state from each finger touch
+        std::vector<MultiTouchState> mStates;
+
+		//! Used for buffered/actionmapping callback
+		MultiTouchListener *mListener;
+	};
+}
+#endif
Index: /code/branches/kicklib2/src/external/ois/OISPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/OISPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/OISPrereqs.h	(revision 8284)
@@ -79,7 +79,13 @@
 #	endif
 #elif defined( __APPLE_CC__ ) // Apple OS X
-#	define OIS_APPLE_PLATFORM
-#	undef _OISExport
-#	define _OISExport __attribute__((visibility("default")))
+    // Device                                       Simulator
+#   if __IPHONE_OS_VERSION_MIN_REQUIRED >= 20201 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000
+//#   if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000
+#       define OIS_IPHONE_PLATFORM
+#   else
+#       define OIS_APPLE_PLATFORM
+#   endif
+#   undef _OISExport
+#   define _OISExport __attribute__((visibility("default")))
 #else //Probably Linux
 #	define OIS_LINUX_PLATFORM
@@ -95,7 +101,7 @@
 //-------------- Common Classes, Enums, and Typdef's -------------------------//
 #define OIS_VERSION_MAJOR 1
-#define OIS_VERSION_MINOR 2 
+#define OIS_VERSION_MINOR 3
 #define OIS_VERSION_PATCH 0
-#define OIS_VERSION_NAME "Smash"
+#define OIS_VERSION_NAME "1.3.0"
 
 #define OIS_VERSION ((OIS_VERSION_MAJOR << 16) | (OIS_VERSION_MINOR << 8) | OIS_VERSION_PATCH)
@@ -110,6 +116,8 @@
 	class Mouse;
 	class JoyStick;
+    class MultiTouch;
 	class KeyListener;
 	class MouseListener;
+    class MultiTouchListener;
 	class JoyStickListener;
 	class Interface;
@@ -130,9 +138,10 @@
     enum Type
 	{
-		OISUnknown   = 0,
-		OISKeyboard  = 1,
-		OISMouse     = 2,
-		OISJoyStick  = 3,
-		OISTablet    = 4
+		OISUnknown       = 0,
+		OISKeyboard      = 1,
+		OISMouse         = 2,
+		OISJoyStick      = 3,
+		OISTablet        = 4,
+		OISMultiTouch    = 5
 	};
 
Index: /code/branches/kicklib2/src/external/ois/ReadMe.txt
===================================================================
--- /code/branches/kicklib2/src/external/ois/ReadMe.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/ReadMe.txt	(revision 8284)
@@ -5,5 +5,5 @@
 The zlib/libpng License
 
-Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
 
 This software is provided 'as-is', without any express or implied warranty. In no 
@@ -46,19 +46,14 @@
 Win32/
 	Contains Visual Studio .Net Solution Files
-	Contains CodeBlocks + MinGW + StlPort project files for OIS
+	Contains CodeBlocks project files for OIS
 	
 	---- Dependencies ------------------------------------------------------
 	DirectInput 8
-	Ogre & CEGUI 0.4.0 If building CEGUIOgre OIS Demo
 
-	SDL/
-		A test bed for an OIS InputManager with SDL as the backend. Not recommended;
-		however, useful for platforms with non-native OIS ports for temporary use.
 
 Linux/
 	---- Dependencies ------------------------------------------------------
 	X11
-	Ogre (GLX Platform) & CEGUI 0.4.0 If building CEGUIOgre OIS Demo
-        Newer Linux Kernel (2.6+ ?) for Event API - else, use --disable-joyevents
+        Newer Linux Kernel (2.6+ ?) for Event API
 
 	Steps to build on Linux:
@@ -69,7 +64,5 @@
 	---- Configure build options --------------------------------------------
 	./configure --help              --- List all configure options
-	./configure --disable-ogre      --- Disables CEGUIOgre ActionMapping Demo
-	./configure --disable-joyevents --- Uses /dev/input/jsX instead of 
-	                                    /dev/input/eventX
+
 
 LinuxCB/
@@ -80,8 +73,4 @@
 
 Mac/
-	
-	XCode-1.5/
-		Non-complete native OIS port.
-
 	XCode-2.2/
-		Working, complete, OIS port to OSX using SDL as a backend.
+		Working, mostly complete OSX vackend.
Index: /code/branches/kicklib2/src/external/ois/VERSION
===================================================================
--- /code/branches/kicklib2/src/external/ois/VERSION	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/VERSION	(revision 8284)
@@ -1,3 +1,2 @@
-OIS v1_2 CVS updated on 2009/01/24
-Note that this is not CVS HEAD, but v1_2 branch!
-
+OIS SVN v1.3 branch updated on 2011/02/20 (revision 32)
+https://wgois.svn.sourceforge.net/svnroot/wgois/ois/branches/v1-3/
Index: /code/branches/kicklib2/src/external/ois/changes_orxonox.diff
===================================================================
--- /code/branches/kicklib2/src/external/ois/changes_orxonox.diff	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/changes_orxonox.diff	(revision 8284)
@@ -10,4 +10,6 @@
  			//Ignorable Dll interface warning...
  #           if !defined(OIS_MINGW_COMPILER)
+
+
 --- linux/EventHelpers.cpp	(revision 5668)
 +++ linux/EventHelpers.cpp	(working copy)
@@ -37,5 +39,5 @@
 +++ win32/Win32ForceFeedback.cpp
 @@ -25,7 +25,7 @@
- #include <Math.h>
+ #include <math.h>
  
  // 0 = No trace; 1 = Important traces; 2 = Debug traces
@@ -45,2 +47,65 @@
  #if (defined (_DEBUG) || defined(OIS_WIN32_JOYFF_DEBUG))
    #include <iostream>
+
+
+--- win32/Win32JoyStick.cpp
++++ win32/Win32JoyStick.cpp
+@@ -26,6 +26,14 @@
+ #include "OISEvents.h"
+ #include "OISException.h"
+ 
++// (Orxonox): Required for MinGW to compile properly
++#ifdef __MINGW32__
++#  include <oaidl.h>
++#  ifndef __MINGW_EXTENSION
++#    define __MINGW_EXTENSION __extension__
++#  endif
++#endif
++
+ #include <cassert>
+ #include <wbemidl.h>
+ #include <oleauto.h>
+@@ -39,6 +47,11 @@
+    }
+ #endif
+ 
++// (Orxonox): MinGW doesn't have swscanf_s
++#ifdef __MINGW32__
++#	define swscanf_s swscanf
++#endif
++
+ #ifdef OIS_WIN32_XINPUT_SUPPORT
+ #	pragma comment(lib, "xinput.lib")
+ #endif
+@@ -583,7 +596,12 @@
+     bool bCleanupCOM = SUCCEEDED(hr);
+ 
+     // Create WMI
++    // (Orxonox): Fix for MinGW
++#ifdef __MINGW32__
++    hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pIWbemLocator);
++#else
+     hr = CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator);
++#endif
+     if( FAILED(hr) || pIWbemLocator == NULL )
+         goto LCleanup;
+ 
+
+--- mac/MacHIDManager.cpp
++++ mac/MacHIDManager.cpp
+@@ -406,6 +406,7 @@
+ 			switch(iType)
+ 			{
+ 				case OISJoyStick:
++                {
+ 					int totalDevs = totalDevices(iType);
+ 					int freeDevs = freeDevices(iType);
+ 					int devID = totalDevs - freeDevs;
+@@ -413,6 +414,7 @@
+ 					obj = new MacJoyStick((*it)->combinedKey, bufferMode, *it, creator, devID);
+ 					(*it)->inUse = true;
+ 					return obj;
++                }
+ 				case OISTablet:
+ 					//Create MacTablet
+ 					break;
Index: /code/branches/kicklib2/src/external/ois/linux/LinuxInputManager.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/linux/LinuxInputManager.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/linux/LinuxInputManager.cpp	(revision 8284)
@@ -40,5 +40,4 @@
 	hideMouse = true;
 	mGrabs = true;
-	useXRepeat = false;
 	keyboardUsed = mouseUsed = false;
 
@@ -74,9 +73,4 @@
 
 	//--------- Keyboard Settings ------------//
-	i = paramList.find("XAutoRepeatOn");
-	if( i != paramList.end() )
-		if( i->second == "true" )
-			useXRepeat = true;
-
 	i = paramList.find("x11_keyboard_grab");
 	if( i != paramList.end() )
@@ -172,5 +166,5 @@
 	{
 		if( keyboardUsed == false )
-			obj = new LinuxKeyboard(this, bufferMode, grabKeyboard, useXRepeat);
+			obj = new LinuxKeyboard(this, bufferMode, grabKeyboard);
 		break;
 	}
Index: /code/branches/kicklib2/src/external/ois/linux/LinuxInputManager.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/linux/LinuxInputManager.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/linux/LinuxInputManager.h	(revision 8284)
@@ -101,7 +101,4 @@
 		bool mGrabs;
 		bool hideMouse;
-
-		//! By default, keyboard disables XRepeatRate
-		bool useXRepeat;
 	};
 }
Index: /code/branches/kicklib2/src/external/ois/linux/LinuxJoyStickEvents.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/linux/LinuxJoyStickEvents.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/linux/LinuxJoyStickEvents.cpp	(revision 8284)
@@ -96,104 +96,107 @@
 	//We are in non blocking mode - we just read once, and try to fill up buffer
 	input_event js[JOY_BUFFERSIZE];
-	int ret = read(mJoyStick, &js, sizeof(struct input_event) * JOY_BUFFERSIZE);
-	if( ret <= 0 )
-		return;
-
-	//Determine how many whole events re read up
-	ret /= sizeof(struct input_event);
-	for(int i = 0; i < ret; ++i)
+	while(true)
 	{
-		switch(js[i].type)
+		int ret = read(mJoyStick, &js, sizeof(struct input_event) * JOY_BUFFERSIZE);
+        if( ret < 0 )
+			break;
+
+		//Determine how many whole events re read up
+		ret /= sizeof(struct input_event);
+		for(int i = 0; i < ret; ++i)
 		{
-		case EV_KEY:  //Button
-		{
-			int button = mButtonMap[js[i].code];
-
-			#ifdef OIS_LINUX_JOY_DEBUG
-			  cout << "\nButton Code: " << js[i].code << ", OIS Value: " << button << endl;
-			#endif
-
-			//Check to see whether push or released event...
-			if(js[i].value)
-			{
-				mState.mButtons[button] = true;
-				if( mBuffered && mListener )
-					if(!mListener->buttonPressed(JoyStickEvent(this,mState), button)) return;
-			}
-			else
-			{
-				mState.mButtons[button] = false;
-				if( mBuffered && mListener )
-					if(!mListener->buttonReleased(JoyStickEvent(this,mState), button)) return;
-			}
-			break;
-		}
-
-		case EV_ABS:  //Absolute Axis
-		{
-			//A Stick (BrakeDefine is the highest possible Axis)
-			if( js[i].code <= ABS_BRAKE )
-			{
-				int axis = mAxisMap[js[i].code];
-				assert( axis < 32 && "Too many axes (Max supported is 32). Report this to OIS forums!" );
-
-				axisMoved[axis] = true;
-
-				//check for rescaling:
-				if( mRanges[axis].min == JoyStick::MIN_AXIS && mRanges[axis].max != JoyStick::MAX_AXIS )
-				{	//Scale is perfect
-					mState.mAxes[axis].abs = js[i].value;
+			switch(js[i].type)
+			{
+			case EV_KEY:  //Button
+			{
+				int button = mButtonMap[js[i].code];
+
+				#ifdef OIS_LINUX_JOY_DEBUG
+				  cout << "\nButton Code: " << js[i].code << ", OIS Value: " << button << endl;
+				#endif
+
+				//Check to see whether push or released event...
+				if(js[i].value)
+				{
+					mState.mButtons[button] = true;
+					if( mBuffered && mListener )
+						if(!mListener->buttonPressed(JoyStickEvent(this,mState), button)) return;
 				}
 				else
-				{	//Rescale
-					float proportion = (float)(js[i].value-mRanges[axis].max)/(float)(mRanges[axis].min-mRanges[axis].max);
-					mState.mAxes[axis].abs = (int)(32767.0f - (65535.0f * proportion));
+				{
+					mState.mButtons[button] = false;
+					if( mBuffered && mListener )
+						if(!mListener->buttonReleased(JoyStickEvent(this,mState), button)) return;
 				}
-			}
-			else if( js[i].code <= ABS_HAT3Y ) //A POV - Max four POVs allowed
-			{
-				//Normalise the POV to between 0-7
-				//Even is X Axis, Odd is Y Axis
-				unsigned char LinuxPovNumber = js[i].code - 16;
-				short OIS_POVIndex = POV_MASK[LinuxPovNumber];
-
-				//Handle X Axis first (Even) (left right)
-				if((LinuxPovNumber & 0x0001) == 0)
+				break;
+			}
+
+			case EV_ABS:  //Absolute Axis
+			{
+				//A Stick (BrakeDefine is the highest possible Axis)
+				if( js[i].code <= ABS_BRAKE )
 				{
-					//Why do this? Because, we use a bit field, and when this axis is east,
-					//it can't possibly be west too. So clear out the two X axes, then refil
-					//it in with the new direction bit.
-					//Clear the East/West Bit Flags first
-					mState.mPOV[OIS_POVIndex].direction &= 0x11110011;
-					if( js[i].value == -1 )	//Left
-						mState.mPOV[OIS_POVIndex].direction |= Pov::West;
-					else if( js[i].value == 1 ) //Right
-						mState.mPOV[OIS_POVIndex].direction |= Pov::East;
+					int axis = mAxisMap[js[i].code];
+					assert( axis < 32 && "Too many axes (Max supported is 32). Report this to OIS forums!" );
+
+					axisMoved[axis] = true;
+
+					//check for rescaling:
+					if( mRanges[axis].min == JoyStick::MIN_AXIS && mRanges[axis].max != JoyStick::MAX_AXIS )
+					{	//Scale is perfect
+						mState.mAxes[axis].abs = js[i].value;
+					}
+					else
+					{	//Rescale
+						float proportion = (float)(js[i].value-mRanges[axis].max)/(float)(mRanges[axis].min-mRanges[axis].max);
+						mState.mAxes[axis].abs = (int)(32767.0f - (65535.0f * proportion));
+					}
 				}
-				//Handle Y Axis (Odd) (up down)
-				else
+				else if( js[i].code <= ABS_HAT3Y ) //A POV - Max four POVs allowed
 				{
-					//Clear the North/South Bit Flags first
-					mState.mPOV[OIS_POVIndex].direction &= 0x11111100;
-					if( js[i].value == -1 )	//Up
-						mState.mPOV[OIS_POVIndex].direction |= Pov::North;
-					else if( js[i].value == 1 ) //Down
-						mState.mPOV[OIS_POVIndex].direction |= Pov::South;
+					//Normalise the POV to between 0-7
+					//Even is X Axis, Odd is Y Axis
+					unsigned char LinuxPovNumber = js[i].code - 16;
+					short OIS_POVIndex = POV_MASK[LinuxPovNumber];
+
+					//Handle X Axis first (Even) (left right)
+					if((LinuxPovNumber & 0x0001) == 0)
+					{
+						//Why do this? Because, we use a bit field, and when this axis is east,
+						//it can't possibly be west too. So clear out the two X axes, then refil
+						//it in with the new direction bit.
+						//Clear the East/West Bit Flags first
+						mState.mPOV[OIS_POVIndex].direction &= 0x11110011;
+						if( js[i].value == -1 )	//Left
+							mState.mPOV[OIS_POVIndex].direction |= Pov::West;
+						else if( js[i].value == 1 ) //Right
+							mState.mPOV[OIS_POVIndex].direction |= Pov::East;
+					}
+					//Handle Y Axis (Odd) (up down)
+					else
+					{
+						//Clear the North/South Bit Flags first
+						mState.mPOV[OIS_POVIndex].direction &= 0x11111100;
+						if( js[i].value == -1 )	//Up
+							mState.mPOV[OIS_POVIndex].direction |= Pov::North;
+						else if( js[i].value == 1 ) //Down
+							mState.mPOV[OIS_POVIndex].direction |= Pov::South;
+					}
+
+					if( mBuffered && mListener )
+						if( mListener->povMoved( JoyStickEvent(this,mState), OIS_POVIndex) == false )
+							return;
 				}
-
-				if( mBuffered && mListener )
-					if( mListener->povMoved( JoyStickEvent(this,mState), OIS_POVIndex) == false )
-						return;
-			}
-			break;
-		}
-
-		
-		case EV_REL: //Relative Axes (Do any joystick actually have a relative axis?)
-#ifdef OIS_LINUX_JOY_DEBUG
-		    cout << "\nWarning: Relatives axes not supported yet" << endl;
-#endif
-			break;
-		default: break;
+				break;
+			}
+
+			
+			case EV_REL: //Relative Axes (Do any joystick actually have a relative axis?)
+	#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "\nWarning: Relatives axes not supported yet" << endl;
+	#endif
+				break;
+			default: break;
+			}
 		}
 	}
Index: /code/branches/kicklib2/src/external/ois/linux/LinuxKeyboard.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/linux/LinuxKeyboard.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/linux/LinuxKeyboard.cpp	(revision 8284)
@@ -33,5 +33,5 @@
 #include <iostream>
 //-------------------------------------------------------------------//
-LinuxKeyboard::LinuxKeyboard(InputManager* creator, bool buffered, bool grab, bool useXRepeat)
+LinuxKeyboard::LinuxKeyboard(InputManager* creator, bool buffered, bool grab)
 	: Keyboard(creator->inputSystemName(), buffered, 0, creator)
 {
@@ -43,7 +43,4 @@
 	grabKeyboard = grab;
 	keyFocusLost = false;
-
-	xAutoRepeat = useXRepeat;
-	oldXAutoRepeat = false;
 
 	//X Key Map to KeyCode
@@ -213,18 +210,4 @@
 
 	keyFocusLost = false;
-
-	if( xAutoRepeat == false )
-	{
-		//We do not want to blindly turn on autorepeat later when quiting if
-		//it was not on to begin with.. So, let us check and see first
-		XKeyboardState old;
-		XGetKeyboardControl( display, &old );
-		oldXAutoRepeat = false;
-
-		if( old.global_auto_repeat == AutoRepeatModeOn )
-			oldXAutoRepeat = true;
-
-		XAutoRepeatOff( display );
-	}
 }
 
@@ -234,7 +217,4 @@
 	if( display )
 	{
-		if( oldXAutoRepeat )
-			XAutoRepeatOn(display);
-
 		if( grabKeyboard )
 			XUngrabKeyboard(display, CurrentTime);
@@ -303,9 +283,12 @@
 
 	while( XPending(display) > 0 )
-	{ 		XNextEvent(display, &event);  		if( KeyPress == event.type )
+	{
+		XNextEvent(display, &event);
+
+		if(KeyPress == event.type)
 		{
 			unsigned int character = 0;
 
-			if( mTextMode != Off )
+			if(mTextMode != Off)
 			{
 				unsigned char buffer[6] = {0,0,0,0,0,0};
@@ -332,13 +315,17 @@
 			if( event.xkey.state & Mod1Mask && key == XK_Tab )
 				linMan->_setGrabState(false);
-		} 		else if( KeyRelease == event.type )
+		}
+		else if(KeyRelease == event.type)
 		{
-			//Mask out the modifier states X sets.. or we will get improper values
-			event.xkey.state &= ~ShiftMask;
-			event.xkey.state &= ~LockMask;
-
-			//Else, it is a valid key release
-			XLookupString(&event.xkey,NULL,0,&key,NULL);
-			_injectKeyUp(key); 		}
+			if(!_isKeyRepeat(event))
+			{
+				//Mask out the modifier states X sets.. or we will get improper values
+				event.xkey.state &= ~ShiftMask;
+				event.xkey.state &= ~LockMask;
+
+				XLookupString(&event.xkey,NULL,0,&key,NULL);
+				_injectKeyUp(key);
+			}
+		}
 	}
 
Index: /code/branches/kicklib2/src/external/ois/linux/LinuxKeyboard.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/linux/LinuxKeyboard.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/linux/LinuxKeyboard.h	(revision 8284)
@@ -34,5 +34,5 @@
 	{
 	public:
-		LinuxKeyboard(InputManager* creator, bool buffered, bool grab, bool useXRepeat );
+		LinuxKeyboard(InputManager* creator, bool buffered, bool grab);
 		virtual ~LinuxKeyboard();
 
@@ -59,4 +59,21 @@
 
 	protected:
+		inline bool _isKeyRepeat(XEvent &event)
+		{
+			//When a key is repeated, there will be two events: released, followed by another immediate pressed. So check to see if another pressed is present	
+			if(!XPending(display))
+				return false;
+
+			XEvent e;
+			XPeekEvent(display, &e);
+			if(e.type == KeyPress && e.xkey.keycode == event.xkey.keycode && (e.xkey.time - event.xkey.time) < 2)
+			{
+				XNextEvent(display, &e);
+				return true;
+			}
+
+			return false;
+		}
+
 		bool _injectKeyDown( KeySym key, int text );
 		bool _injectKeyUp( KeySym key );
@@ -75,7 +92,4 @@
 		bool keyFocusLost;
 
-		bool xAutoRepeat;
-		bool oldXAutoRepeat;
-
 		std::string mGetString;
 	};
Index: /code/branches/kicklib2/src/external/ois/linux/LinuxMouse.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/linux/LinuxMouse.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/linux/LinuxMouse.cpp	(revision 8284)
@@ -173,6 +173,6 @@
 
 			//Compute this frames Relative X & Y motion
-			mState.X.rel = event.xmotion.x - oldXMouseX;
-			mState.Y.rel = event.xmotion.y - oldXMouseY;
+			int dx = event.xmotion.x - oldXMouseX;
+			int dy = event.xmotion.y - oldXMouseY;
 		
 			//Store old values for next time to compute relative motion
@@ -180,6 +180,8 @@
 			oldXMouseY = event.xmotion.y;
 
-			mState.X.abs += mState.X.rel;
-			mState.Y.abs += mState.Y.rel;
+			mState.X.abs += dx;
+			mState.Y.abs += dy;
+			mState.X.rel += dx;
+			mState.Y.rel += dy;
 
 			//Check to see if we are grabbing the mouse to the window (requires clipping and warping)
Index: /code/branches/kicklib2/src/external/ois/linux/LinuxPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/linux/LinuxPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/linux/LinuxPrereqs.h	(revision 8284)
@@ -32,5 +32,5 @@
 
 //! Max number of elements to collect from buffered input
-#define JOY_BUFFERSIZE 10
+#define JOY_BUFFERSIZE 64
 
 namespace OIS
Index: /code/branches/kicklib2/src/external/ois/mac/CMakeLists.txt
===================================================================
--- /code/branches/kicklib2/src/external/ois/mac/CMakeLists.txt	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/mac/CMakeLists.txt	(revision 8284)
@@ -3,14 +3,16 @@
   MacHIDManager.h
   MacInputManager.h
+  MacJoyStick.h
   MacKeyboard.h
   MacMouse.h
   MacPrereqs.h
 
-COMPILATION_BEGIN OISMacCompilation.cpp
+#COMPILATION_BEGIN OISMacCompilation.cpp
   MacHelpers.cpp
   MacHIDManager.cpp
   MacInputManager.cpp
+  MacJoyStick.cpp
   MacKeyboard.cpp
   MacMouse.cpp
-COMPILATION_END
+#COMPILATION_END
 )
Index: /code/branches/kicklib2/src/external/ois/mac/MacHIDManager.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/mac/MacHIDManager.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/mac/MacHIDManager.cpp	(revision 8284)
@@ -20,6 +20,7 @@
  
  3. This notice may not be removed or altered from any source distribution.
-*/
+ */
 #include "mac/MacHIDManager.h"
+#include "mac/MacJoyStick.h"
 #include "OISException.h"
 #include "OISObject.h"
@@ -42,5 +43,5 @@
 {
 	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
-
+	
 	if(temp && CFGetTypeID(temp) == CFArrayGetTypeID())
 		return (CFArrayRef)temp;
@@ -53,5 +54,5 @@
 {
 	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
-
+	
 	if(temp && CFGetTypeID(temp) == CFStringGetTypeID())
 		return (CFStringRef)temp;
@@ -64,5 +65,5 @@
 {
 	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
-
+	
 	if(temp && CFGetTypeID(temp) == CFNumberGetTypeID())
 		return (CFNumberRef)temp;
@@ -83,5 +84,5 @@
 {
 	CFTypeRef temp = CFArrayGetValueAtIndex(array, idx);
-
+	
 	if(temp && CFGetTypeID(temp) == CFDictionaryGetTypeID())
 		return (CFDictionaryRef)temp;
@@ -93,8 +94,8 @@
 int getInt32(CFNumberRef ref)
 {
-   int r = 0;
-   if (r) 
-      CFNumberGetValue(ref, kCFNumberIntType, &r);
-   return r;
+	int r = 0;
+	if (r) 
+		CFNumberGetValue(ref, kCFNumberIntType, &r);
+	return r;
 }
 
@@ -111,69 +112,96 @@
 //------------------------------------------------------------------------------------------------------//
 void MacHIDManager::initialize()
+{
+	//Make the search more specific by adding usage flags
+	int usage = kHIDUsage_GD_Joystick;
+	int page = kHIDPage_GenericDesktop;
+	
+	io_iterator_t iterator = lookUpDevices(usage, page);
+	
+	if(iterator)
+		iterateAndOpenDevices(iterator);
+	
+	//Doesn't support multiple usage flags, iterate twice
+	usage = kHIDUsage_GD_GamePad;
+	iterator = lookUpDevices(usage, page);
+	
+	if(iterator)
+		iterateAndOpenDevices(iterator);
+}
+
+//------------------------------------------------------------------------------------------------------//
+io_iterator_t MacHIDManager::lookUpDevices(int usage, int page)
 {
 	CFMutableDictionaryRef deviceLookupMap = IOServiceMatching(kIOHIDDeviceKey);
 	if(!deviceLookupMap)
 		OIS_EXCEPT(E_General, "Could not setup HID device search parameters");
-
-	//Make the search more specific by adding usage flags
-	int usage = kHIDUsage_GD_GamePad | kHIDUsage_GD_Joystick,
-	    page  = kHIDPage_GenericDesktop;
-
-	CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage),
-				pageRef  = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
-
+	
+	CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
+	CFNumberRef pageRef  = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
+	
 	CFDictionarySetValue(deviceLookupMap, CFSTR(kIOHIDPrimaryUsageKey), usageRef);
 	CFDictionarySetValue(deviceLookupMap, CFSTR(kIOHIDPrimaryUsagePageKey), pageRef);
-
+	
 	//IOServiceGetMatchingServices consumes the map so we do not have to release it ourself
 	io_iterator_t iterator = 0;
 	IOReturn result = IOServiceGetMatchingServices(kIOMasterPortDefault, deviceLookupMap, &iterator);
-	if (result == kIOReturnSuccess && iterator)
-	{
-		io_object_t hidDevice = 0;
-		while ((hidDevice = IOIteratorNext(iterator)) !=0)
+	
+	CFRelease(usageRef);
+	CFRelease(pageRef);
+	
+	if(result == kIOReturnSuccess)
+	{
+		return iterator;
+	}
+	//TODO: Throw exception instead?
+	else
+	{
+		return 0;
+	}
+}
+
+//------------------------------------------------------------------------------------------------------//
+void MacHIDManager::iterateAndOpenDevices(io_iterator_t iterator)
+{
+	io_object_t hidDevice = 0;
+	while ((hidDevice = IOIteratorNext(iterator)) !=0)
+	{
+		//Get the current registry items property map
+		CFMutableDictionaryRef propertyMap = 0;
+		if (IORegistryEntryCreateCFProperties(hidDevice, &propertyMap, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS && propertyMap)
 		{
-			//Get the current registry items property map
-			CFMutableDictionaryRef propertyMap = 0;
-			if (IORegistryEntryCreateCFProperties(hidDevice, &propertyMap, kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS && propertyMap)
+			//Go through device to find all needed info
+			HidInfo* hid = enumerateDeviceProperties(propertyMap);
+			
+			if(hid)
 			{
-				//Go through device to find all needed info
-				HidInfo* hid = enumerateDeviceProperties(propertyMap);
-				if(hid)
-					mDeviceList.push_back(hid);
-					
 				//todo - we need to hold an open interface so we do not have to enumerate again later
 				//should be able to watch for device removals also
-
-				/// Testing opening / closing interface
-				//IOCFPlugInInterface **pluginInterface = NULL;
-				//SInt32 score = 0;
-				//if (IOCreatePlugInInterfaceForService(hidDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &pluginInterface, &score) == kIOReturnSuccess)
-				//{
-				//	IOHIDDeviceInterface **interface;
-				//	HRESULT pluginResult = (*pluginInterface)->QueryInterface(pluginInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void **)&(interface));
-				//	if(pluginResult == S_OK)
-				//		cout << "Successfully created plugin interface for device\n";
-				//	else
-				//		cout << "Not able to create plugin interface\n";
-
-				//	IODestroyPlugInInterface(pluginInterface);
-
-				//	if ((*interface)->open(interface, 0) == KERN_SUCCESS)
-				//		cout << "Opened interface.\n";
-				//	else
-				//		cout << "Failed to open\n";
-
-				//	(*interface)->close(interface);
-				//}
-				//
+				
+				// Testing opening / closing interface
+				IOCFPlugInInterface **pluginInterface = NULL;
+				SInt32 score = 0;
+				if (IOCreatePlugInInterfaceForService(hidDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &pluginInterface, &score) == kIOReturnSuccess)
+				{
+					IOHIDDeviceInterface **interface;
+					
+					HRESULT pluginResult = (*pluginInterface)->QueryInterface(pluginInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void **)&(interface));
+					
+					if(pluginResult != S_OK)
+						OIS_EXCEPT(E_General, "Not able to create plugin interface");
+					
+					IODestroyPlugInInterface(pluginInterface);
+					
+					hid->interface = interface;
+					
+					//Check for duplicates - some devices have multiple usage
+					if(std::find(mDeviceList.begin(), mDeviceList.end(), hid) == mDeviceList.end())
+						mDeviceList.push_back(hid);
+				}
 			}
 		}
-
-		IOObjectRelease(iterator);
-	}
-
-	CFRelease(usageRef);
-	CFRelease(pageRef);
+	}
+	
+	IOObjectRelease(iterator);
 }
 
@@ -188,11 +216,11 @@
 	if (str)
 		info->vendor = CFStringGetCStringPtr(str, CFStringGetSystemEncoding());
-
+	
 	str = getDictionaryItemAsRef<CFStringRef>(propertyMap, kIOHIDProductKey);
 	if (str)
 		info->productKey = CFStringGetCStringPtr(str, CFStringGetSystemEncoding());
-		
+	
 	info->combinedKey = info->vendor + " " + info->productKey;
-
+	
 	//Go through all items in this device (i.e. buttons, hats, sticks, axes, etc)
 	CFArrayRef array = getDictionaryItemAsRef<CFArrayRef>(propertyMap, kIOHIDElementKey);
@@ -200,5 +228,5 @@
 		for (int i = 0; i < CFArrayGetCount(array); i++)
 			parseDeviceProperties(getArrayItemAsRef<CFDictionaryRef>(array, i));
-
+	
 	return info;
 }
@@ -209,5 +237,5 @@
 	if(!properties)
 		return;
-
+	
 	CFArrayRef array = getDictionaryItemAsRef<CFArrayRef>(properties, kIOHIDElementKey);
 	if (array)
@@ -227,32 +255,32 @@
 					switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsagePageKey)))
 					{
-					case kHIDPage_GenericDesktop:
-						switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsageKey)))
+						case kHIDPage_GenericDesktop:
+							switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsageKey)))
 						{
-						case kHIDUsage_GD_Pointer:
-							cout << "\tkHIDUsage_GD_Pointer\n";
-							parseDevicePropertiesGroup(element);
+							case kHIDUsage_GD_Pointer:
+								cout << "\tkHIDUsage_GD_Pointer\n";
+								parseDevicePropertiesGroup(element);
+								break;
+							case kHIDUsage_GD_X:
+							case kHIDUsage_GD_Y:
+							case kHIDUsage_GD_Z:
+							case kHIDUsage_GD_Rx:
+							case kHIDUsage_GD_Ry:
+							case kHIDUsage_GD_Rz:
+								cout << "\tAxis\n";
+								break;
+							case kHIDUsage_GD_Slider:
+							case kHIDUsage_GD_Dial:
+							case kHIDUsage_GD_Wheel:
+								cout << "\tUnsupported kHIDUsage_GD_Wheel\n";
+								break;
+							case kHIDUsage_GD_Hatswitch:
+								cout << "\tUnsupported - kHIDUsage_GD_Hatswitch\n";
+								break;
+						}
 							break;
-						case kHIDUsage_GD_X:
-						case kHIDUsage_GD_Y:
-						case kHIDUsage_GD_Z:
-						case kHIDUsage_GD_Rx:
-						case kHIDUsage_GD_Ry:
-						case kHIDUsage_GD_Rz:
-							cout << "\tAxis\n";
+						case kHIDPage_Button:
+							cout << "\tkHIDPage_Button\n";
 							break;
-						case kHIDUsage_GD_Slider:
-						case kHIDUsage_GD_Dial:
-						case kHIDUsage_GD_Wheel:
-							cout << "\tUnsupported kHIDUsage_GD_Wheel\n";
-							break;
-						case kHIDUsage_GD_Hatswitch:
-							cout << "\tUnsupported - kHIDUsage_GD_Hatswitch\n";
-							break;
-						}
-						break;
-					case kHIDPage_Button:
-						cout << "\tkHIDPage_Button\n";
-						break;
 					}
 				}
@@ -267,5 +295,5 @@
 	if(!properties)
 		return;
-
+	
 	CFArrayRef array = getDictionaryItemAsRef<CFArrayRef>(properties, kIOHIDElementKey);
 	if(array)
@@ -278,27 +306,27 @@
 				switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsagePageKey)))
 				{
-				case kHIDPage_GenericDesktop:
-					switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsageKey)))
+					case kHIDPage_GenericDesktop:
+						switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsageKey)))
 					{
-					case kHIDUsage_GD_X:
-					case kHIDUsage_GD_Y:
-					case kHIDUsage_GD_Z:
-					case kHIDUsage_GD_Rx:
-					case kHIDUsage_GD_Ry:
-					case kHIDUsage_GD_Rz:
-						cout << "\t\tAxis\n";
+						case kHIDUsage_GD_X:
+						case kHIDUsage_GD_Y:
+						case kHIDUsage_GD_Z:
+						case kHIDUsage_GD_Rx:
+						case kHIDUsage_GD_Ry:
+						case kHIDUsage_GD_Rz:
+							cout << "\t\tAxis\n";
+							break;
+						case kHIDUsage_GD_Slider:
+						case kHIDUsage_GD_Dial:
+						case kHIDUsage_GD_Wheel:
+							cout << "\tUnsupported - kHIDUsage_GD_Wheel\n";
+							break;
+						case kHIDUsage_GD_Hatswitch:
+							cout << "\tUnsupported - kHIDUsage_GD_Hatswitch\n";
+							break;
+					}
 						break;
-					case kHIDUsage_GD_Slider:
-					case kHIDUsage_GD_Dial:
-					case kHIDUsage_GD_Wheel:
-						cout << "\tUnsupported - kHIDUsage_GD_Wheel\n";
+					case kHIDPage_Button:
 						break;
-					case kHIDUsage_GD_Hatswitch:
-						cout << "\tUnsupported - kHIDUsage_GD_Hatswitch\n";
-						break;
-					}
-					break;
-				case kHIDPage_Button:
-					break;
 				}
 			}
@@ -317,5 +345,5 @@
 			ret.insert(std::make_pair((*it)->type, (*it)->combinedKey));
 	}
-
+	
 	return ret;
 }
@@ -326,5 +354,5 @@
 	int ret = 0;
 	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
-
+	
 	for(; it != end; ++it)
 	{
@@ -341,5 +369,5 @@
 	int ret = 0;
 	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
-
+	
 	for(; it != end; ++it)
 	{
@@ -347,5 +375,5 @@
 			ret++;
 	}
-
+	
 	return ret;
 }
@@ -355,5 +383,5 @@
 {
 	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
-
+	
 	for(; it != end; ++it)
 	{
@@ -367,8 +395,8 @@
 //--------------------------------------------------------------------------------//
 Object* MacHIDManager::createObject(InputManager* creator, Type iType, bool bufferMode, 
-									  const std::string & vendor)
+									const std::string & vendor)
 {
 	Object *obj = 0;
-
+	
 	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
 	for(; it != end; ++it)
@@ -376,11 +404,25 @@
 		if((*it)->inUse == false && (*it)->type == iType && (vendor == "" || (*it)->combinedKey == vendor))
 		{
-			//create device
+			switch(iType)
+			{
+				case OISJoyStick:
+                {
+					int totalDevs = totalDevices(iType);
+					int freeDevs = freeDevices(iType);
+					int devID = totalDevs - freeDevs;
+					
+					obj = new MacJoyStick((*it)->combinedKey, bufferMode, *it, creator, devID);
+					(*it)->inUse = true;
+					return obj;
+                }
+				case OISTablet:
+					//Create MacTablet
+					break;
+				default:
+					break;
+			}
 		}
 	}
-
-	if( obj == 0 )
-		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
-
+	
 	return obj;
 }
Index: /code/branches/kicklib2/src/external/ois/mac/MacHIDManager.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/mac/MacHIDManager.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/mac/MacHIDManager.h	(revision 8284)
@@ -70,4 +70,7 @@
 
 		void initialize();
+		
+		void iterateAndOpenDevices(io_iterator_t iterator);
+		io_iterator_t lookUpDevices(int usage, int page);
 
 		//FactoryCreator Overrides
Index: /code/branches/kicklib2/src/external/ois/mac/MacInputManager.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/mac/MacInputManager.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/mac/MacInputManager.cpp	(revision 8284)
@@ -188,5 +188,8 @@
 	}
 	default:
+	{
+		obj = mHIDManager->createObject(creator, iType, bufferMode, vendor);
 		break;
+	}
 	}
 
Index: /code/branches/kicklib2/src/external/ois/mac/MacJoyStick.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/mac/MacJoyStick.cpp	(revision 8284)
+++ /code/branches/kicklib2/src/external/ois/mac/MacJoyStick.cpp	(revision 8284)
@@ -0,0 +1,325 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+ 
+ 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 "mac/MacJoyStick.h"
+#include "mac/MacHIDManager.h"
+#include "mac/MacInputManager.h"
+#include "OISEvents.h"
+#include "OISException.h"
+
+#include <cassert>
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------------------------//
+MacJoyStick::MacJoyStick(const std::string &vendor, bool buffered, HidInfo* info, InputManager* creator, int devID) : 
+JoyStick(vendor, buffered, devID, creator), mInfo(info)
+{
+	
+}
+
+//--------------------------------------------------------------------------------------------------//
+MacJoyStick::~MacJoyStick()
+{
+	//TODO: check if the queue has been started first?
+	//(*mQueue)->stop(mQueue); 
+	(*mQueue)->dispose(mQueue); 
+	(*mQueue)->Release(mQueue); 
+	
+	
+	//TODO: check if the interface has been opened first?
+	(*mInfo->interface)->close(mInfo->interface);
+	(*mInfo->interface)->Release(mInfo->interface); 
+}
+
+//--------------------------------------------------------------------------------------------------//
+void MacJoyStick::_initialize()
+{
+	assert(mInfo && "Given HidInfo invalid");
+	assert(mInfo->interface && "Joystick interface invalid");
+	
+	//TODO: Is this necessary?
+	//Clear old state
+	mState.mAxes.clear();
+	
+	if ((*mInfo->interface)->open(mInfo->interface, 0) != KERN_SUCCESS)
+		OIS_EXCEPT(E_General, "MacJoyStick::_initialize() >> Could not initialize joy device!");
+	
+	mState.clear();
+	
+	_enumerateCookies();
+	
+	mState.mButtons.resize(mInfo->numButtons);
+	mState.mAxes.resize(mInfo->numAxes);
+	
+	mQueue = _createQueue();
+}
+
+class FindAxisCookie : public std::unary_function<std::pair<IOHIDElementCookie, AxisInfo>&, bool>
+{
+public:
+	FindAxisCookie(IOHIDElementCookie cookie) : m_Cookie(cookie) {}
+	bool operator()(const std::pair<IOHIDElementCookie, AxisInfo>& pair) const
+	{
+		return pair.first == m_Cookie;
+	}
+private:
+	IOHIDElementCookie m_Cookie;
+};
+
+//--------------------------------------------------------------------------------------------------//
+void MacJoyStick::capture()
+{
+	assert(mQueue && "Queue must be initialized before calling MacJoyStick::capture()");
+	
+	AbsoluteTime zeroTime = {0,0}; 
+	
+	IOHIDEventStruct event; 
+	IOReturn result = (*mQueue)->getNextEvent(mQueue, &event, zeroTime, 0); 
+	while(result == kIOReturnSuccess)
+	{
+		switch(event.type)
+		{
+			case kIOHIDElementTypeInput_Button:
+			{
+				std::vector<IOHIDElementCookie>::iterator buttonIt = std::find(mCookies.buttonCookies.begin(), mCookies.buttonCookies.end(), event.elementCookie);
+				int button = std::distance(mCookies.buttonCookies.begin(), buttonIt);
+				mState.mButtons[button] = (event.value == 1);
+				
+				if(mBuffered && mListener)
+				{
+					if(event.value == 0)
+						mListener->buttonPressed(JoyStickEvent(this, mState), button);
+					else if(event.value == 1)
+						mListener->buttonReleased(JoyStickEvent(this, mState), button);
+				}
+				break;
+			}
+			case kIOHIDElementTypeInput_Misc:
+				//TODO: It's an axis! - kind of - for gamepads - or should this be a pov?
+			case kIOHIDElementTypeInput_Axis:
+				std::map<IOHIDElementCookie, AxisInfo>::iterator axisIt = std::find_if(mCookies.axisCookies.begin(), mCookies.axisCookies.end(), FindAxisCookie(event.elementCookie));
+				int axis = std::distance(mCookies.axisCookies.begin(), axisIt);
+				
+				//Copied from LinuxJoyStickEvents.cpp, line 149
+				const AxisInfo& axisInfo = axisIt->second;
+				float proportion = (float) (event.value - axisInfo.max) / (float) (axisInfo.min - axisInfo.max);
+				mState.mAxes[axis].abs = -JoyStick::MIN_AXIS - (JoyStick::MAX_AXIS * 2 * proportion);
+				
+				if(mBuffered && mListener) mListener->axisMoved(JoyStickEvent(this, mState), axis);
+				break;
+		}
+		
+		result = (*mQueue)->getNextEvent(mQueue, &event, zeroTime, 0);
+	}
+}
+
+//--------------------------------------------------------------------------------------------------//
+void MacJoyStick::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//--------------------------------------------------------------------------------------------------//
+Interface* MacJoyStick::queryInterface(Interface::IType type)
+{
+	//Thought about using covariant return type here.. however,
+	//some devices may allow LED light changing, or other interface stuff
+	
+	//f( ff_device && type == Interface::ForceFeedback )
+	//return ff_device;
+	//else
+	return 0;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void MacJoyStick::_enumerateCookies()
+{
+	assert(mInfo && "Given HidInfo invalid");
+	assert(mInfo->interface && "Joystick interface invalid");
+	
+	CFTypeRef                               object; 
+	long                                    number; 
+	IOHIDElementCookie                      cookie; 
+	long                                    usage; 
+	long                                    usagePage;
+	int										min;
+	int										max;
+
+	CFDictionaryRef                         element; 
+	
+	// Copy all elements, since we're grabbing most of the elements 
+	// for this device anyway, and thus, it's faster to iterate them 
+	// ourselves. When grabbing only one or two elements, a matching 
+	// dictionary should be passed in here instead of NULL. 
+	CFArrayRef elements; 
+	IOReturn success = reinterpret_cast<IOHIDDeviceInterface122*>(*mInfo->interface)->copyMatchingElements(mInfo->interface, NULL, &elements); 
+	
+	if (success == kIOReturnSuccess)
+	{ 
+		const CFIndex numOfElements = CFArrayGetCount(elements);
+		for (CFIndex i = 0; i < numOfElements; ++i) 
+		{ 
+			element = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(elements, i));
+			
+			//Get cookie 
+			object = (CFDictionaryGetValue(element, 
+										   CFSTR(kIOHIDElementCookieKey))); 
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) 
+				continue; 
+			if(!CFNumberGetValue((CFNumberRef) object, kCFNumberLongType, 
+								 &number)) 
+				continue; 
+			cookie = (IOHIDElementCookie) number; 
+			
+			//Get usage 
+			object = CFDictionaryGetValue(element, 
+										  CFSTR(kIOHIDElementUsageKey)); 
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) 
+				continue; 
+			if (!CFNumberGetValue((CFNumberRef) object, kCFNumberLongType, 
+								  &number)) 
+				continue; 
+			usage = number; 
+			
+			//Get min
+			object = CFDictionaryGetValue(element,
+										  CFSTR(kIOHIDElementMinKey)); // kIOHIDElementMinKey or kIOHIDElementScaledMinKey?, no idea ...
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID())
+				continue;
+			if (!CFNumberGetValue((CFNumberRef) object, kCFNumberIntType,
+								  &number))
+				continue;
+			min = number;
+			
+			//Get max
+			object = CFDictionaryGetValue(element,
+										  CFSTR(kIOHIDElementMaxKey)); // kIOHIDElementMaxKey or kIOHIDElementScaledMaxKey?, no idea ...
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID())
+				continue;
+			if (!CFNumberGetValue((CFNumberRef) object, kCFNumberIntType,
+								  &number))
+				continue;
+			max = number;			
+			
+			//Get usage page 
+			object = CFDictionaryGetValue(element, 
+										  CFSTR(kIOHIDElementUsagePageKey)); 
+			
+			if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) 
+				continue; 
+			
+			if (!CFNumberGetValue((CFNumberRef) object, kCFNumberLongType, 
+								  &number)) 
+				continue; 
+			
+			usagePage = number;
+			switch(usagePage)
+			{
+				case kHIDPage_GenericDesktop:
+					switch(usage)
+				{
+					case kHIDUsage_GD_Pointer:
+						break;
+					case kHIDUsage_GD_X:
+					case kHIDUsage_GD_Y:
+					case kHIDUsage_GD_Z:
+					case kHIDUsage_GD_Rx:
+					case kHIDUsage_GD_Ry:
+					case kHIDUsage_GD_Rz:
+						mCookies.axisCookies.insert(std::make_pair(cookie, AxisInfo(min, max)));
+						break;
+					case kHIDUsage_GD_Slider:
+					case kHIDUsage_GD_Dial:
+					case kHIDUsage_GD_Wheel:
+						break;
+					case kHIDUsage_GD_Hatswitch:
+						break;
+				}
+					break;
+				case kHIDPage_Button:
+					mCookies.buttonCookies.push_back(cookie);
+					break;
+			}		
+		}
+		
+		mInfo->numButtons = mCookies.buttonCookies.size();
+		mInfo->numAxes = mCookies.axisCookies.size();
+
+	} 
+	else 
+	{ 
+		OIS_EXCEPT(E_General, "JoyStick elements could not be copied: copyMatchingElements failed with error: " + success); 
+	}
+	
+}
+
+//--------------------------------------------------------------------------------------------------//
+IOHIDQueueInterface** MacJoyStick::_createQueue(unsigned int depth)
+{	
+	assert(mInfo && "Given HidInfo invalid");
+	assert(mInfo->interface && "Joystick interface invalid");
+	
+	IOHIDQueueInterface** queue = (*mInfo->interface)->allocQueue(mInfo->interface); 
+	
+	if (queue) 
+	{		
+		//create the queue 
+		IOReturn result = (*queue)->create(queue, 0, depth); 
+		
+		if(result == kIOReturnSuccess)
+		{		
+			//add elements to the queue
+			std::map<IOHIDElementCookie, AxisInfo>::iterator axisIt = mCookies.axisCookies.begin();
+			for(; axisIt != mCookies.axisCookies.end(); ++axisIt)
+			{
+				result = (*queue)->addElement(queue, axisIt->first, 0);
+			}
+			
+			std::vector<IOHIDElementCookie>::iterator buttonIt = mCookies.buttonCookies.begin();
+			for(; buttonIt != mCookies.buttonCookies.end(); ++buttonIt)
+			{
+				result = (*queue)->addElement(queue, (*buttonIt), 0);
+			}
+
+			//start data delivery to queue 
+			result = (*queue)->start(queue); 
+			if(result == kIOReturnSuccess)
+			{
+				return queue;
+			}
+			else
+			{
+				OIS_EXCEPT(E_General, "Queue could not be started.");
+			}
+		}
+		else
+		{
+			OIS_EXCEPT(E_General, "Queue could not be created.");
+		}
+	}
+	else
+	{
+		OIS_EXCEPT(E_General, "Queue allocation failed.");
+	}
+}
Index: /code/branches/kicklib2/src/external/ois/mac/MacJoyStick.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/mac/MacJoyStick.h	(revision 8284)
+++ /code/branches/kicklib2/src/external/ois/mac/MacJoyStick.h	(revision 8284)
@@ -0,0 +1,76 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
+ 
+ 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 MAC_Joystick_H
+#define MAC_Joystick_H
+#include "OISJoyStick.h"
+#include "mac/MacPrereqs.h"
+#include "mac/MacHIDManager.h"
+
+namespace OIS
+{
+	struct AxisInfo
+	{
+		int min;
+		int max;
+		
+		AxisInfo(int min, int max)
+			: min(min), max(max) {}
+	};
+	
+	typedef struct cookie_struct 
+	{ 
+		std::map<IOHIDElementCookie, AxisInfo> axisCookies; 			
+		std::vector<IOHIDElementCookie> buttonCookies; 
+	} cookie_struct_t; 
+	
+	//class HidDeviceInfo
+	
+	class MacJoyStick : public JoyStick
+	{
+	public:
+		MacJoyStick(const std::string& vendor, bool buffered, HidInfo* info, InputManager* creator, int devID);
+		
+		virtual ~MacJoyStick();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+		
+		/** @copydoc Object::capture */
+		virtual void capture();
+		
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type);
+		
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+		
+		void _enumerateCookies();
+		
+		IOHIDQueueInterface** _createQueue(unsigned int depth = 8);
+	protected:
+		HidInfo* mInfo;
+		cookie_struct_t mCookies;
+		IOHIDQueueInterface** mQueue;
+	};
+}
+#endif
Index: /code/branches/kicklib2/src/external/ois/mac/MacKeyboard.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/mac/MacKeyboard.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/mac/MacKeyboard.cpp	(revision 8284)
@@ -199,17 +199,9 @@
 	char macChar;
 	
-	// TODO clean this up
 	if (mTextMode == Unicode)
 	{
 		//get string size
 		UInt32 stringsize;
-		//status = GetEventParameter( theEvent, 'kuni', typeUnicodeText, NULL, 0, &stringsize, NULL);
-		//status = GetEventParameter( theEvent, 'kuni', typeUnicodeText, NULL, sizeof(UniChar)*10, NULL, &text );
 		status = GetEventParameter( theEvent, 'kuni', typeUnicodeText, NULL, sizeof(UniChar) * 10, &stringsize, &text );
-		std::cout << "String length: " << stringsize << std::endl;
-		
-		//wstring unitext;
-		//for (int i=0;i<10;i++) unitext += (wchar_t)text[i];
-		//wcout << "Unicode out: " << unitext << endl;
 		
 		if(stringsize > 0)
Index: /code/branches/kicklib2/src/external/ois/win32/Win32ForceFeedback.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32ForceFeedback.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32ForceFeedback.cpp	(revision 8284)
@@ -21,7 +21,7 @@
     3. This notice may not be removed or altered from any source distribution.
 */
-#include "Win32/Win32ForceFeedback.h"
+#include "win32/Win32ForceFeedback.h"
 #include "OISException.h"
-#include <Math.h>
+#include <math.h>
 
 // 0 = No trace; 1 = Important traces; 2 = Debug traces
Index: /code/branches/kicklib2/src/external/ois/win32/Win32ForceFeedback.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32ForceFeedback.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32ForceFeedback.h	(revision 8284)
@@ -26,5 +26,5 @@
 #include "OISPrereqs.h"
 #include "OISForceFeedback.h"
-#include "Win32/Win32Prereqs.h"
+#include "win32/Win32Prereqs.h"
 
 namespace OIS
Index: /code/branches/kicklib2/src/external/ois/win32/Win32InputManager.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32InputManager.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32InputManager.cpp	(revision 8284)
@@ -21,8 +21,8 @@
     3. This notice may not be removed or altered from any source distribution.
 */
-#include "Win32/Win32InputManager.h"
-#include "Win32/Win32Keyboard.h"
-#include "Win32/Win32Mouse.h"
-#include "Win32/Win32JoyStick.h"
+#include "win32/Win32InputManager.h"
+#include "win32/Win32KeyBoard.h"
+#include "win32/Win32Mouse.h"
+#include "win32/Win32JoyStick.h"
 #include "OISException.h"
 
@@ -75,5 +75,5 @@
 	hInst = GetModuleHandle(0);
 
-	//Create the input system
+	//Create the device
 	hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
     if (FAILED(hr))	
@@ -118,5 +118,18 @@
 {
 	//Enumerate all attached devices
-	mDirectInput->EnumDevices(NULL , _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY); 
+	mDirectInput->EnumDevices(NULL, _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY);
+
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+	//let's check how many possible XInput devices we may have (max 4)... 
+	for(int i = 0; i < 3; ++i)
+	{
+		XINPUT_STATE state;
+		if(XInputGetState(i, &state) != ERROR_DEVICE_NOT_CONNECTED)
+		{	//Once we found 1, just check our whole list against devices
+			Win32JoyStick::CheckXInputDevices(unusedJoyStickList);
+			break;
+		}
+	}
+#endif
 }
 
@@ -134,4 +147,6 @@
 	{
 		JoyStickInfo jsInfo;
+		jsInfo.isXInput = false;
+		jsInfo.productGuid = lpddi->guidProduct;
 		jsInfo.deviceID = lpddi->guidInstance;
 		jsInfo.vendor = lpddi->tszInstanceName;
Index: /code/branches/kicklib2/src/external/ois/win32/Win32InputManager.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32InputManager.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32InputManager.h	(revision 8284)
@@ -26,5 +26,5 @@
 #include "OISInputManager.h"
 #include "OISFactoryCreator.h"
-#include "Win32/Win32Prereqs.h"
+#include "win32/Win32Prereqs.h"
 
 namespace OIS
Index: /code/branches/kicklib2/src/external/ois/win32/Win32JoyStick.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32JoyStick.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32JoyStick.cpp	(revision 8284)
@@ -21,11 +21,39 @@
     3. This notice may not be removed or altered from any source distribution.
 */
-#include "Win32/Win32JoyStick.h"
-#include "Win32/Win32InputManager.h"
-#include "Win32/Win32ForceFeedback.h"
+#include "win32/Win32JoyStick.h"
+#include "win32/Win32InputManager.h"
+#include "win32/Win32ForceFeedback.h"
 #include "OISEvents.h"
 #include "OISException.h"
 
+// (Orxonox): Required for MinGW to compile properly
+#ifdef __MINGW32__
+#  include <oaidl.h>
+#  ifndef __MINGW_EXTENSION
+#    define __MINGW_EXTENSION __extension__
+#  endif
+#endif
+
 #include <cassert>
+#include <wbemidl.h>
+#include <oleauto.h>
+//#include <wmsstd.h>
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(x) \
+   if(x != NULL)        \
+   {                    \
+      x->Release();     \
+      x = NULL;         \
+   }
+#endif
+
+// (Orxonox): MinGW doesn't have swscanf_s
+#ifdef __MINGW32__
+#	define swscanf_s swscanf
+#endif
+
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+#	pragma comment(lib, "xinput.lib")
+#endif
 
 //DX Only defines macros for the JOYSTICK not JOYSTICK2, so fix it
@@ -40,18 +68,18 @@
 #define DIJOFS_SLIDER3(n) (FIELD_OFFSET(DIJOYSTATE2, rglFSlider)+(n) * sizeof(LONG))
 
+#define XINPUT_TRANSLATED_BUTTON_COUNT 12
+#define XINPUT_TRANSLATED_AXIS_COUNT 6
+
 using namespace OIS;
 
 //--------------------------------------------------------------------------------------------------//
-Win32JoyStick::Win32JoyStick( InputManager* creator, IDirectInput8* pDI,
-	bool buffered, DWORD coopSettings, const JoyStickInfo &info )
-	: JoyStick(info.vendor, buffered, info.devId, creator)
-{
-	mDirectInput = pDI;
-	coopSetting = coopSettings;
-	mJoyStick = 0;
-
-	deviceGuid = info.deviceID;
-
-	ff_device = 0;
+Win32JoyStick::Win32JoyStick( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings, const JoyStickInfo &info ) :
+	JoyStick(info.vendor, buffered, info.devId, creator),
+	mDirectInput(pDI),
+	coopSetting(coopSettings),
+	mJoyStick(0),
+	mJoyInfo(info),
+	mFfDevice(0)
+{
 }
 
@@ -59,5 +87,5 @@
 Win32JoyStick::~Win32JoyStick()
 {
-	delete ff_device;
+	delete mFfDevice;
 
 	if(mJoyStick)
@@ -69,9 +97,5 @@
 
 	//Return joystick to pool
-	JoyStickInfo js;
-	js.deviceID = deviceGuid;
-	js.devId = mDevID;
-	js.vendor = mVendor;
-	static_cast<Win32InputManager*>(mCreator)->_returnJoyStick(js);
+	static_cast<Win32InputManager*>(mCreator)->_returnJoyStick(mJoyInfo);
 }
 
@@ -79,43 +103,45 @@
 void Win32JoyStick::_initialize()
 {
-	//Clear old state
-	mState.mAxes.clear();
-
-	if (ff_device)
-	{
-		delete ff_device;
-		ff_device = 0;
-	}
-
-	// Create direct input joystick device.
-	if(FAILED(mDirectInput->CreateDevice(deviceGuid, &mJoyStick, NULL)))
-		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!");
-
-	// Set DIJoystick2 data format.
-	if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2)))
-		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!");
-
-	// Set cooperative level as specified when creating input manager.
-	HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
-	if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting)))
-		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!");
-
-	// Set buffer size.
-	DIPROPDWORD dipdw;
-	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
-	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
-	dipdw.diph.dwObj        = 0;
-	dipdw.diph.dwHow        = DIPH_DEVICE;
-	dipdw.dwData            = JOYSTICK_DX_BUFFERSIZE;
-
-	if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) )
-		OIS_EXCEPT( E_General, "Win32JoyStick::_initialize >> Failed to set buffer size property" );
-
-	// Enumerate all axes/buttons/sliders/force feedback/etc before aquiring
-	_enumerate();
-
-	mState.clear();
-
-	capture();
+    if (mJoyInfo.isXInput)
+    {
+        _enumerate();
+    }
+    else
+    {
+	    //Clear old state
+	    mState.mAxes.clear();
+
+	    delete mFfDevice;
+	    mFfDevice = 0;
+
+	    DIPROPDWORD dipdw;
+
+	    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
+	    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	    dipdw.diph.dwObj        = 0;
+	    dipdw.diph.dwHow        = DIPH_DEVICE;
+	    dipdw.dwData            = JOYSTICK_DX_BUFFERSIZE;
+
+	    if(FAILED(mDirectInput->CreateDevice(mJoyInfo.deviceID, &mJoyStick, NULL)))
+		    OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!");
+
+	    if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2)))
+		    OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!");
+
+	    HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
+
+	    if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting)))
+		    OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!");
+
+	    if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) )
+		    OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set buffer size property" );
+
+	    //Enumerate all axes/buttons/sliders/etc before aquiring
+	    _enumerate();
+
+	    mState.clear();
+
+	    capture();
+    }
 }
 
@@ -123,24 +149,32 @@
 void Win32JoyStick::_enumerate()
 {
-	// Get joystick capabilities.
-	mDIJoyCaps.dwSize = sizeof(DIDEVCAPS);
-	if( FAILED(mJoyStick->GetCapabilities(&mDIJoyCaps)) )
-		OIS_EXCEPT( E_General, "Win32JoyStick::_enumerate >> Failed to get capabilities" );
-
-	// => Number of POVs
-	mPOVs = (short)mDIJoyCaps.dwPOVs;
-
-	// => Number of buttons and axes.
-	mState.mButtons.resize(mDIJoyCaps.dwButtons);
-	mState.mAxes.resize(mDIJoyCaps.dwAxes);
-
-	// Enumerate all Force Feedback effects (if any)
-	mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL);
-
-	//Reset the axis mapping enumeration value
-	_AxisNumber = 0;
-
-	// Enumerate and set axis constraints (and check FF Axes)
-	mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS);
+    if (mJoyInfo.isXInput)
+    {
+        mPOVs = 1;
+
+        mState.mButtons.resize(XINPUT_TRANSLATED_BUTTON_COUNT);
+	    mState.mAxes.resize(XINPUT_TRANSLATED_AXIS_COUNT);
+    }
+    else
+    {
+		// Get joystick capabilities.
+		mDIJoyCaps.dwSize = sizeof(DIDEVCAPS);
+		if( FAILED(mJoyStick->GetCapabilities(&mDIJoyCaps)) )
+			OIS_EXCEPT( E_General, "Win32JoyStick::_enumerate >> Failed to get capabilities" );
+
+	    mPOVs = (short)mDIJoyCaps.dwPOVs;
+
+	    mState.mButtons.resize(mDIJoyCaps.dwButtons);
+	    mState.mAxes.resize(mDIJoyCaps.dwAxes);
+
+	    //Reset the axis mapping enumeration value
+	    _AxisNumber = 0;
+
+	    //Enumerate Force Feedback (if any)
+	    mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL);
+
+	    //Enumerate and set axis constraints (and check FF Axes)
+	    mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS);
+    }
 }
 
@@ -191,7 +225,7 @@
 	if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 )
 	{
-		if( _this->ff_device )
+		if( _this->mFfDevice )
 		{
-			_this->ff_device->_addFFAxis();
+			_this->mFfDevice->_addFFAxis();
 		}
 	}
@@ -200,8 +234,8 @@
 	//as DInput has no API to query the device for these capabilities
 	//(the only way to know is to try them ...)
-	if( _this->ff_device )
-	{
-	    _this->ff_device->_setGainSupport(true);
-	    _this->ff_device->_setAutoCenterSupport(true);
+	if( _this->mFfDevice )
+	{
+	    _this->mFfDevice->_setGainSupport(true);
+	    _this->mFfDevice->_setAutoCenterSupport(true);
 	}
 
@@ -215,8 +249,8 @@
 
 	//Create the FF instance only after we know there is at least one effect type
-	if( _this->ff_device == 0 )
-	  _this->ff_device = new Win32ForceFeedback(_this->mJoyStick, &_this->mDIJoyCaps);
-
-	_this->ff_device->_addEffectSupport( pdei );
+	if( _this->mFfDevice == 0 )
+		_this->mFfDevice = new Win32ForceFeedback(_this->mJoyStick, &_this->mDIJoyCaps);
+
+	_this->mFfDevice->_addEffectSupport(pdei);
 
 	return DIENUM_CONTINUE;
@@ -226,4 +260,14 @@
 void Win32JoyStick::capture()
 {
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+	//handle xbox controller differently
+    if (mJoyInfo.isXInput)
+	{
+		captureXInput();
+		return;
+	}
+#endif
+
+	//handle directinput based devices
 	DIDEVICEOBJECTDATA diBuff[JOYSTICK_DX_BUFFERSIZE];
 	DWORD entries = JOYSTICK_DX_BUFFERSIZE;
@@ -241,5 +285,5 @@
 
 		// Poll the device to read the current state
-	    mJoyStick->Poll();
+		mJoyStick->Poll();
 		hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
 		//Perhaps the user just tabbed away
@@ -353,4 +397,116 @@
 
 //--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::captureXInput()
+{
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+    XINPUT_STATE inputState;
+	if (XInputGetState((DWORD)mJoyInfo.xInputDev, &inputState) != ERROR_SUCCESS)
+        memset(&inputState, 0, sizeof(inputState));
+
+    //Sticks and triggers
+	int value;
+    bool axisMoved[XINPUT_TRANSLATED_AXIS_COUNT] = {false,false,false,false,false,false};
+
+	//LeftY
+	value = -(int)inputState.Gamepad.sThumbLY;
+	mState.mAxes[0].rel = value - mState.mAxes[0].abs;
+	mState.mAxes[0].abs = value;
+	if(mState.mAxes[0].rel != 0)
+        axisMoved[0] = true;
+
+	//LeftX
+    mState.mAxes[1].rel = inputState.Gamepad.sThumbLX - mState.mAxes[1].abs;
+    mState.mAxes[1].abs = inputState.Gamepad.sThumbLX;
+
+	if(mState.mAxes[1].rel != 0)
+        axisMoved[1] = true;
+
+	//RightY
+	value = -(int)inputState.Gamepad.sThumbRY;           
+    mState.mAxes[2].rel = value - mState.mAxes[2].abs;
+    mState.mAxes[2].abs = value;
+	if(mState.mAxes[2].rel != 0)
+        axisMoved[2] = true;
+
+	//RightX
+    mState.mAxes[3].rel = inputState.Gamepad.sThumbRX - mState.mAxes[3].abs;
+    mState.mAxes[3].abs = inputState.Gamepad.sThumbRX;
+	if(mState.mAxes[3].rel != 0)
+		axisMoved[3] = true;
+
+	//Left trigger
+    value = inputState.Gamepad.bLeftTrigger * 129;
+	if(value > JoyStick::MAX_AXIS)
+		value = JoyStick::MAX_AXIS;
+
+    mState.mAxes[4].rel = value - mState.mAxes[4].abs;
+    mState.mAxes[4].abs = value;
+	if(mState.mAxes[4].rel != 0)
+		axisMoved[4] = true;
+
+	//Right trigger
+    value = (int)inputState.Gamepad.bRightTrigger * 129;
+	if(value > JoyStick::MAX_AXIS)
+		value = JoyStick::MAX_AXIS;
+
+	mState.mAxes[5].rel = value - mState.mAxes[5].abs;
+    mState.mAxes[5].abs = value;
+	if(mState.mAxes[5].rel != 0)
+		axisMoved[5] = true;
+    
+    //POV
+    int previousPov = mState.mPOV[0].direction;        
+    int& pov = mState.mPOV[0].direction;
+    pov = Pov::Centered;        
+    if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
+        pov |= Pov::North;
+    else if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
+        pov |= Pov::South;
+    if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
+        pov |= Pov::West;
+    else if (inputState.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
+        pov |= Pov::East;
+    
+    //Buttons - The first 4 buttons don't need to be checked since they represent the dpad
+    bool previousButtons[XINPUT_TRANSLATED_BUTTON_COUNT];
+    std::copy(mState.mButtons.begin(), mState.mButtons.end(), previousButtons);
+    for (size_t i = 0; i < XINPUT_TRANSLATED_BUTTON_COUNT; i++)
+        mState.mButtons[i] = (inputState.Gamepad.wButtons & (1 << (i + 4))) != 0;
+
+    //Send events
+    if (mBuffered && mListener)
+    {
+	    JoyStickEvent joystickEvent(this, mState);
+
+	    //Axes
+	    for (int i = 0; i < XINPUT_TRANSLATED_AXIS_COUNT; i++)
+        {
+		    if (axisMoved[i] && !mListener->axisMoved(joystickEvent, i))
+			    return;
+        }
+
+        //POV
+        if (previousPov != pov && !mListener->povMoved(joystickEvent, 0))
+            return;
+
+        //Buttons
+        for (int i = 0; i < XINPUT_TRANSLATED_BUTTON_COUNT; i++)
+        {
+            if (!previousButtons[i] && mState.mButtons[i])
+            {
+                if (!mListener->buttonPressed(joystickEvent, i))
+                    return;
+            }
+            else if (previousButtons[i] && !mState.mButtons[i])
+            {
+                if (!mListener->buttonReleased(joystickEvent, i))
+                    return;
+            }
+        }
+    }
+#endif
+}
+
+//--------------------------------------------------------------------------------------------------//
 bool Win32JoyStick::_doButtonClick( int button, DIDEVICEOBJECTDATA& di )
 {
@@ -410,10 +566,136 @@
 Interface* Win32JoyStick::queryInterface(Interface::IType type)
 {
-	//Thought about using covariant return type here.. however,
-	//some devices may allow LED light changing, or other interface stuff
-
-	if( ff_device && type == Interface::ForceFeedback )
-		return ff_device;
+	if( mFfDevice && type == Interface::ForceFeedback )
+		return mFfDevice;
 	else
 		return 0;
 }
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::CheckXInputDevices(JoyStickInfoList &joys)
+{
+    IWbemLocator*           pIWbemLocator  = NULL;
+    IEnumWbemClassObject*   pEnumDevices   = NULL;
+    IWbemClassObject*       pDevices[20]   = {0};
+    IWbemServices*          pIWbemServices = NULL;
+    BSTR                    bstrNamespace  = NULL;
+    BSTR                    bstrDeviceID   = NULL;
+    BSTR                    bstrClassName  = NULL;
+    DWORD                   uReturned      = 0;
+    bool                    bIsXinputDevice= false;
+	DWORD                   iDevice        = 0;
+	int                     xDevice        = 0;
+    VARIANT                 var;
+    HRESULT                 hr;
+
+	if(joys.size() == 0)
+		return;
+
+    // CoInit if needed
+    hr = CoInitialize(NULL);
+    bool bCleanupCOM = SUCCEEDED(hr);
+
+    // Create WMI
+    // (Orxonox): Fix for MinGW
+#ifdef __MINGW32__
+    hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pIWbemLocator);
+#else
+    hr = CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator);
+#endif
+    if( FAILED(hr) || pIWbemLocator == NULL )
+        goto LCleanup;
+
+    bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );
+	if( bstrNamespace == NULL )
+		goto LCleanup;
+
+    bstrClassName = SysAllocString( L"Win32_PNPEntity" );
+	if( bstrClassName == NULL )
+		goto LCleanup;
+
+    bstrDeviceID  = SysAllocString( L"DeviceID" );
+	if( bstrDeviceID == NULL )
+		goto LCleanup;
+    
+    // Connect to WMI 
+    hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices );
+    if( FAILED(hr) || pIWbemServices == NULL )
+        goto LCleanup;
+
+    // Switch security level to IMPERSONATE. 
+    CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );                    
+
+    hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, NULL, &pEnumDevices ); 
+    if( FAILED(hr) || pEnumDevices == NULL )
+        goto LCleanup;
+
+    // Loop over all devices
+    for( ;; )
+    {
+        // Get 20 at a time
+        hr = pEnumDevices->Next(5000, 20, pDevices, &uReturned);
+        if( FAILED(hr) )
+            goto LCleanup;
+
+        if( uReturned == 0 )
+            break;
+
+        for(iDevice = 0; iDevice < uReturned; iDevice++)
+        {
+            // For each device, get its device ID
+            hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL);
+            if(SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL)
+            {
+                // Check if the device ID contains "IG_".  If it does, then it's an XInput device - This information can not be found from DirectInput 
+                if(wcsstr(var.bstrVal, L"IG_"))
+                {
+                    // If it does, then get the VID/PID from var.bstrVal
+                    DWORD dwPid = 0, dwVid = 0;
+                    WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" );
+                    if(strVid && swscanf_s( strVid, L"VID_%4X", &dwVid ) != 1)
+						dwVid = 0;
+
+                    WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" );
+                    if(strPid && swscanf_s( strPid, L"PID_%4X", &dwPid ) != 1)
+                        dwPid = 0;
+
+                    // Compare the VID/PID to the DInput device
+                    DWORD dwVidPid = MAKELONG(dwVid, dwPid);
+					for(JoyStickInfoList::iterator i = joys.begin(); i != joys.end(); ++i)
+					{
+						if(dwVidPid == i->productGuid.Data1)
+						{
+							i->isXInput = true;
+							i->xInputDev = xDevice;
+						}
+					}
+
+					if(joys.size() == 0)
+						goto LCleanup;
+                }
+            }
+
+            SAFE_RELEASE(pDevices[iDevice]);
+        }
+    }
+
+LCleanup:
+    if(bstrNamespace)
+        SysFreeString(bstrNamespace);
+
+    if(bstrDeviceID)
+        SysFreeString(bstrDeviceID);
+
+    if(bstrClassName)
+        SysFreeString(bstrClassName);
+
+    for(iDevice=0; iDevice < 20; iDevice++)
+        SAFE_RELEASE(pDevices[iDevice]);
+
+    SAFE_RELEASE(pEnumDevices);
+    SAFE_RELEASE(pIWbemLocator);
+    SAFE_RELEASE(pIWbemServices);
+
+    if(bCleanupCOM)
+        CoUninitialize();
+}
Index: /code/branches/kicklib2/src/external/ois/win32/Win32JoyStick.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32JoyStick.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32JoyStick.h	(revision 8284)
@@ -25,5 +25,5 @@
 
 #include "OISJoyStick.h"
-#include "Win32/Win32Prereqs.h"
+#include "win32/Win32Prereqs.h"
 
 namespace OIS
@@ -41,4 +41,7 @@
 		virtual void capture();
 
+		//! hanlde xinput
+		void captureXInput();
+
 		/** @copydoc Object::queryInterface */
 		virtual Interface* queryInterface(Interface::IType type);
@@ -46,4 +49,12 @@
 		/** @copydoc Object::_initialize */
 		virtual void _initialize();
+
+		/**
+		@remarks
+			Enum each PNP device using WMI and check each device ID to see if it contains 
+			"IG_" (ex. "VID_045E&PID_028E&IG_00").  If it does, then it's an XInput device
+			Unfortunately this information can not be found by just using DirectInput 
+		*/
+		static void CheckXInputDevices(JoyStickInfoList &joys);
 
 	protected:
@@ -61,10 +72,10 @@
 		IDirectInputDevice8* mJoyStick;
 		DIDEVCAPS mDIJoyCaps;
+		DWORD coopSetting;
 
-		DWORD coopSetting;
-		GUID deviceGuid;
+        JoyStickInfo mJoyInfo;
 
 		//! A force feedback device
-		Win32ForceFeedback* ff_device;
+		Win32ForceFeedback* mFfDevice;
 
 		//! Mapping
Index: /code/branches/kicklib2/src/external/ois/win32/Win32KeyBoard.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32KeyBoard.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32KeyBoard.cpp	(revision 8284)
@@ -21,6 +21,6 @@
     3. This notice may not be removed or altered from any source distribution.
 */
-#include "Win32/Win32InputManager.h"
-#include "Win32/Win32KeyBoard.h"
+#include "win32/Win32InputManager.h"
+#include "win32/Win32KeyBoard.h"
 #include "OISException.h"
 #include "OISEvents.h"
@@ -287,5 +287,5 @@
 
 //--------------------------------------------------------------------------------------------------//
-const std::string& Win32Keyboard::getAsString( KeyCode kc )
+const std::string& Win32Keyboard::getAsString(KeyCode kc)
 {
 	char temp[256];
@@ -297,14 +297,14 @@
 	prop.diph.dwHow = DIPH_BYOFFSET;
 
-	if ( SUCCEEDED( mKeyboard->GetProperty( DIPROP_KEYNAME, &prop.diph ) ) )
+	if (SUCCEEDED(mKeyboard->GetProperty(DIPROP_KEYNAME, &prop.diph)))
 	{
 		// convert the WCHAR in "wsz" to multibyte
-		if ( WideCharToMultiByte( CP_ACP, 0, prop.wsz, -1, temp, sizeof(temp), NULL, NULL) )
-			return mGetString.assign( temp );
+		if (WideCharToMultiByte(CP_ACP, 0, prop.wsz, -1, temp, sizeof(temp), NULL, NULL))
+			return mGetString.assign(temp);
 	}
 
 	std::stringstream ss;
 	ss << "Key_" << (int)kc;
-	return mGetString.assign( ss.str() );
+	return mGetString.assign(ss.str());
 }
 
Index: /code/branches/kicklib2/src/external/ois/win32/Win32KeyBoard.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32KeyBoard.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32KeyBoard.h	(revision 8284)
@@ -25,5 +25,5 @@
 
 #include "OISKeyboard.h"
-#include "Win32/Win32Prereqs.h"
+#include "win32/Win32Prereqs.h"
 
 namespace OIS
@@ -42,15 +42,15 @@
 			A combination of DI Flags (see DX Help for info on input device settings)
 		*/
-		Win32Keyboard( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings );
+		Win32Keyboard(InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings);
 		virtual ~Win32Keyboard();
 
 		/** @copydoc Keyboard::isKeyDown */
-		virtual bool isKeyDown( KeyCode key ) const;
+		virtual bool isKeyDown(KeyCode key) const;
 		
 		/** @copydoc Keyboard::getAsString */
-		virtual const std::string& getAsString( KeyCode kc );
+		virtual const std::string& getAsString(KeyCode kc);
 
 		/** @copydoc Keyboard::copyKeyStates */
-		virtual void copyKeyStates( char keys[256] ) const;
+		virtual void copyKeyStates(char keys[256]) const;
 
 		/** @copydoc Object::setBuffered */
Index: /code/branches/kicklib2/src/external/ois/win32/Win32Mouse.cpp
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32Mouse.cpp	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32Mouse.cpp	(revision 8284)
@@ -21,6 +21,6 @@
     3. This notice may not be removed or altered from any source distribution.
 */
-#include "Win32/Win32Mouse.h"
-#include "Win32/Win32InputManager.h"
+#include "win32/Win32Mouse.h"
+#include "win32/Win32InputManager.h"
 #include "OISException.h"
 #include "OISEvents.h"
Index: /code/branches/kicklib2/src/external/ois/win32/Win32Mouse.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32Mouse.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32Mouse.h	(revision 8284)
@@ -25,5 +25,5 @@
 
 #include "OISMouse.h"
-#include "Win32/Win32Prereqs.h"
+#include "win32/Win32Prereqs.h"
 
 namespace OIS
Index: /code/branches/kicklib2/src/external/ois/win32/Win32Prereqs.h
===================================================================
--- /code/branches/kicklib2/src/external/ois/win32/Win32Prereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/external/ois/win32/Win32Prereqs.h	(revision 8284)
@@ -29,8 +29,12 @@
 #include <dinput.h>
 
+#ifdef OIS_WIN32_XINPUT_SUPPORT
+#	include <XInput.h>
+#endif
+
 //Max number of elements to collect from buffered DirectInput
 #define KEYBOARD_DX_BUFFERSIZE 17
-#define MOUSE_DX_BUFFERSIZE 64
-#define JOYSTICK_DX_BUFFERSIZE 124
+#define MOUSE_DX_BUFFERSIZE 128
+#define JOYSTICK_DX_BUFFERSIZE 129
 
 //MinGW defines
@@ -55,8 +59,11 @@
 		int devId;
 		GUID deviceID;
+		GUID productGuid;
 		std::string vendor;
+        bool isXInput;
+		int xInputDev;
 	};
 
-	typedef std::vector< JoyStickInfo > JoyStickInfoList;
+	typedef std::vector<JoyStickInfo> JoyStickInfoList;
 }
 
Index: /code/branches/kicklib2/src/libraries/core/Core.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/Core.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/Core.cc	(revision 8284)
@@ -81,5 +81,7 @@
 
     SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file");
+#ifndef ORXONOX_PLATFORM_APPLE
     SetCommandLineSwitch(noIOConsole).information("Use this if you don't want to use the IOConsole (for instance for Lua debugging)");
+#endif
 
 #ifdef ORXONOX_PLATFORM_WINDOWS
@@ -156,5 +158,6 @@
         this->setConfigValues();
 
-        // create persistent io console
+#ifndef ORXONOX_PLATFORM_APPLE
+        // Create persistent IO console
         if (CommandLineParser::getValue("noIOConsole").getBool())
         {
@@ -163,4 +166,5 @@
         if (this->bStartIOConsole_)
             this->ioConsole_.reset(new IOConsole());
+#endif
 
         // creates the class hierarchy for all classes with factories
Index: /code/branches/kicklib2/src/libraries/core/CorePrereqs.h
===================================================================
--- /code/branches/kicklib2/src/libraries/core/CorePrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/CorePrereqs.h	(revision 8284)
@@ -54,8 +54,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _CorePrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _CoreExport  __attribute__ ((visibility("default")))
+#  define _CorePrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _CoreExport
+#  define _CorePrivate
 #endif
 
@@ -259,5 +262,5 @@
 namespace boost
 {
-#if (BOOST_VERSION < 104400)
+#if BOOST_VERSION < 104400
     namespace filesystem
     {
@@ -266,5 +269,5 @@
         typedef basic_path<std::string, path_traits> path;
     }
-#else
+#elif BOOST_VERSION < 104600
     namespace filesystem2
     {
@@ -278,4 +281,13 @@
         using filesystem2::path_traits;
         using filesystem2::path;
+    }
+#else
+    namespace filesystem3
+    {
+        class path;
+    }
+    namespace filesystem
+    {
+        using filesystem3::path;
     }
 #endif
Index: /code/branches/kicklib2/src/libraries/core/DynLib.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/DynLib.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/DynLib.cc	(revision 8284)
@@ -42,10 +42,10 @@
 #endif
 
-#ifdef ORXONOX_PLATFORM_LINUX
+#ifdef ORXONOX_PLATFORM_UNIX
 #  include <dlfcn.h>
 #endif
 
 #ifdef ORXONOX_PLATFORM_APPLE
-#  include <macPlugins.h>
+#   include <OSX/macUtils.h> // OGRE include
 #endif
 
@@ -75,4 +75,13 @@
         if (name.substr(name.length() - 3, 3) != ".so")
            name += ".so";
+#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
+        // dlopen() does not add .dylib to the filename, like windows does for .dll
+        if (name.substr(name.length() - 6, 6) != ".dylib")
+            name += ".dylib";
+#elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+        // Although LoadLibraryEx will add .dll itself when you only specify the library name,
+        // if you include a relative path then it does not. So, add it to be sure.
+        if (name.substr(name.length() - 4, 4) != ".dll")
+            name += ".dll";
 #endif
 
@@ -127,12 +136,9 @@
         LocalFree( lpMsgBuf );
         return ret;
-#elif defined(ORXONOX_PLATFORM_LINUX)
+#elif defined(ORXONOX_PLATFORM_UNIX)
         return std::string(dlerror());
-#elif defined(ORXONOX_PLATFORM_APPLE)
-        return std::string(mac_errorBundle());
 #else
         return "";
 #endif
     }
-
 }
Index: /code/branches/kicklib2/src/libraries/core/DynLib.h
===================================================================
--- /code/branches/kicklib2/src/libraries/core/DynLib.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/DynLib.h	(revision 8284)
@@ -52,15 +52,9 @@
 typedef struct HINSTANCE__* hInstance;
 
-#elif defined(ORXONOX_PLATFORM_LINUX)
+#elif defined(ORXONOX_PLATFORM_UNIX)
 #    define DYNLIB_HANDLE void*
 #    define DYNLIB_LOAD( a ) dlopen( a, RTLD_LAZY | RTLD_GLOBAL)
 #    define DYNLIB_GETSYM( a, b ) dlsym( a, b )
 #    define DYNLIB_UNLOAD( a ) dlclose( a )
-
-#elif defined(ORXONOX_PLATFORM_APPLE)
-#    define DYNLIB_HANDLE CFBundleRef
-#    define DYNLIB_LOAD( a ) mac_loadExeBundle( a )
-#    define DYNLIB_GETSYM( a, b ) mac_getBundleSym( a, b )
-#    define DYNLIB_UNLOAD( a ) mac_unloadExeBundle( a )
 #endif
 
Index: /code/branches/kicklib2/src/libraries/core/GUIManager.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/GUIManager.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/GUIManager.cc	(revision 8284)
@@ -149,11 +149,11 @@
         : destroyer_(*this, &GUIManager::cleanup)
         , guiRenderer_(NULL)
+        , resourceProvider_(NULL)
+#ifndef ORXONOX_OLD_CEGUI
+        , imageCodec_(NULL)
+#endif
         , luaState_(NULL)
         , scriptModule_(NULL)
         , guiSystem_(NULL)
-        , resourceProvider_(NULL)
-#ifndef ORXONOX_OLD_CEGUI
-        , imageCodec_(NULL)
-#endif
         , camera_(NULL)
     {
@@ -393,4 +393,9 @@
         false                     | False | True  | Dontcare
         */
+
+#ifdef ORXONOX_PLATFORM_APPLE
+        // There is no non exclusive mode on OS X yet
+        state->setMouseExclusive(TriBool::True);
+#else
         if (showCursor == TriBool::Dontcare)
             state->setMouseExclusive(TriBool::Dontcare);
@@ -399,4 +404,5 @@
         else
             state->setMouseExclusive(TriBool::False);
+#endif
 
         if (showCursor == TriBool::True)
Index: /code/branches/kicklib2/src/libraries/core/Game.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/Game.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/Game.cc	(revision 8284)
@@ -459,5 +459,5 @@
             ThrowException(GameState, "Emtpy GameState hierarchy provided, terminating.");
         // Add element with large identation to detect the last with just an iterator
-        stateStrings.push_back(std::make_pair("", -1));
+        stateStrings.push_back(std::make_pair(std::string(), -1));
 
         // Parse elements recursively
Index: /code/branches/kicklib2/src/libraries/core/GraphicsManager.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/GraphicsManager.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/GraphicsManager.cc	(revision 8284)
@@ -260,5 +260,9 @@
         // Use backslash paths on Windows! file_string() already does that though.
         for (unsigned int i = 0; i < plugins.size(); ++i)
+#if BOOST_FILESYSTEM_VERSION < 3
             ogreRoot_->loadPlugin((folder / plugins[i]).file_string());
+#else
+            ogreRoot_->loadPlugin((folder / plugins[i]).string());
+#endif
     }
 
@@ -286,4 +290,13 @@
 
         Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_.get());
+
+// HACK
+#ifdef ORXONOX_PLATFORM_APPLE
+        //INFO: This will give our window focus, and not lock it to the terminal
+        ProcessSerialNumber psn = {0, kCurrentProcess};
+        TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+        SetFrontProcess(&psn);
+#endif
+// End of HACK
 
         // create a full screen default viewport
Index: /code/branches/kicklib2/src/libraries/core/Identifier.h
===================================================================
--- /code/branches/kicklib2/src/libraries/core/Identifier.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/Identifier.h	(revision 8284)
@@ -123,5 +123,5 @@
 
             /// Returns the unique ID of the class.
-            FORCEINLINE unsigned int getClassID() const { return this->classID_; }
+            ORX_FORCEINLINE unsigned int getClassID() const { return this->classID_; }
 
             /// Returns the list of all existing objects of this class.
@@ -486,5 +486,5 @@
     */
     template <class T, class U>
-    FORCEINLINE T orxonox_cast(U* source)
+    ORX_FORCEINLINE T orxonox_cast(U* source)
     {
 #ifdef ORXONOX_COMPILER_MSVC
Index: /code/branches/kicklib2/src/libraries/core/OrxonoxClass.h
===================================================================
--- /code/branches/kicklib2/src/libraries/core/OrxonoxClass.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/OrxonoxClass.h	(revision 8284)
@@ -135,5 +135,5 @@
                 Returns NULL if the no pointer was found.
             */
-            FORCEINLINE void* getDerivedPointer(unsigned int classID)
+            ORX_FORCEINLINE void* getDerivedPointer(unsigned int classID)
             {
                 for (int i = this->objectPointers_.size() - 1; i >= 0; --i)
@@ -146,8 +146,8 @@
 
             /// Version of getDerivedPointer with template
-            template <class T> FORCEINLINE T* getDerivedPointer(unsigned int classID)
+            template <class T> ORX_FORCEINLINE T* getDerivedPointer(unsigned int classID)
             {   return static_cast<T*>(this->getDerivedPointer(classID));   }
             /// Const version of getDerivedPointer with template
-            template <class T> FORCEINLINE const T* getDerivedPointer(unsigned int classID) const
+            template <class T> ORX_FORCEINLINE const T* getDerivedPointer(unsigned int classID) const
             {   return const_cast<OrxonoxClass*>(this)->getDerivedPointer<T>(classID);   }
 
Index: /code/branches/kicklib2/src/libraries/core/PathConfig.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/PathConfig.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/PathConfig.cc	(revision 8284)
@@ -59,6 +59,8 @@
 #if (BOOST_VERSION == 103600)
 #  define BOOST_LEAF_FUNCTION filename
-#else
+#elif (BOOST_FILESYSTEM_VERSION < 3)
 #  define BOOST_LEAF_FUNCTION leaf
+#else
+#  define BOOST_LEAF_FUNCTION path().filename().string
 #endif
 
@@ -95,5 +97,5 @@
 #elif defined(ORXONOX_PLATFORM_APPLE)
         char buffer[1024];
-        unsigned long path_len = 1023;
+        uint32_t path_len = 1023;
         if (_NSGetExecutablePath(buffer, &path_len))
             ThrowException(General, "Could not retrieve executable path.");
@@ -125,8 +127,6 @@
 #endif
 
-        executablePath_ = bf::path(buffer);
-#ifndef ORXONOX_PLATFORM_APPLE
-        executablePath_ = executablePath_.branch_path(); // remove executable name
-#endif
+        // Remove executable filename
+        executablePath_ = bf::path(buffer).branch_path();
 
         /////////////////////
@@ -206,9 +206,9 @@
 
             // Get user directory
-#  ifdef ORXONOX_PLATFORM_UNIX /* Apple? */
+#ifdef ORXONOX_PLATFORM_UNIX
             char* userDataPathPtr(getenv("HOME"));
-#  else
+#else
             char* userDataPathPtr(getenv("APPDATA"));
-#  endif
+#endif
             if (userDataPathPtr == NULL)
                 ThrowException(General, "Could not retrieve user data path.");
@@ -233,6 +233,6 @@
         // Create directories to avoid problems when opening files in non existent folders.
         std::vector<std::pair<bf::path, std::string> > directories;
-        directories.push_back(std::make_pair(bf::path(configPath_), "config"));
-        directories.push_back(std::make_pair(bf::path(logPath_), "log"));
+        directories.push_back(std::make_pair(bf::path(configPath_), std::string("config")));
+        directories.push_back(std::make_pair(bf::path(logPath_), std::string("log")));
 
         for (std::vector<std::pair<bf::path, std::string> >::iterator it = directories.begin();
@@ -273,7 +273,7 @@
         while (file != end)
         {
-            const std::string& filename = file->BOOST_LEAF_FUNCTION();
-
-            // Check if the file ends with the exension in question
+            std::string filename = file->BOOST_LEAF_FUNCTION();
+
+            // Check if the file ends with the extension in question
             if (filename.size() > moduleextensionlength)
             {
@@ -282,5 +282,9 @@
                     // We've found a helper file
                     const std::string& library = filename.substr(0, filename.size() - moduleextensionlength);
+#if BOOST_FILESYSTEM_VERSION < 3
                     modulePaths.push_back((modulePath_ / library).file_string());
+#else
+                    modulePaths.push_back((modulePath_ / library).string());
+#endif
                 }
             }
Index: /code/branches/kicklib2/src/libraries/core/Resource.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/Resource.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/Resource.cc	(revision 8284)
@@ -36,10 +36,13 @@
 namespace orxonox
 {
-    std::string Resource::DEFAULT_GROUP(Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+    const std::string& Resource::getDefaultResourceGroup()
+    {
+        return Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME;
+    }
 
     DataStreamPtr Resource::open(const std::string& name)
     {
         return Ogre::ResourceGroupManager::getSingleton().openResource(name,
-            Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
+            getDefaultResourceGroup(), true);
     }
 
Index: /code/branches/kicklib2/src/libraries/core/Resource.h
===================================================================
--- /code/branches/kicklib2/src/libraries/core/Resource.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/Resource.h	(revision 8284)
@@ -137,5 +137,5 @@
 
         //! Name of the default resource group (usually "General")
-        static std::string DEFAULT_GROUP;
+        static const std::string& getDefaultResourceGroup();
 
     private:
Index: /code/branches/kicklib2/src/libraries/core/Super.h
===================================================================
--- /code/branches/kicklib2/src/libraries/core/Super.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/Super.h	(revision 8284)
@@ -94,8 +94,8 @@
         struct SuperFunctionCondition<functionnumber, T, 0, templatehack2> \
         { \
-            static void check() \
+            static void superCheck() \
             { \
                 SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0)); \
-                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::check(); \
+                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::superCheck(); \
             } \
             \
@@ -132,7 +132,7 @@
         struct SuperFunctionCondition<functionnumber, baseclass, 0, templatehack2> \
         { \
-            static void check() \
-            { \
-                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::check(); \
+            static void superCheck() \
+            { \
+                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::superCheck(); \
             } \
         };
@@ -150,5 +150,5 @@
         struct SuperFunctionCondition<functionnumber, T, 0, templatehack2>
         {
-            static void check()
+            static void superCheck()
             {
                 // This call to the apply-function is the whole check. By calling the function with
@@ -156,6 +156,6 @@
                 SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0));
 
-                // Go go the check for of next super-function (functionnumber + 1)
-                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::check();
+                // Go go the superCheck for of next super-function (functionnumber + 1)
+                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::superCheck();
             }
 
@@ -202,8 +202,8 @@
         struct SuperFunctionCondition<functionnumber, baseclass, 0, templatehack2> \
         { \
-            // The check function acts like the fallback - it advances to the check for the next super-function (functionnumber + 1)
-            static void check() \
-            { \
-                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::check(); \
+            // The superCheck function acts like the fallback - it advances to the check for the next super-function (functionnumber + 1)
+            static void superCheck() \
+            { \
+                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::superCheck(); \
             } \
         };
@@ -303,5 +303,5 @@
         struct SuperFunctionCondition
         {
-            static void check() {}
+            static void superCheck() {}
         };
 
@@ -338,7 +338,7 @@
             struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2> \
             { \
-                static void check() \
+                static void superCheck() \
                 { \
-                    SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::check(); \
+                    SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::superCheck(); \
                 } \
             }; \
@@ -421,8 +421,8 @@
             // If this function gets called, the header-file of the super function is not
             // included, so this fallback template (templatehack not specialized) is used
-            static void check()
+            static void superCheck()
             {
                 // Calls the condition-check of the next super-function (functionnumber + 1)
-                SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::check();
+                SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::superCheck();
             }
         };
@@ -574,5 +574,5 @@
         virtual void createSuperFunctionCaller() const
         {
-            SuperFunctionCondition<0, T, 0, 0>::check();
+            SuperFunctionCondition<0, T, 0, 0>::superCheck();
         }
 
Index: /code/branches/kicklib2/src/libraries/core/command/ArgumentCompletionFunctions.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/command/ArgumentCompletionFunctions.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/command/ArgumentCompletionFunctions.cc	(revision 8284)
@@ -50,6 +50,11 @@
 #if (BOOST_VERSION == 103600)
 #  define BOOST_LEAF_FUNCTION filename
+#  define BOOST_DICTIONARY_ENTRY_NAME string
+#elif (BOOST_FILESYSTEM_VERSION < 3)
+#  define BOOST_LEAF_FUNCTION leaf
+#  define BOOST_DICTIONARY_ENTRY_NAME string
 #else
-#  define BOOST_LEAF_FUNCTION leaf
+#  define BOOST_LEAF_FUNCTION path().filename().string
+#  define BOOST_DICTIONARY_ENTRY_NAME path().string
 #endif
 
@@ -257,7 +262,7 @@
                 {
                     if (boost::filesystem::is_directory(*file))
-                        dirlist.push_back(ArgumentCompletionListElement(file->string() + '/', getLowercase(file->string()) + '/', file->BOOST_LEAF_FUNCTION() + '/'));
+                        dirlist.push_back(ArgumentCompletionListElement(file->BOOST_DICTIONARY_ENTRY_NAME() + '/', getLowercase(file->BOOST_DICTIONARY_ENTRY_NAME()) + '/', file->BOOST_LEAF_FUNCTION() + '/'));
                     else
-                        filelist.push_back(ArgumentCompletionListElement(file->string(), getLowercase(file->string()), file->BOOST_LEAF_FUNCTION()));
+                        filelist.push_back(ArgumentCompletionListElement(file->BOOST_DICTIONARY_ENTRY_NAME(), getLowercase(file->BOOST_DICTIONARY_ENTRY_NAME()), file->BOOST_LEAF_FUNCTION()));
                     ++file;
                 }
Index: /code/branches/kicklib2/src/libraries/core/input/InputDevice.h
===================================================================
--- /code/branches/kicklib2/src/libraries/core/input/InputDevice.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/input/InputDevice.h	(revision 8284)
@@ -184,5 +184,5 @@
     protected:
         //! Common code for all button pressed events (updates pressed buttons list and calls the input states)
-        FORCEINLINE void buttonPressed(ButtonTypeParam button)
+        ORX_FORCEINLINE void buttonPressed(ButtonTypeParam button)
         {
             // check whether the button already is in the list (can happen when focus was lost)
@@ -201,5 +201,5 @@
 
         //! Common code for all button released events (updates pressed buttons list and calls the input states)
-        FORCEINLINE void buttonReleased(ButtonTypeParam button)
+        ORX_FORCEINLINE void buttonReleased(ButtonTypeParam button)
         {
             // remove the button from the pressedButtons_ list
Index: /code/branches/kicklib2/src/libraries/core/input/InputManager.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/core/input/InputManager.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/input/InputManager.cc	(revision 8284)
@@ -151,39 +151,41 @@
         assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
 
+        typedef std::pair<std::string, std::string> StringPair;
+
         // Fill parameter list
         OIS::ParamList paramList;
         size_t windowHnd = GraphicsManager::getInstance().getRenderWindowHandle();
-        paramList.insert(std::make_pair("WINDOW", multi_cast<std::string>(windowHnd)));
+        paramList.insert(StringPair("WINDOW", multi_cast<std::string>(windowHnd)));
 #if defined(ORXONOX_PLATFORM_WINDOWS)
-        paramList.insert(std::make_pair("w32_keyboard", "DISCL_NONEXCLUSIVE"));
-        paramList.insert(std::make_pair("w32_keyboard", "DISCL_FOREGROUND"));
-        paramList.insert(std::make_pair("w32_mouse", "DISCL_FOREGROUND"));
+        paramList.insert(StringPair("w32_keyboard", "DISCL_NONEXCLUSIVE"));
+        paramList.insert(StringPair("w32_keyboard", "DISCL_FOREGROUND"));
+        paramList.insert(StringPair("w32_mouse", "DISCL_FOREGROUND"));
         if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
         {
             // Disable Windows key plus special keys (like play, stop, next, etc.)
-            paramList.insert(std::make_pair("w32_keyboard", "DISCL_NOWINKEY"));
-            paramList.insert(std::make_pair("w32_mouse", "DISCL_EXCLUSIVE"));
-        }
-        else
-            paramList.insert(std::make_pair("w32_mouse", "DISCL_NONEXCLUSIVE"));
+            paramList.insert(StringPair("w32_keyboard", "DISCL_NOWINKEY"));
+            paramList.insert(StringPair("w32_mouse", "DISCL_EXCLUSIVE"));
+        }
+        else
+            paramList.insert(StringPair("w32_mouse", "DISCL_NONEXCLUSIVE"));
 #elif defined(ORXONOX_PLATFORM_LINUX)
         // Enabling this is probably a bad idea, but whenever orxonox crashes, the setting stays on
         // Trouble might be that the Pressed event occurs a bit too often...
-        paramList.insert(std::make_pair("XAutoRepeatOn", "true"));
+        paramList.insert(StringPair("XAutoRepeatOn", "true"));
 
         if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
         {
             if (CommandLineParser::getValue("keyboard_no_grab").getBool())
-                paramList.insert(std::make_pair("x11_keyboard_grab", "false"));
+                paramList.insert(StringPair("x11_keyboard_grab", "false"));
             else
-                paramList.insert(std::make_pair("x11_keyboard_grab", "true"));
-            paramList.insert(std::make_pair("x11_mouse_grab",  "true"));
-            paramList.insert(std::make_pair("x11_mouse_hide", "true"));
-        }
-        else
-        {
-            paramList.insert(std::make_pair("x11_keyboard_grab", "false"));
-            paramList.insert(std::make_pair("x11_mouse_grab",  "false"));
-            paramList.insert(std::make_pair("x11_mouse_hide", "false"));
+                paramList.insert(StringPair("x11_keyboard_grab", "true"));
+            paramList.insert(StringPair("x11_mouse_grab",  "true"));
+            paramList.insert(StringPair("x11_mouse_hide", "true"));
+        }
+        else
+        {
+            paramList.insert(StringPair("x11_keyboard_grab", "false"));
+            paramList.insert(StringPair("x11_mouse_grab",  "false"));
+            paramList.insert(StringPair("x11_mouse_hide", "false"));
         }
 #endif
Index: /code/branches/kicklib2/src/libraries/core/input/InputState.h
===================================================================
--- /code/branches/kicklib2/src/libraries/core/input/InputState.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/core/input/InputState.h	(revision 8284)
@@ -176,5 +176,5 @@
     };
 
-    FORCEINLINE void InputState::update(float dt)
+    ORX_FORCEINLINE void InputState::update(float dt)
     {
         for (unsigned int i = 0; i < handlers_.size(); ++i)
@@ -183,5 +183,5 @@
     }
 
-    FORCEINLINE void InputState::update(float dt, unsigned int device)
+    ORX_FORCEINLINE void InputState::update(float dt, unsigned int device)
     {
         switch (device)
@@ -205,5 +205,5 @@
 
     template <typename EventType, class ButtonTypeParam>
-    FORCEINLINE void InputState::buttonEvent(unsigned int device, ButtonTypeParam button)
+    ORX_FORCEINLINE void InputState::buttonEvent(unsigned int device, ButtonTypeParam button)
     {
         assert(device < handlers_.size());
@@ -216,5 +216,5 @@
     }
 
-    FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    ORX_FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
     {
         if (handlers_[mouseIndex_s] != NULL)
@@ -222,5 +222,5 @@
     }
 
-    FORCEINLINE void InputState::mouseScrolled(int abs, int rel)
+    ORX_FORCEINLINE void InputState::mouseScrolled(int abs, int rel)
     {
         if (handlers_[mouseIndex_s] != NULL)
@@ -228,5 +228,5 @@
     }
 
-    FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value)
+    ORX_FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value)
     {
         assert(device < handlers_.size());
Index: /code/branches/kicklib2/src/libraries/network/LANDiscoverable.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/network/LANDiscoverable.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/network/LANDiscoverable.cc	(revision 8284)
@@ -29,10 +29,10 @@
 #include "LANDiscoverable.h"
 
-#include "NetworkPrereqs.h"
-#include "packet/ServerInformation.h"
-
 #include <enet/enet.h>
 #include <cassert>
 #include <cstring>
+
+#include "util/Debug.h"
+#include "packet/ServerInformation.h"
 
 namespace orxonox
Index: /code/branches/kicklib2/src/libraries/network/MasterServerComm.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/network/MasterServerComm.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/network/MasterServerComm.cc	(revision 8284)
@@ -28,4 +28,5 @@
 
 #include "MasterServerComm.h"
+#include "util/Debug.h"
 
 namespace orxonox
Index: /code/branches/kicklib2/src/libraries/network/NetworkPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/libraries/network/NetworkPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/network/NetworkPrereqs.h	(revision 8284)
@@ -52,8 +52,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _NetworkPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _NetworkExport  __attribute__ ((visibility("default")))
+#  define _NetworkPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _NetworkExport
+#  define _NetworkPrivate
 #endif
 
Index: /code/branches/kicklib2/src/libraries/tools/BulletConversions.h
===================================================================
--- /code/branches/kicklib2/src/libraries/tools/BulletConversions.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/tools/BulletConversions.h	(revision 8284)
@@ -43,5 +43,5 @@
     struct ConverterExplicit<orxonox::Vector3, btVector3>
     {
-        FORCEINLINE static bool convert(btVector3* output, const orxonox::Vector3& input)
+        ORX_FORCEINLINE static bool convert(btVector3* output, const orxonox::Vector3& input)
         {
             output->setX(input.x);
@@ -56,5 +56,5 @@
     struct ConverterExplicit<btVector3, orxonox::Vector3>
     {
-        FORCEINLINE static bool convert(orxonox::Vector3* output, const btVector3& input)
+        ORX_FORCEINLINE static bool convert(orxonox::Vector3* output, const btVector3& input)
         {
             output->x = input.x();
@@ -69,5 +69,5 @@
     struct ConverterExplicit<orxonox::Quaternion, btQuaternion>
     {
-        FORCEINLINE static bool convert(btQuaternion* output, const orxonox::Quaternion& input)
+        ORX_FORCEINLINE static bool convert(btQuaternion* output, const orxonox::Quaternion& input)
         {
             output->setW(input.w);
@@ -83,5 +83,5 @@
     struct ConverterExplicit<btQuaternion, orxonox::Quaternion>
     {
-        FORCEINLINE static bool convert(orxonox::Quaternion* output, const btQuaternion& input)
+        ORX_FORCEINLINE static bool convert(orxonox::Quaternion* output, const btQuaternion& input)
         {
             output->w = input.w();
Index: /code/branches/kicklib2/src/libraries/tools/ResourceCollection.cc
===================================================================
--- /code/branches/kicklib2/src/libraries/tools/ResourceCollection.cc	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/tools/ResourceCollection.cc	(revision 8284)
@@ -45,5 +45,5 @@
 
         // Default group is "General"
-        this->setResourceGroup(Resource::DEFAULT_GROUP);
+        this->setResourceGroup(Resource::getDefaultResourceGroup());
     }
 
Index: /code/branches/kicklib2/src/libraries/tools/ToolsPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/libraries/tools/ToolsPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/tools/ToolsPrereqs.h	(revision 8284)
@@ -52,8 +52,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _ToolsPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _ToolsExport  __attribute__ ((visibility("default")))
+#  define _ToolsPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _ToolsExport
+#  define _ToolsPrivate
 #endif
 
Index: /code/branches/kicklib2/src/libraries/util/Convert.h
===================================================================
--- /code/branches/kicklib2/src/libraries/util/Convert.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/util/Convert.h	(revision 8284)
@@ -143,5 +143,5 @@
     struct ConverterFallback
     {
-        FORCEINLINE static bool convert(ToType* output, const FromType& input)
+        ORX_FORCEINLINE static bool convert(ToType* output, const FromType& input)
         {
             COUT(2) << "Could not convert value of type " << typeid(FromType).name()
@@ -155,5 +155,5 @@
     struct ConverterFallback<FromType*, ToType*>
     {
-        FORCEINLINE static bool convert(ToType** output, FromType* const input)
+        ORX_FORCEINLINE static bool convert(ToType** output, FromType* const input)
         {
             ToType* temp = dynamic_cast<ToType*>(input);
@@ -182,5 +182,5 @@
 struct ConverterStringStream
 {
-    FORCEINLINE static bool convert(ToType* output, const FromType& input)
+    ORX_FORCEINLINE static bool convert(ToType* output, const FromType& input)
     {
         return orxonox::ConverterFallback<FromType, ToType>::convert(output, input);
@@ -198,5 +198,5 @@
     /// Fallback operator <<() (delegates to orxonox::ConverterFallback)
     template <class FromType>
-    FORCEINLINE bool operator <<(std::ostream& outstream,  const FromType& input)
+    ORX_FORCEINLINE bool operator <<(std::ostream& outstream,  const FromType& input)
     {
         std::string temp;
@@ -215,5 +215,5 @@
 struct ConverterStringStream<FromType, std::string>
 {
-    FORCEINLINE static bool convert(std::string* output, const FromType& input)
+    ORX_FORCEINLINE static bool convert(std::string* output, const FromType& input)
     {
         using namespace fallbackTemplates;
@@ -241,5 +241,5 @@
     /// Fallback operator >>() (delegates to orxonox::ConverterFallback)
     template <class ToType>
-    FORCEINLINE bool operator >>(std::istream& instream, ToType& output)
+    ORX_FORCEINLINE bool operator >>(std::istream& instream, ToType& output)
     {
         std::string input(static_cast<std::istringstream&>(instream).str());
@@ -252,5 +252,5 @@
 struct ConverterStringStream<std::string, ToType>
 {
-    FORCEINLINE static bool convert(ToType* output, const std::string& input)
+    ORX_FORCEINLINE static bool convert(ToType* output, const std::string& input)
     {
         using namespace fallbackTemplates;
@@ -276,5 +276,5 @@
     /// %Template delegates to ::ConverterStringStream
     template <class FromType, class ToType>
-    FORCEINLINE bool convertImplicitely(ToType* output, const FromType& input, Loki::Int2Type<false>)
+    ORX_FORCEINLINE bool convertImplicitely(ToType* output, const FromType& input, Loki::Int2Type<false>)
     {
         return ConverterStringStream<FromType, ToType>::convert(output, input);
@@ -283,5 +283,5 @@
     /// Makes an implicit cast from \a FromType to \a ToType
     template <class FromType, class ToType>
-    FORCEINLINE bool convertImplicitely(ToType* output, const FromType& input, Loki::Int2Type<true>)
+    ORX_FORCEINLINE bool convertImplicitely(ToType* output, const FromType& input, Loki::Int2Type<true>)
     {
         (*output) = static_cast<ToType>(input);
@@ -303,5 +303,5 @@
     {
         enum { probe = ImplicitConversion<FromType, ToType>::exists };
-        FORCEINLINE static bool convert(ToType* output, const FromType& input)
+        ORX_FORCEINLINE static bool convert(ToType* output, const FromType& input)
         {
             // Use the probe's value to delegate to the right function
@@ -327,5 +327,5 @@
     */
     template <class FromType, class ToType>
-    FORCEINLINE bool convertValue(ToType* output, const FromType& input)
+    ORX_FORCEINLINE bool convertValue(ToType* output, const FromType& input)
     {
         return ConverterExplicit<FromType, ToType>::convert(output, input);
@@ -348,5 +348,5 @@
     */
     template<class FromType, class ToType>
-    FORCEINLINE bool convertValue(ToType* output, const FromType& input, const ToType& fallback)
+    ORX_FORCEINLINE bool convertValue(ToType* output, const FromType& input, const ToType& fallback)
     {
         if (convertValue(output, input))
@@ -361,5 +361,5 @@
     /// Directly returns the converted value, but uses the fallback on failure. @see convertValue
     template<class FromType, class ToType>
-    FORCEINLINE ToType getConvertedValue(const FromType& input, const ToType& fallback)
+    ORX_FORCEINLINE ToType getConvertedValue(const FromType& input, const ToType& fallback)
     {
         ToType output;
@@ -380,5 +380,5 @@
     */
     template<class ToType, class FromType>
-    FORCEINLINE ToType multi_cast(const FromType& input)
+    ORX_FORCEINLINE ToType multi_cast(const FromType& input)
     {
         ToType output;
@@ -395,5 +395,5 @@
     struct ConverterExplicit<const char*, ToType>
     {
-        FORCEINLINE static bool convert(ToType* output, const char* input)
+        ORX_FORCEINLINE static bool convert(ToType* output, const char* input)
         {
             return convertValue<std::string, ToType>(output, input);
@@ -405,5 +405,5 @@
     struct ConverterExplicit<char, std::string>
     {
-        FORCEINLINE static bool convert(std::string* output, const char input)
+        ORX_FORCEINLINE static bool convert(std::string* output, const char input)
         {
             *output = input;
@@ -415,5 +415,5 @@
     struct ConverterExplicit<unsigned char, std::string>
     {
-        FORCEINLINE static bool convert(std::string* output, const unsigned char input)
+        ORX_FORCEINLINE static bool convert(std::string* output, const unsigned char input)
         {
             *output = input;
@@ -425,5 +425,5 @@
     struct ConverterExplicit<std::string, char>
     {
-        FORCEINLINE static bool convert(char* output, const std::string& input)
+        ORX_FORCEINLINE static bool convert(char* output, const std::string& input)
         {
             if (!input.empty())
@@ -438,5 +438,5 @@
     struct ConverterExplicit<std::string, unsigned char>
     {
-        FORCEINLINE static bool convert(unsigned char* output, const std::string& input)
+        ORX_FORCEINLINE static bool convert(unsigned char* output, const std::string& input)
         {
             if (!input.empty())
@@ -453,5 +453,5 @@
     struct ConverterExplicit<bool, std::string>
     {
-        FORCEINLINE static bool convert(std::string* output, const bool& input)
+        ORX_FORCEINLINE static bool convert(std::string* output, const bool& input)
         {
             if (input)
Index: /code/branches/kicklib2/src/libraries/util/MathConvert.h
===================================================================
--- /code/branches/kicklib2/src/libraries/util/MathConvert.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/util/MathConvert.h	(revision 8284)
@@ -51,5 +51,5 @@
     struct ConverterExplicit<orxonox::Vector2, std::string>
     {
-        FORCEINLINE static bool convert(std::string* output, const orxonox::Vector2& input)
+        ORX_FORCEINLINE static bool convert(std::string* output, const orxonox::Vector2& input)
         {
             std::ostringstream ostream;
@@ -67,5 +67,5 @@
     struct ConverterExplicit<orxonox::Vector3, std::string>
     {
-        FORCEINLINE static bool convert(std::string* output, const orxonox::Vector3& input)
+        ORX_FORCEINLINE static bool convert(std::string* output, const orxonox::Vector3& input)
         {
             std::ostringstream ostream;
@@ -83,5 +83,5 @@
     struct ConverterExplicit<orxonox::Vector4, std::string>
     {
-        FORCEINLINE static bool convert(std::string* output, const orxonox::Vector4& input)
+        ORX_FORCEINLINE static bool convert(std::string* output, const orxonox::Vector4& input)
         {
             std::ostringstream ostream;
@@ -99,5 +99,5 @@
     struct ConverterExplicit<orxonox::Quaternion, std::string>
     {
-        FORCEINLINE static bool convert(std::string* output, const orxonox::Quaternion& input)
+        ORX_FORCEINLINE static bool convert(std::string* output, const orxonox::Quaternion& input)
         {
             std::ostringstream ostream;
@@ -115,5 +115,5 @@
     struct ConverterExplicit<orxonox::ColourValue, std::string>
     {
-        FORCEINLINE static bool convert(std::string* output, const orxonox::ColourValue& input)
+        ORX_FORCEINLINE static bool convert(std::string* output, const orxonox::ColourValue& input)
         {
             std::ostringstream ostream;
@@ -157,5 +157,5 @@
     struct ConverterFallback<orxonox::Radian, ToType>
     {
-        FORCEINLINE static bool convert(ToType* output, const orxonox::Radian& input)
+        ORX_FORCEINLINE static bool convert(ToType* output, const orxonox::Radian& input)
         {
             return convertValue<Ogre::Real, ToType>(output, input.valueRadians());
@@ -167,5 +167,5 @@
     struct ConverterFallback<orxonox::Degree, ToType>
     {
-        FORCEINLINE static bool convert(ToType* output, const orxonox::Degree& input)
+        ORX_FORCEINLINE static bool convert(ToType* output, const orxonox::Degree& input)
         {
             return convertValue<Ogre::Real, ToType>(output, input.valueDegrees());
@@ -177,5 +177,5 @@
     struct ConverterFallback<FromType, orxonox::Radian>
     {
-        FORCEINLINE static bool convert(orxonox::Radian* output, const FromType& input)
+        ORX_FORCEINLINE static bool convert(orxonox::Radian* output, const FromType& input)
         {
             float temp;
@@ -194,5 +194,5 @@
     struct ConverterFallback<FromType, orxonox::Degree>
     {
-        FORCEINLINE static bool convert(orxonox::Degree* output, const FromType& input)
+        ORX_FORCEINLINE static bool convert(orxonox::Degree* output, const FromType& input)
         {
             float temp;
Index: /code/branches/kicklib2/src/libraries/util/SharedPtr.h
===================================================================
--- /code/branches/kicklib2/src/libraries/util/SharedPtr.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/util/SharedPtr.h	(revision 8284)
@@ -163,4 +163,5 @@
             public:
                 SharedCounter() : count_(1) {}
+                virtual ~SharedCounter() {}
                 virtual void destroy() = 0;
 
@@ -186,5 +187,5 @@
         _UtilExport SmallObjectAllocator& createSharedCounterPool();
 
-        FORCEINLINE SmallObjectAllocator& getSharedCounterPool()
+        ORX_FORCEINLINE SmallObjectAllocator& getSharedCounterPool()
         {
             static SmallObjectAllocator& instance = createSharedCounterPool();
Index: /code/branches/kicklib2/src/libraries/util/SignalHandler.h
===================================================================
--- /code/branches/kicklib2/src/libraries/util/SignalHandler.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/util/SignalHandler.h	(revision 8284)
@@ -70,5 +70,5 @@
 
     /// The SignalHandler is used to catch signals like SIGSEGV and write a backtrace to the logfile.
-    class SignalHandler : public Singleton<SignalHandler>
+    class _UtilExport SignalHandler : public Singleton<SignalHandler>
     {
         friend class Singleton<SignalHandler>;
Index: /code/branches/kicklib2/src/libraries/util/UtilPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/libraries/util/UtilPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/libraries/util/UtilPrereqs.h	(revision 8284)
@@ -52,8 +52,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _UtilPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _UtilExport  __attribute__ ((visibility("default")))
+#  define _UtilPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _UtilExport
+#  define _UtilPrivate
 #endif
 
Index: /code/branches/kicklib2/src/modules/designtools/DesignToolsPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/modules/designtools/DesignToolsPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/modules/designtools/DesignToolsPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _DesignToolsPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _DesignToolsExport  __attribute__ ((visibility("default")))
+#  define _DesignToolsPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _DesignToolsExport
+#  define _DesignToolsPrivate
 #endif
 
Index: /code/branches/kicklib2/src/modules/designtools/ScreenshotManager.cc
===================================================================
--- /code/branches/kicklib2/src/modules/designtools/ScreenshotManager.cc	(revision 8283)
+++ /code/branches/kicklib2/src/modules/designtools/ScreenshotManager.cc	(revision 8284)
@@ -46,4 +46,5 @@
 #include "core/GraphicsManager.h"
 #include "core/PathConfig.h"
+#include "core/Resource.h"
 #include "core/command/ConsoleCommand.h"
 #include "util/ScopedSingletonManager.h"
Index: /code/branches/kicklib2/src/modules/notifications/NotificationsPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/modules/notifications/NotificationsPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/modules/notifications/NotificationsPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _NotificationsPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _NotificationsExport  __attribute__ ((visibility("default")))
+#  define _NotificationsPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _NotificationsExport
+#  define _NotificationsPrivate
 #endif
 
Index: /code/branches/kicklib2/src/modules/objects/ObjectsPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/modules/objects/ObjectsPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/modules/objects/ObjectsPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _ObjectsPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _ObjectsExport  __attribute__ ((visibility("default")))
+#  define _ObjectsPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _ObjectsExport
+#  define _ObjectsPrivate
 #endif
 
Index: /code/branches/kicklib2/src/modules/overlays/OverlaysPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/modules/overlays/OverlaysPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/modules/overlays/OverlaysPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _OverlaysPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _OverlaysExport  __attribute__ ((visibility("default")))
+#  define _OverlaysPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _OverlaysExport
+#  define _OverlaysPrivate
 #endif
 
Index: /code/branches/kicklib2/src/modules/pickup/PickupPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/modules/pickup/PickupPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/modules/pickup/PickupPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _PickupPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _PickupExport  __attribute__ ((visibility("default")))
+#  define _PickupPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _PickupExport
+#  define _PickupPrivate
 #endif
 
Index: /code/branches/kicklib2/src/modules/pong/PongPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/modules/pong/PongPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/modules/pong/PongPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _PongPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _PongExport  __attribute__ ((visibility("default")))
+#  define _PongPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _PongExport
+#  define _PongPrivate
 #endif
 
Index: /code/branches/kicklib2/src/modules/questsystem/QuestEffect.cc
===================================================================
--- /code/branches/kicklib2/src/modules/questsystem/QuestEffect.cc	(revision 8283)
+++ /code/branches/kicklib2/src/modules/questsystem/QuestEffect.cc	(revision 8284)
@@ -68,12 +68,12 @@
     /*static*/ bool QuestEffect::invokeEffects(PlayerInfo* player, std::list<QuestEffect*> & effects)
     {
-        bool check = true;
+        bool temp = true;
 
         COUT(4) << "Invoking QuestEffects on player: " << player << " ."  << std::endl;
 
         for (std::list<QuestEffect*>::iterator effect = effects.begin(); effect != effects.end(); effect++)
-            check = check && (*effect)->invoke(player);
+            temp = temp && (*effect)->invoke(player);
 
-        return check;
+        return temp;
     }
 
Index: /code/branches/kicklib2/src/modules/questsystem/QuestEffectBeacon.cc
===================================================================
--- /code/branches/kicklib2/src/modules/questsystem/QuestEffectBeacon.cc	(revision 8283)
+++ /code/branches/kicklib2/src/modules/questsystem/QuestEffectBeacon.cc	(revision 8284)
@@ -143,6 +143,6 @@
         COUT(4) << "QuestEffectBeacon executed on player: " << player << " ." << std::endl;
 
-        bool check = QuestEffect::invokeEffects(player, this->effects_); // Invoke the QuestEffects on the PlayerInfo.
-        if(check)
+        bool temp = QuestEffect::invokeEffects(player, this->effects_); // Invoke the QuestEffects on the PlayerInfo.
+        if(temp)
         {
             this->decrementTimes(); // Decrement the number of times the beacon can be used.
Index: /code/branches/kicklib2/src/modules/questsystem/QuestsystemPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/modules/questsystem/QuestsystemPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/modules/questsystem/QuestsystemPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _QuestsystemPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _QuestsystemExport  __attribute__ ((visibility("default")))
+#  define _QuestsystemPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _QuestsystemExport
+#  define _QuestsystemPrivate
 #endif
 
Index: /code/branches/kicklib2/src/modules/questsystem/effects/AddReward.cc
===================================================================
--- /code/branches/kicklib2/src/modules/questsystem/effects/AddReward.cc	(revision 8283)
+++ /code/branches/kicklib2/src/modules/questsystem/effects/AddReward.cc	(revision 8284)
@@ -105,11 +105,11 @@
         COUT(5) << "AddReward on player: " << player << " ." << std::endl;
 
-        bool check = true;
+        bool temp = true;
         for ( std::list<Rewardable*>::iterator reward = this->rewards_.begin(); reward != this->rewards_.end(); ++reward )
-            check = check && (*reward)->reward(player);
+            temp = temp && (*reward)->reward(player);
 
         COUT(4) << "Rewardable successfully added to player." << player << " ." << std::endl;
 
-        return check;
+        return temp;
     }
 
Index: /code/branches/kicklib2/src/modules/weapons/WeaponsPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/modules/weapons/WeaponsPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/modules/weapons/WeaponsPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _WeaponsPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _WeaponsExport  __attribute__ ((visibility("default")))
+#  define _WeaponsPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _WeaponsExport
+#  define _WeaponsPrivate
 #endif
 
Index: /code/branches/kicklib2/src/orxonox-main.vcxproj.user.in
===================================================================
--- /code/branches/kicklib2/src/orxonox-main.vcxproj.user.in	(revision 8284)
+++ /code/branches/kicklib2/src/orxonox-main.vcxproj.user.in	(revision 8284)
@@ -0,0 +1,23 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|${MSVC_PLATFORM}'">
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerEnvironment>PATH=${RUNTIME_LIBRARY_DIRECTORY};%PATH%</LocalDebuggerEnvironment>
+    <LocalDebuggerWorkingDirectory>$(Outdir)</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|${MSVC_PLATFORM}'">
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerEnvironment>PATH=${RUNTIME_LIBRARY_DIRECTORY};%PATH%</LocalDebuggerEnvironment>
+    <LocalDebuggerWorkingDirectory>$(Outdir)</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|${MSVC_PLATFORM}'">
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerEnvironment>PATH=${RUNTIME_LIBRARY_DIRECTORY};%PATH%</LocalDebuggerEnvironment>
+    <LocalDebuggerWorkingDirectory>$(Outdir)</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|${MSVC_PLATFORM}'">
+    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+    <LocalDebuggerEnvironment>PATH=${RUNTIME_LIBRARY_DIRECTORY};%PATH%</LocalDebuggerEnvironment>
+    <LocalDebuggerWorkingDirectory>$(Outdir)</LocalDebuggerWorkingDirectory>
+  </PropertyGroup>
+</Project>
Index: /code/branches/kicklib2/src/orxonox/MoodManager.cc
===================================================================
--- /code/branches/kicklib2/src/orxonox/MoodManager.cc	(revision 8283)
+++ /code/branches/kicklib2/src/orxonox/MoodManager.cc	(revision 8284)
@@ -56,4 +56,7 @@
             COUT(2) << "Mood Warning: Folder for default mood (" << MoodManager::defaultMood_ << ") does not exist!" << std::endl;
         }
+        
+        // @TODO
+        // Creating a vector of the available moods to enable easy mood selection by Lua/CEGUI        
     }
 
Index: /code/branches/kicklib2/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- /code/branches/kicklib2/src/orxonox/OrxonoxPrereqs.h	(revision 8283)
+++ /code/branches/kicklib2/src/orxonox/OrxonoxPrereqs.h	(revision 8284)
@@ -53,8 +53,11 @@
 #    endif
 #  endif
-#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _OrxonoxPrivate
+#elif defined (ORXONOX_GCC_VISIBILITY)
 #  define _OrxonoxExport  __attribute__ ((visibility("default")))
+#  define _OrxonoxPrivate __attribute__ ((visibility("hidden")))
 #else
 #  define _OrxonoxExport
+#  define _OrxonoxPrivate
 #endif
 
Index: /code/branches/kicklib2/src/orxonox/sound/AmbientSound.cc
===================================================================
--- /code/branches/kicklib2/src/orxonox/sound/AmbientSound.cc	(revision 8283)
+++ /code/branches/kicklib2/src/orxonox/sound/AmbientSound.cc	(revision 8284)
@@ -42,5 +42,5 @@
 
         // Ambient sounds always fade in
-        this->setVolume(0);
+        this->setVolume(0.0f);
     }
 
Index: /code/branches/kicklib2/src/orxonox/sound/SoundBuffer.cc
===================================================================
--- /code/branches/kicklib2/src/orxonox/sound/SoundBuffer.cc	(revision 8283)
+++ /code/branches/kicklib2/src/orxonox/sound/SoundBuffer.cc	(revision 8284)
@@ -30,5 +30,5 @@
 #include "SoundBuffer.h"
 
-#include <AL/alut.h>
+#include <alut.h>
 #include <vorbis/vorbisfile.h>
 
Index: /code/branches/kicklib2/src/orxonox/sound/SoundManager.cc
===================================================================
--- /code/branches/kicklib2/src/orxonox/sound/SoundManager.cc	(revision 8283)
+++ /code/branches/kicklib2/src/orxonox/sound/SoundManager.cc	(revision 8284)
@@ -31,6 +31,6 @@
 #include "SoundManager.h"
 
-#include <AL/alut.h>
 #include <utility>
+#include <alut.h>
 #include <loki/ScopeGuard.h>
 
@@ -73,4 +73,8 @@
         this->bDestructorCalled_ = false;
 
+        // Clear error messages (might be problematic on some systems)
+        alGetError();
+        alutGetError();
+
         // See whether we even want to load
         bool bDisableSound_ = false;
@@ -78,5 +82,4 @@
         if (bDisableSound_)
             ThrowException(InitialisationAborted, "Sound: Not loading at all");
-
         if (!alutInitWithoutContext(NULL, NULL))
             ThrowException(InitialisationFailed, "Sound Error: ALUT initialisation failed: " << alutGetErrorString(alutGetError()));
Index: /code/branches/kicklib2/src/orxonox/sound/WorldSound.cc
===================================================================
--- /code/branches/kicklib2/src/orxonox/sound/WorldSound.cc	(revision 8283)
+++ /code/branches/kicklib2/src/orxonox/sound/WorldSound.cc	(revision 8284)
@@ -30,5 +30,6 @@
 #include "WorldSound.h"
 
-#include <AL/alut.h>
+#include <alut.h>
+
 #include "util/Math.h"
 #include "core/CoreIncludes.h"
